commit cc4849186baafe348098a897bc3724acbaabcbe4 Author: stoess@i30s3.ibds.uka.de Date: Mon May 18 09:21:37 2009 +0200 Initial revision diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..0620779 --- /dev/null +++ b/.cvsignore @@ -0,0 +1 @@ +.dump diff --git a/README b/README new file mode 100644 index 0000000..931feac --- /dev/null +++ b/README @@ -0,0 +1,37 @@ +L4/KA README +Uwe Dannowski +June 7 2000 + + +1. Getting Started + + After obtaining the source tree (from CVS or as a tarball), go to the kernel +directory and type make: + + src/l4-ka > cd kernel + src/l4-ka/kernel > make + + This should automatically invoke the XConfig tool to configure the kernel. +The settings default to build an x86-X0-debug kernel. After finishing the +configuration, click "Save and Exit" in XConfig. Then the kernel is built. + As a result of the build process, there should be a kernel image file +x86-kernel (or whatever architecture you chose). That's all - copy the kernel +image to your boot medium. + +The build process for the applications is quite similar - go to the apps + directory and type make there: + + src/l4-ka > cd apps + src/l4-ka/apps > make + + The XConfig tool for the applications is invoked. Make your selections with +respect to the kernel settings (kernel version) and select the applications +you want to build. When you're done with the configuration, click "Save and +Exit" and the build process starts. + For now, the resulting binaries will reside in the respective subdirectories. +Copy them to your boot medium and have fun. + + + +Please, direct comments, contributions, etc. to this README to: + Uwe.Dannowski@ira.uka.de diff --git a/apps/.cvsignore b/apps/.cvsignore new file mode 100644 index 0000000..70127f4 --- /dev/null +++ b/apps/.cvsignore @@ -0,0 +1 @@ +Makeconf.local diff --git a/apps/Makeconf b/apps/Makeconf new file mode 100644 index 0000000..b1d6df9 --- /dev/null +++ b/apps/Makeconf @@ -0,0 +1,200 @@ +# -*- mode: Makefile; -*- +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: Makeconf +## Description: Application directory make configuration +## +## @LICENSE@ +## +## $Id: Makeconf,v 1.22 2002/01/24 07:16:26 uhlig Exp $ +## +###################################################################### + +###################################################################### +# the root directory +# this rule assumes the topdir to be /l4-ka/ +# with apps as one of its subdirectories + +TOPDIR = $(dir $(word 1,$(wildcard Makeconf $(addsuffix /Makeconf, .. ../.. ../../..))))/.. +LIB= + +# this checks for the Makeconf.local +# we need it, so if it's not there, just rebuild it +ifneq ($(wildcard $(TOPDIR)/apps/Makeconf.local), ) + +###################################################################### +# this should be the very first rule + +_default: all + + +###################################################################### +# local Makeconf file + +-include $(TOPDIR)/apps/Makeconf.local + + +###################################################################### +# Platform specific parts + +ifeq ($(PLATFORM), dnard) +CPPFLAGS += -mcpu=strongarm110 +ARCH = arm +else + +ifeq ($(PLATFORM), ep7211) +CPPFLAGS += +DEFINES += EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), brutus) +CPPFLAGS += -mcpu=strongarm1100 +DEFINES += EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), pleb) +CPPFLAGS += -mcpu=strongarm1100 +DEFINES += EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), ipaq) +CPPFLAGS += -mcpu=strongarm1100 +DEFINES += EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), i586) +ARCH = x86 +CPPFLAGS = -D__L4_VERSION_X__ +CFLAGS += -Wall -Wno-format -O9 -fomit-frame-pointer -freg-struct-return +else + +ifeq ($(PLATFORM), r4000) +ARCH = mips +CFLAGS += -Wall -Wno-format -O9 -fomit-frame-pointer -mcpu=r4000 -G 0 -mno-abicalls -fno-pic -mips3 -mgp32 +#CFLAGS += -Wall -Wno-format -O9 -mcpu=r4000 -G 0 -mno-abicalls -fno-pic -mips3 -mgp32 +SFLAGS += -mips3 + +else +$(error fatal error: unknown platform "$(PLATFORM)". Change Makeconf.local) +endif +endif +endif +endif +endif +endif +endif + +else +PLATFORM=i586 # make make happy +_default: + @$(MAKE) xconfig + @$(MAKE) + @exit 0 +endif + +###################################################################### +# Architecture specific parts + +SHELL = bash +ifeq ($(ARCH), arm) + ifneq ($(shell type -p arm-unknown-linux-gcc),) +PREFIX = arm-unknown-linux-gnu- + else + ifneq ($(shell type -p arm-elf-gcc),) +PREFIX = arm-elf- + else +PREFIX = arm-linux- + endif + endif +CFLAGS += -Wall -O2 -fomit-frame-pointer +endif + +ifeq ($(ARCH), mips) +PREFIX = mips- +endif + +ifeq ($(ARCH), x86) + ifeq ($(MACHTYPE),i686-pc-cygwin) +PREFIX=i686-linux- + endif +endif + +###################################################################### +# tools + +RM = rm +LN_S = ln -s +CC = $(PREFIX)gcc +LD = $(PREFIX)ld +OBJCOPY = $(PREFIX)objcopy +STRIP = $(PREFIX)strip +AR = $(PREFIX)ar + +INCLUDES += $(TOPDIR)/apps/include + +LIBGCC = $(dir $(shell $(CC) --print-lib)) + +SFLAGS += -DASSEMBLY +LDFLAGS += -L$(LIBGCC) + +DEFINES += __ARCH__=$(ARCH)\ + __PLATFORM__=$(PLATFORM) + +CPPFLAGS += -nostdinc $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) + +CFLAGS += -funsigned-char -funsigned-bitfields + +###################################################################### +# some evil magic + +ifeq ($(findstring -fomit-frame-pointer, $(CFLAGS)), -fomit-frame-pointer) +DEFINES += NO_FRAME_POINTER +endif + + + +###################################################################### +# compile rules + +%.o: %.S + $(CC) $(CPPFLAGS) $(SFLAGS) -o $@ -c $< + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< + + +###################################################################### +# library rules +LIB_OBJ = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIB_SRC))) + +$(LIB): $(LIB_OBJ) + $(AR) -rcs $(LIB) $(LIB_OBJ) + + +###################################################################### +# striptease + +%.stripped: % + cp $^ $@ + $(STRIP) $@ + @chmod a+r-x $^ $@ + +###################################################################### +# dependencies + +.depend: $(SRCS) + @echo Building dependencies in `pwd` + @$(CC) $(CPPFLAGS) -o - -M $(SRCS) > $@ + + +###################################################################### +# cleanup + +celan clean:: + $(RM) -f *~ *.s *.o *.i *.ii *.s $(LIB) diff --git a/apps/Makeconf.local b/apps/Makeconf.local new file mode 100644 index 0000000..78b529e --- /dev/null +++ b/apps/Makeconf.local @@ -0,0 +1,3 @@ +PLATFORM=i586 +SIGMA0_LINKBASE=00020000 +ROOTTASK_LINKBASE= diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 0000000..708b949 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,63 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: Makefile +## Description: Application directory Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.7 2001/12/09 03:25:12 ud3 Exp $ +## +###################################################################### +# main rule +include Makeconf $(wildcard xconfig/.config) + +SYMLINKS_ARCH = include/l4 +SYMLINKS_PLATFORM = # include/arch + +SUBDIRS += lib/io + +ifeq ($(CONFIG_BUILD_SIGMA0),y) + SUBDIRS += sigma0 +endif +ifeq ($(CONFIG_BUILD_ROOTTASK),y) + SUBDIRS += root_task +endif +ifeq ($(CONFIG_BUILD_RMGR),y) + SUBDIRS += rmgr/src +endif + +all: symlinks subdirs + +subdirs: + @for d in $(SUBDIRS); do \ + $(MAKE) -C $${d} || exit 1; \ + done + +symlinks:: + @for f in $(SYMLINKS_ARCH); do \ + if test ! -e $${f}/arch -o -L $${f}/arch; then \ + $(RM) -f $${f}/arch; \ + $(LN_S) $(ARCH) $${f}/arch; \ + else \ + echo $${f}/arch is not a symbolic link!; \ + exit 1; \ + fi; \ + done + rm -f include/l4/sys + ln -sf arch/sys include/l4/sys + ln -sf x86-x0-32 rmgr/include/l4/sys + +.PHONY: xconfig xconfig/ +xconfig xconfig/: + $(MAKE) -C xconfig + +celan clean:: + @for d in $(SUBDIRS); do \ + $(MAKE) -C $${d} clean; \ + done + @rm -fv *-kernel{,.stripped} + @echo purging symlinks + @$(RM) -fv `find . -type l` + diff --git a/apps/arm-booter/.cvsignore b/apps/arm-booter/.cvsignore new file mode 100644 index 0000000..5e6c554 --- /dev/null +++ b/apps/arm-booter/.cvsignore @@ -0,0 +1,4 @@ +*.ii *.s +*.bin *.stripped +modules.* +arm-booter diff --git a/apps/arm-booter/Makefile b/apps/arm-booter/Makefile new file mode 100644 index 0000000..c75a411 --- /dev/null +++ b/apps/arm-booter/Makefile @@ -0,0 +1,121 @@ +###################################################################### +## +## Copyright (C) 2001-2002, Karlsruhe University +## +## File path: arm-booter/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.15 2002/12/12 08:19:26 ud3 Exp $ +## +###################################################################### +include ../Makeconf + +KERNEL= ../../kernel/arm-kernel.stripped +MODULES= ../sigma0/sigma0.stripped \ + ../root_task/root_task.stripped + +BP_MOD_PARTS=$(patsubst %.stripped, %, $(notdir $(MODULES))) +BP_MOD_FILES=$(addprefix tmp/, $(BP_MOD_PARTS)) +BP_KNL_PARTS=$(patsubst %.stripped, %, $(notdir $(KERNEL))) +BP_KNL_FILES=$(addprefix tmp/, $(BP_KNL_PARTS)) +BP_OBJS=$(addsuffix .o, $(BP_MOD_FILES) $(BP_KNL_FILES)) + +ifeq ($(PLATFORM), dnard) + LINKBASE=0x0e500000 +endif + +ifeq ($(PLATFORM), brutus) + LINKBASE=0xd8000000 +endif + +ifeq ($(PLATFORM), pleb) + LINKBASE=0xc0008000 +endif + +ifeq ($(PLATFORM), ep7211) + LINKBASE=0xc0700000 +endif + +ifeq ($(PLATFORM), ipaq) + LINKBASE=0xc1000000 +endif + +# crt0-$(ARCH).S or crt0-$(ARCH)-$(PLATFORM).S must come first +SRCS = $(wildcard crt0-$(ARCH).S crt0-$(ARCH)-$(PLATFORM).S) main.c elf.c modules.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../include +LDFLAGS += -N -L../lib -static -Ttext=$(LINKBASE) +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ -fno-builtin + + +TARGET = arm-booter + +all: $(TARGET).bin + +$(TARGET).bin: $(TARGET).stripped + $(OBJCOPY) -Obinary -S $< $@ + @chmod a+r $@ + @chmod a-x $@ + @echo ""; echo "Done with $@"; echo "" + +$(TARGET): $(OBJS) Makefile linker.lds ../lib/libionative.a $(BP_OBJS) + @echo ""; echo "Linking $@" + $(LD) -Tlinker.lds $(LDFLAGS) -o $@ $(OBJS) $(BP_OBJS) -lionative -lgcc + +main.o: modules.h + +$(BP_MOD_FILES) $(BP_KNL_FILES): $(MODULES) $(KERNEL) + @for i in $(MODULES) $(KERNEL); do \ + cp $$i tmp/`basename $$i|sed -e 's/\.stripped//'`; \ + done + +modules.h: $(MODULES) Makefile + @echo "Building $@" + @for i in `echo $(BP_MOD_PARTS) $(BP_KNL_PARTS) | tr '-' '_'`; do \ + echo "extern byte_t _binary_$${i}_start[];" ; \ + echo "extern byte_t _binary_$${i}_end[];" ; \ + echo "extern byte_t _binary_$${i}_size[];" ; \ + echo "extern dword_t $${i}_vaddr;" ; \ + echo "extern dword_t $${i}_entry;" ; \ + echo ""; \ + done > modules.h + @echo "" >> modules.h + @echo "void loadmodules();" >> modules.h + @echo "void loadelf(void* image, unsigned* entry, unsigned *paddr);" \ + >> modules.h + + +modules.c: modules.h $(MODULES) Makefile + @echo "Building $@" + @echo "/* automatically generated file - do not edit */"> modules.c + @echo >> modules.c + @echo "#include " >> modules.c + @echo '#include "modules.h"' >> modules.c + @echo >> modules.c + @for i in `echo $(BP_MOD_PARTS) $(BP_KNL_PARTS) | tr '-' '_'`; do \ + echo "unsigned $${i}_vaddr;" ; \ + echo "unsigned $${i}_entry;" ; \ + done >> modules.c + @echo >> modules.c + @echo "#include " >> modules.c + @echo >> modules.c + @echo 'void loadmodules()' >> modules.c + @echo { >> modules.c + @for i in `echo $(BP_MOD_PARTS) | tr '-' '_'`; do \ + echo -n " printf(\" Loading $${i}\n\");" ; \ + echo " loadelf(_binary_$${i}_start, &$${i}_entry, &$${i}_vaddr);"; \ + done >> modules.c + @echo } >> modules.c + +tmp/%.o: tmp/% Makefile + @echo "Preparing $<" + @echo "SECTIONS { .$( $<.lnk + @(cd tmp;$(LD) -T $( + +#define BOOTABLE_ARM_ELF(h) \ + ((h.e_ident[EI_MAG0] == ELFMAG0) & (h.e_ident[EI_MAG1] == ELFMAG1) \ + & (h.e_ident[EI_MAG2] == ELFMAG2) & (h.e_ident[EI_MAG3] == ELFMAG3) \ + & (h.e_ident[EI_CLASS] == ELFCLASS32) & (h.e_ident[EI_DATA] == ELFDATA2LSB) \ + & (h.e_ident[EI_VERSION] == 1/*EV_CURRENT*/) & (h.e_type == ET_EXEC) \ + & (h.e_machine == EM_ARM) & (h.e_version == EV_CURRENT)) + +void loadelf(void* image, unsigned* entry, unsigned* paddr) +{ + Elf32_Ehdr* eh; + dword_t filepos; + + eh = (Elf32_Ehdr*) image; + + if (BOOTABLE_ARM_ELF((*eh))) + { + dword_t i; + dword_t memaddr, memsiz, filesiz; + Elf32_Phdr *phdr; + + *entry = eh->e_entry; + for (i = 0; i < eh->e_phnum; i++) + { + dword_t j; + phdr = (Elf32_Phdr *) (eh->e_phoff + (int) eh + + eh->e_phentsize * i); + if (phdr->p_type == PT_LOAD) + { + /* offset into file */ + filepos = phdr->p_offset; + filesiz = phdr->p_filesz; + memaddr = phdr->p_paddr; + memsiz = phdr->p_memsz; + *paddr = memaddr; + + if (!filepos) + { + filepos = (sizeof(Elf32_Ehdr) + + sizeof(Elf32_Phdr) * eh->e_phnum); + filesiz -= filepos; + memaddr += filepos; + }; + printf(" 0x%x bytes at %x\n", + filesiz, memaddr); + for (j = 0; j < filesiz; j++) + { + *((byte_t*) (j+memaddr)) = ((byte_t*) eh)[filepos+j]; + }; + }; + } + } + else + printf(" is no valid ELF file\n"); +}; diff --git a/apps/arm-booter/elf.h b/apps/arm-booter/elf.h new file mode 100644 index 0000000..feac47b --- /dev/null +++ b/apps/arm-booter/elf.h @@ -0,0 +1,1586 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ian Lance Taylor . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _ELF_H +#define _ELF_H 1 + + +#include + + +typedef qword_t uint64_t; +typedef dword_t uint32_t; +typedef word_t uint16_t; +typedef sqword_t int64_t; +typedef sdword_t int32_t; +typedef sword_t int16_t; + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type of symbol indices. */ +typedef uint32_t Elf32_Symndx; +typedef uint64_t Elf64_Symndx; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOPROC 0xff00 /* Processor-specific */ +#define ET_HIPROC 0xffff /* Processor-specific */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_486 6 /* Intel 80486 */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* Amdahl */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ +#define EM_RS6000 11 /* RS6000 */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_nCUBE 16 /* nCUBE */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH32 */ +#define EM_MMA 39 /* Fujitsu MMA */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_NUM 54 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_NUM 12 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */ +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* No defined meaning, 0 */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* Special section index. */ + +#define SHN_UNDEF 0 /* No section, undefined symbol. */ + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_NUM 5 /* Number of defined types. */ +#define STT_LOOS 11 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) (((sym) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_NUM 7 /* Number of defined types. */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_NUM 29 /* Number used */ +#define DT_LOOS 0x60000000 /* Start of OS-specific */ +#define DT_HIOS 0x6fffffff /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_SYMINFO 0x6ffffeff /* syminfo table */ +#define DT_ADDRRNGHI 0x6ffffeff + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + long int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 17 /* Used FPU control word. */ + + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define ELF_NOTE_ABI 1 + +/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI + note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 + + +/* Motorola 68k specific definitions. */ + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_68K_NUM 23 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +/* Keep this the last entry. */ +#define R_386_NUM 11 + +/* SUN SPARC specific definitions. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_SUN_US1 0x000200 +#define EF_SPARC_HAL_R1 0x000400 + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* ?? */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +/* Keep this the last entry. */ +#define R_SPARC_NUM 56 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ + +/* The following are non-official names and should ot be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +/* Keep this the last entry. */ +#define R_MIPS_NUM 38 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +#define DT_MIPS_NUM 0x32 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNL 1 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 2 /* Program uses arch. extensions. */ +#define EF_PARISC_ARCH 0xffff0000 /* Architecture version. */ +/* Defined values are: + 0x020b PA-RISC 1.0 big-endian + 0x0210 PA-RISC 1.1 big-endian + 0x028b PA-RISC 1.0 little-endian + 0x0290 PA-RISC 1.1 little-endian +*/ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_GOT 0x70000000 /* GOT for external data. */ +#define SHT_PARISC_ARCH 0x70000001 /* Architecture extensions. */ +#define SHT_PARISC_GLOBAL 0x70000002 /* Definition of $global$. */ +#define SHT_PARISC_MILLI 0x70000003 /* Millicode routines. */ +#define SHT_PARISC_UNWIND 0x70000004 /* Unwind information. */ +#define SHT_PARISC_PLT 0x70000005 /* Procedure linkage table. */ +#define SHT_PARISC_SDATA 0x70000006 /* Short initialized data. */ +#define SHT_PARISC_SBSS 0x70000007 /* Short uninitialized data. */ +#define SHT_PARISC_SYMEXTN 0x70000008 /* Argument/relocation info. */ +#define SHT_PARISC_STUBS 0x70000009 /* Linker stubs. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_GLOBAL 0x10000000 /* Section defines dp. */ +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR14R 4 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL21L 5 /* PC-relative, left 21 bits. */ +#define R_PARISC_PCREL14R 6 /* PC-relative, right 14 bits. */ +#define R_PARISC_PCREL17C 7 /* Conditional PC-relative, ignore + if displacement > 17bits. */ +#define R_PARISC_PCREL17F 8 /* Conditional PC-relative, must + fit in 17bits. */ +#define R_PARISC_DPREL21L 9 /* DP-relative, left 21 bits. */ +#define R_PARISC_DPREL14R 10 /* DP-relative, right 14 bits. */ +#define R_PARISC_DPREL14F 11 /* DP-relative, must bit in 14 bits. */ +#define R_PARISC_DLTREL21L 12 /* DLT-relative, left 21 bits. */ +#define R_PARISC_DLTREL14R 13 /* DLT-relative, right 14 bits. */ +#define R_PARISC_DLTREL14F 14 /* DLT-relative, must fit in 14 bits.*/ +#define R_PARISC_DLTIND21L 15 /* DLT-relative indirect, left + 21 bits. */ +#define R_PARISC_DLTIND14R 16 /* DLT-relative indirect, right + 14 bits. */ +#define R_PARISC_DLTIND14F 17 /* DLT-relative indirect, must fit + int 14 bits. */ +#define R_PARISC_PLABEL32 18 /* Direct 32-bit reference to proc. */ + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_ALPHA_NUM 28 + + +/* PowerPC specific declarations */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry. */ +#define R_PPC_NUM 37 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_NEW_ABI 0x80 +#define EF_OLD_ABI 0x100 + +/* Additional symbol types for Thumb */ +#define STT_ARM_TFUNC 0xd + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +/* ARM relocs. */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +#endif /* elf.h */ diff --git a/apps/arm-booter/linker.lds b/apps/arm-booter/linker.lds new file mode 100644 index 0000000..2d60aaa --- /dev/null +++ b/apps/arm-booter/linker.lds @@ -0,0 +1,21 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm-booter/linker.lds + * Description: linker script + * + * @LICENSE@ + * + * $Id: linker.lds,v 1.5 2001/12/09 04:06:30 ud3 Exp $ + * + ********************************************************************/ + +SECTIONS +{ + /DISCARD/ : { *(.comment) *(.debug*) *(.glue*) } + .text : { *(.text) *(.data) *(.rodata) *(.bss) } + . = ALIGN(0x10); + .modules : { *(*) } + _end = .; +} diff --git a/apps/arm-booter/main.c b/apps/arm-booter/main.c new file mode 100644 index 0000000..1719a6e --- /dev/null +++ b/apps/arm-booter/main.c @@ -0,0 +1,123 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm-booter/main.c + * Description: System Image loader for Brutus and EP7211 boards + * + * @LICENSE@ + * + * $Id: main.c,v 1.11 2002/01/24 07:18:34 uhlig Exp $ + * + ********************************************************************/ +#include +#include +#include + +void loadELF(void *, unsigned*); +void bootELF(void *); + +#include "modules.h" + +int main(void) +{ + l4_kernel_info_t *kip = NULL; + extern dword_t _start[]; + extern dword_t _end[]; + printf("\n\n\n\n"); +// putc(12); /* clear screen */ + printf("Welcome to ARM-Booter version 0.1 - built on %s %s\n", + __DATE__, __TIME__); + printf("using %p-%p\n", _start, _end); + + loadmodules(); + + { + byte_t *p = (byte_t*) _binary_arm_kernel_start; + int i = (int) _binary_arm_kernel_size; + printf("looking for KIP: [%x:%x]\n", (unsigned) p, i); + for (;i--;p++) + if ((p[0] == 'L') && + (p[1] == '4') && + (p[2] == 0xe6) && + (p[3] == 'K')) + { + printf("Found KIP at %x\n", (unsigned) p); + printf("Sigma0 entry : %x\n", sigma0_entry); + printf("Root Task entry: %x\n", root_task_entry); + + kip = (l4_kernel_info_t *) p; + + kip->sigma0_eip = sigma0_entry; + kip->root_eip = root_task_entry; + +#if defined(CONFIG_ARCH_ARM_BRUTUS) + kip->main_memory.low = 0xC0000000; + kip->main_memory.high = 0xD8400000; + + /* Remove memory in between banks. */ + kip->dedicated[0].low = 0xC0400000; + kip->dedicated[0].high = 0xC8000000; + kip->dedicated[1].low = 0xC8400000; + kip->dedicated[1].high = 0xD0000000; + kip->dedicated[2].low = 0xD0400000; + kip->dedicated[2].high = 0xD8000000; +#elif defined(CONFIG_ARCH_ARM_IPAQ) + /* the IPaq uses just one bank. for more details see: + * http://handhelds.org/Compaq/iPAQH3600/iPAQ_H3600.html + */ + kip->main_memory.low = 0xC0000000; + kip->main_memory.high = 0xC2000000; + + /* exclude all others */ + kip->dedicated[0].high = 0; + kip->dedicated[1].high = 0; + kip->dedicated[2].high = 0; + kip->dedicated[3].high = 0; + +#elif defined(CONFIG_ARCH_ARM_PLEB) + kip->main_memory.low = 0xC0000000; + kip->main_memory.high = 0xC8800000; + + /* Remove memory in between banks. */ + kip->dedicated[0].low = 0xC0800000; + kip->dedicated[0].high = 0xC8000000; +#elif defined(CONFIG_ARCH_ARM_DNARD) + kip->main_memory.low = 0x08000000; + kip->main_memory.high = 0x0E800000; + + /* Remove memory in between banks. */ + kip->dedicated[0].low = 0x08800000; + kip->dedicated[0].high = 0x0A000000; + kip->dedicated[1].low = 0x0A800000; + kip->dedicated[1].high = 0x0C000000; + kip->dedicated[2].low = 0x0C800000; + kip->dedicated[2].high = 0x0E000000; +#elif defined(CONFIG_ARCH_ARM_EP7211) + /* EP7211 */ + ((unsigned*)p)[24] = 0xC0000000; + ((unsigned*)p)[25] = 0xC0800000; +#else +#error unknown ARM platform +#endif + break; + } + if (i == -1) + printf("KIP not found!\n"); + } + + kip->sigma0_memory.low = sigma0_vaddr; + kip->sigma0_memory.high = sigma0_vaddr + (dword_t) _binary_sigma0_size; + kip->root_memory.low = root_task_vaddr; + kip->root_memory.high = root_task_vaddr + + (dword_t) _binary_root_task_size; + + printf("Loading kernel\n"); + loadelf(_binary_arm_kernel_start, &arm_kernel_entry, &arm_kernel_vaddr); + + printf("kernel_entry: %x\n", arm_kernel_entry); + __asm__ __volatile__ ("mov pc,%0\n": :"r"(arm_kernel_entry)); + + while(1); + +} diff --git a/apps/arm-booter/tmp/.cvsignore b/apps/arm-booter/tmp/.cvsignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/apps/arm-booter/tmp/.cvsignore @@ -0,0 +1 @@ +* diff --git a/apps/bench/int-latency/Makefile b/apps/bench/int-latency/Makefile new file mode 100644 index 0000000..304d8b8 --- /dev/null +++ b/apps/bench/int-latency/Makefile @@ -0,0 +1,35 @@ +###################################################################### +## +## Copyright (C) 2002, Karlsruhe University +## +## File path: bench/int-latency/Makefile +## Description: Application for measuring interrupt latencies +## +## @LICENSE@ +## +## $Id: Makefile,v 1.1 2002/05/07 19:08:28 skoglund Exp $ +## +###################################################################### +include ../../Makeconf + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES+= ../../include +LDFLAGS+= -N -L../../lib +DEFINES+= USE_L4_TYPES +CFLAGS+= -x c++ --save-temps -ggdb +SFLAGS+= --save-temps + +TARGET= $(notdir $(shell "pwd")) + +LINKBASE= $(ROOTTASK_LINKBASE) + +all: $(TARGET).stripped + +$(TARGET): $(OBJS) Makefile ../../lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) -lio -lgcc + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/bench/int-latency/apic.c b/apps/bench/int-latency/apic.c new file mode 100644 index 0000000..48208c1 --- /dev/null +++ b/apps/bench/int-latency/apic.c @@ -0,0 +1,48 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: bench/int-latency/apic.c + * Description: Setup local APIC + * + * @LICENSE@ + * + * $Id: apic.c,v 1.1 2002/05/07 19:09:30 skoglund Exp $ + * + ********************************************************************/ +#include +#include "apic.h" + +dword_t local_apic; + +void setup_local_apic (dword_t apic_location) +{ + dword_t tmp; + extern dword_t int_num; + + local_apic = apic_location; + + /* Enable local apic. */ + tmp = get_local_apic (X86_APIC_SVR); + tmp |= 0x100; /* enable APIC */ + tmp &= ~(0x200); /* enable focus processor */ + set_local_apic (X86_APIC_SVR, tmp); + + /* Set prio to accept all. */ + tmp = get_local_apic (X86_APIC_TASK_PRIO); + tmp &= ~0xff; + set_local_apic (X86_APIC_TASK_PRIO, tmp); + + /* Flat mode. */ + tmp = get_local_apic (X86_APIC_DEST_FORMAT); + tmp |= 0xf0000000; + set_local_apic (X86_APIC_DEST_FORMAT, tmp); + + /* Divider = 1 */ + set_local_apic (X86_APIC_TIMER_DIVIDE, + (get_local_apic (X86_APIC_TIMER_DIVIDE) & ~0xf) | 0xb); + + /* Periodic timer, masked */ + set_local_apic (X86_APIC_LVT_TIMER, APIC_IRQ_MASK | + APIC_TRIGGER_PERIODIC | ((int_num + 32) & 0xff)); +} diff --git a/apps/bench/int-latency/apic.h b/apps/bench/int-latency/apic.h new file mode 100644 index 0000000..12a1074 --- /dev/null +++ b/apps/bench/int-latency/apic.h @@ -0,0 +1,94 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: bench/int-latency/apic.h + * Description: APIC register and bit definitions + * + * @LICENSE@ + * + * $Id: apic.h,v 1.1 2002/05/07 19:09:46 skoglund Exp $ + * + ********************************************************************/ +#ifndef __APIC_H__ +#define __APIC_H__ + + +/* + * APIC register locations. + */ + +#define X86_APIC_ID 0x020 +#define X86_APIC_VERSION 0x030 +#define X86_APIC_TASK_PRIO 0x080 +#define X86_APIC_ARBITR_PRIO 0x090 +#define X86_APIC_PROC_PRIO 0x0A0 +#define X86_APIC_EOI 0x0B0 +#define X86_APIC_LOCAL_DEST 0x0D0 +#define X86_APIC_DEST_FORMAT 0x0E0 +#define X86_APIC_SVR 0x0F0 +#define X86_APIC_ISR_BASE 0x100 +#define X86_APIC_TMR_BASE 0x180 +#define X86_APIC_IRR_BASE 0x200 +#define X86_APIC_ERR_STATUS 0x280 +#define X86_APIC_INTR_CMD1 0x300 +#define X86_APIC_INTR_CMD2 0x310 +#define X86_APIC_LVT_TIMER 0x320 +#define X86_APIC_PERF_COUNTER 0x340 +#define X86_APIC_LVT_LINT0 0x350 +#define X86_APIC_LVT_LINT1 0x360 +#define X86_APIC_LVT_ERROR 0x370 +#define X86_APIC_TIMER_COUNT 0x380 +#define X86_APIC_TIMER_CURRENT 0x390 +#define X86_APIC_TIMER_DIVIDE 0x3E0 + + +/* + * APIC LVT bits. + */ + +#define APIC_DEL_FIXED (0x0 << 8) +#define APIC_DEL_LOWESTPRIO (0x1 << 8) +#define APIC_DEL_SMI (0x2 << 8) +#define APIC_DEL_NMI (0x4 << 8) +#define APIC_DEL_INIT (0x5 << 8) +#define APIC_DEL_EXTINT (0x7 << 8) + +#define APIC_TRIGGER_LEVEL (1 << 15) +#define APIC_TRIGGER_EDGE (0 << 15) + +#define APIC_IRQ_MASK (1 << 16) + +#define APIC_TRIGGER_ONE_SHOT (0 << 17) +#define APIC_TRIGGER_PERIODIC (1 << 17) + + +/* + * Interface to APIC. + */ + +inline dword_t get_local_apic (dword_t reg) +{ + extern dword_t local_apic; + dword_t tmp; + tmp = *(volatile dword_t *) (local_apic + reg); + return tmp; +} + +inline void set_local_apic (dword_t reg, dword_t val) +{ + extern dword_t local_apic; + *(volatile dword_t *) (local_apic + reg) = val; +} + + +inline void apic_ack_irq (void) +{ + set_local_apic (X86_APIC_EOI, 0); +} + + +void setup_local_apic (dword_t apic_location); + + +#endif /* !__APIC_H__ */ diff --git a/apps/bench/int-latency/crt0-x86.S b/apps/bench/int-latency/crt0-x86.S new file mode 100644 index 0000000..3599507 --- /dev/null +++ b/apps/bench/int-latency/crt0-x86.S @@ -0,0 +1,36 @@ + .text + .global _start + .global _stext +_stext: +_start: + int3 + nop + leal __stack, %esp + pushl %ebx /* mbi ptr */ + pushl %eax /* mb magic */ + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/bench/int-latency/main.c b/apps/bench/int-latency/main.c new file mode 100644 index 0000000..3c85987 --- /dev/null +++ b/apps/bench/int-latency/main.c @@ -0,0 +1,394 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: bench/int-latency/main.c + * Description: Interrupt latancy benchmark + * + * @LICENSE@ + * + * $Id: main.c,v 1.2 2002/05/07 19:11:10 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#include +#include + +#include "../../sigma0/kip.h" +#include "apic.h" + + +#define MASTER_PRIO 201 +#define INT_PRIO 200 +#define WORKER_PRIO 199 + +#if 1 +extern "C" void memset (char * p, char c, int size) +{ + while (size--) + *(p++) = c; +} + +extern "C" char * strchr (char * s, int c) +{ + while (*s != c) + { + if (*s == 0) + return NULL; + s++; + } + return s; +} + +extern "C" char * strstr (char * big, char * little) +{ + char *cb, *cl; + + if (*strstr == '\0') + return big; + + for (;;) + { + big = strchr (big, *little); + if (big == NULL) + return NULL; + + for (cb = big, cl = little; + *cl != 0 && *cb != 0 && *cl == *cb; + cb++, cl++) ; + + if (*cl == 0) + return big; + else if (*cb == 0) + return NULL; + big++; + } +} + +extern "C" int atoi (char * nptr) +{ + int neg = 0, num = 0; + + if (*nptr == '-') + neg = 1; + + while (*nptr >= '0' && *nptr <= '9') + { + num *= 10; + num += *nptr - '0'; + nptr++; + } + + return neg ? -num : num; +} + +#endif + +inline dword_t rdtsc (void) +{ + dword_t ret; + asm volatile ("rdtsc" :"=a" (ret) : :"edx"); + return ret; +} + + +dword_t int_num = 9; +dword_t period = 50000000; + +l4_threadid_t pager_tid; +l4_threadid_t master_tid; +l4_threadid_t int_tid; +l4_threadid_t worker_tid; +l4_threadid_t starter_tid; + +dword_t cpu_freq, bus_freq; + +dword_t starter_stack[1024]; +dword_t int_stack[1024]; +dword_t worker_stack[1024]; + +void worker_thread (void) +{ + l4_msgdope_t dope; + + /* Notify interrupt handler thread. */ + l4_ipc_send (int_tid, 0, 0, 0, 0, L4_IPC_NEVER, &dope); + + for (;;) + ; +} + +void int_thread (void) +{ + dword_t dummy; + dword_t rdtsc0, rdtsc1, rdtsc2, time0, time1; + l4_msgdope_t dope; + bool go = true; + + /* Setup local APIC. */ + extern dword_t _end; + dword_t apic = ((dword_t) &_end + (1 << 12)) & ~((1 << 12) - 1); + apic = (apic + (1 << 22)) & ~((1 << 22) - 1); + + l4_sigma0_getpage_rcvpos (L4_NIL_ID, l4_fpage (0xfee00000, 22, 1, 0), + l4_fpage ((dword_t) apic, 22, 1, 0)); + + apic += 0xfee00000 & ((1 << 22) - 1); + setup_local_apic (apic); + + /* Wait for worker thread to come up. */ + l4_ipc_receive (worker_tid, 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + + /* Associate with IRQ. */ + associate_interrupt (int_num); + + /* Unmask APIC IRQ. */ + set_local_apic (X86_APIC_LVT_TIMER, + (get_local_apic (X86_APIC_LVT_TIMER) & ~APIC_IRQ_MASK)); + + set_local_apic (X86_APIC_TIMER_COUNT, period); + + while (go) + { + printf ("\n"); + printf (" Bus cycles CPU cycles\n"); + printf (" hw-kern kern-user kern-ipc ipc-user\n"); + + apic_ack_irq (); + l4_ipc_receive (L4_INTERRUPT (int_num), 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + apic_ack_irq (); + + for (int j = 10; j--;) + { + l4_ipc_receive (L4_INTERRUPT (int_num), 0, + &time0, &rdtsc0, &rdtsc1, + L4_IPC_NEVER, &dope); + + rdtsc2 = rdtsc (); + time1 = get_local_apic (X86_APIC_TIMER_CURRENT); + + apic_ack_irq (); + + printf ("%8d %8d %8d %8d\n", + period-time0, time0-time1, + rdtsc1-rdtsc0, rdtsc2-rdtsc1); + } + enter_kdebug ("done"); + + for (;;) + { + printf ("What now?\n" + " g - Continue\n" + " q - Quit/New measurement\n\n"); + char c = kd_inchar (); + if (c == 'g') { break; } + if (c == 'q') { go = false; break; } + } + } + + /* Tell master that we're finished. */ + l4_ipc_send (master_tid, 0, 0, 0, 0, L4_IPC_NEVER, &dope); + + for (;;) + l4_sleep (0); + /* NOTREACHED */ +} + +void startup_worker (void) +{ + l4_threadid_t foo = pager_tid; + dword_t dummy; + + /* Start worker thread. */ + l4_thread_ex_regs (int_tid, + (dword_t) int_thread, + (dword_t) int_stack + sizeof (int_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + l4_set_prio (worker_tid, WORKER_PRIO); + + /* Start doing the work. */ + int_thread (); +} + + + +#define PAGE_BITS 12 +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +dword_t pager_stack[512]; + +void pager (void) +{ + l4_threadid_t t; + l4_msgdope_t dope; + dword_t dw0, dw1, dw2; + dword_t map = 2; + + for (;;) + { + l4_ipc_wait (&t, 0, &dw0, &dw1, &dw2, L4_IPC_NEVER, &dope); + + for (;;) + { + dw0 &= PAGE_MASK; + dw1 = dw0 | 0x32; + l4_ipc_reply_and_wait (t, (void *) map, + dw0, dw1, dw2, + &t, 0, + &dw0, &dw1, &dw2, + L4_IPC_NEVER, &dope); + + if (L4_IPC_ERROR (dope)) + { + printf ("%s: error reply_and_wait (%x)\n", + __FUNCTION__, dope.raw); + break; + } + } + } +} + + + +int main (dword_t mbvalid, multiboot_info_t * mbi) +{ + l4_threadid_t foo; + l4_msgdope_t dope; + dword_t dummy; + bool is_small, is_inter_as; + + /* Parse commandline. */ + if (mbvalid == MULTIBOOT_VALID) + { + if (1) // (mbi->flags & MULTIBOOT_MODS) + { + char *arg, *cmdline = NULL; + for (dword_t i = 0; i < mbi->mods_count; i++) + { + cmdline = strstr (mbi->mods_addr[i].string, "/int-latency "); + if (cmdline) + break; + } + + if (cmdline) + { + if ((arg = strstr (cmdline, "interrupt=")) != NULL) + int_num = atoi (arg + sizeof ("interrupt=") - 1); + else if ((arg = strstr (cmdline, "period=")) != NULL) + period = atoi (arg + sizeof ("period=") - 1); + } + } + } + + /* Get kernel info page. */ + extern dword_t _end; + kernel_info_page_t * kip = (kernel_info_page_t *) + (((dword_t) &_end + (1 << 12)) & ~((1 << 12) - 1)); + + l4_sigma0_getkerninfo_rcvpos (L4_NIL_ID, + l4_fpage ((dword_t) kip, 12, 0, 0)); + + cpu_freq = kip->processor_frequency; + bus_freq = kip->bus_frequency; + printf ("CPU freq: %d, Bus freq: %d\n", cpu_freq, bus_freq); + + printf ("Int latency using the following code sequence for IPC:\n"); + printf ("->->->->->-\n"); + printf ("%s", IPC_SYSENTER); + printf ("\r-<-<-<-<-<-\n"); + + /* Create pager. */ + pager_tid = master_tid = l4_myself (); + pager_tid.id.thread = 1; + l4_thread_ex_regs (pager_tid, + (dword_t) pager, + (dword_t) pager_stack + sizeof (pager_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + /* Increase prio of self. */ + l4_set_prio (l4_myself(), MASTER_PRIO); + l4_set_prio (pager_tid, MASTER_PRIO); + + for (;;) + { + for (;;) + { + printf ("\nPlease select interrupt ipc type:\n"); + printf ("\n" + "0: INTER-AS\n" + "1: INTER-AS (small)\n" + "2: INTRA-AS\n"); + char c = kd_inchar(); + if (c == '0') { is_inter_as = true; is_small = false; break; }; + if (c == '1') { is_inter_as = true; is_small = true; break; }; + if (c == '2') { is_inter_as = false; is_small = false; break; }; + } + + extern dword_t _end, _start; + for (ptr_t x = (&_start); x < &_end; x++) + { + dword_t q; + q = *(volatile dword_t*)x; + } + + starter_tid = int_tid = worker_tid = master_tid; + + if (is_inter_as) + { + int_tid.id.task += 1; + worker_tid.id.task += 2; + int_tid.id.thread = 0; + worker_tid.id.thread = 0; + + /* Create separate tasks for both threads. */ + l4_task_new (int_tid, 255, + (dword_t) &int_stack[1024], + (dword_t) int_thread, pager_tid); + + l4_task_new (worker_tid, 255, + (dword_t) &worker_stack[1024], + (dword_t) worker_thread, pager_tid); + + if (is_small) + { + l4_set_small (int_tid, l4_make_small_id (8, 0)); + l4_set_small (worker_tid, l4_make_small_id (8, 1)); + } + + l4_set_prio (int_tid, INT_PRIO); + l4_set_prio (worker_tid, WORKER_PRIO); + } + else + { + int_tid.id.task += 1; + int_tid.id.thread = 0; + worker_tid.id.task = int_tid.id.task; + worker_tid.id.thread = 1; + + /* Create new task containing the new threads. */ + l4_task_new (int_tid, 255, + (dword_t) &int_stack[1024], + (dword_t) startup_worker, pager_tid); + } + + /* Wait for measurement to finish. */ + l4_ipc_receive (int_tid, 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + + l4_task_new (int_tid, 0, 0, 0, L4_NIL_ID); + if (is_inter_as) + l4_task_new (worker_tid, 0, 0, 0, L4_NIL_ID); + } + + for (;;) + enter_kdebug ("EOW"); +} diff --git a/apps/bench/intra-as/root_task.c b/apps/bench/intra-as/root_task.c new file mode 100644 index 0000000..06d8714 --- /dev/null +++ b/apps/bench/intra-as/root_task.c @@ -0,0 +1,226 @@ +#include +#include + + +#if 1 +extern "C" void memset(char* p, char c, int size) +{ + for (;size--;) + *(p++)=c; +} +#endif + + +static inline void rdpmc(int no, qword_t* res) +{ +#if (__ARCH__ == x86) + dword_t dummy; + __asm__ __volatile__ ( + "rdpmc" + : "=a"(*(dword_t*)res), "=d"(*((dword_t*)res + 1)), "=c"(dummy) + : "c"(no) + : "memory"); +#endif +} + + + + + + + + + +dword_t in, out; + +dword_t pong_stack[128]; +l4_threadid_t src; + +void pong_thread() +{ + dword_t dummy; + l4_msgdope_t dope; + l4_threadid_t t = src; + + while(1) +#if (__ARCH__ != x86) + l4_ipc_call(src, + 0, + 1, 2, 3, + 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); +#else + { + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "sub %%ebp, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (t.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(t.raw) + : "edx", "ebx", "edi"); + } +#endif +} + + + + +int main() +{ + l4_threadid_t tid; + + printf("KTEST using the following code sequence for IPC:\n"); + outstring("KTEST using the following code sequence for IPC:\n"); + printf("->->->->->-\n"); outstring("->->->->->-\n\r"); + printf(IPC_SYSENTER); outstring(IPC_SYSENTER); + printf("\r-<-<-<-<-<-\n"); outstring("\r-<-<-<-<-<-\n"); + + qword_t cnt0,cnt1; + + l4_threadid_t foo; + dword_t dummy; + l4_msgdope_t dope; + + src = tid = l4_myself(); + tid.id.thread = 3; + + l4_thread_ex_regs(tid, + (dword_t) pong_thread, (dword_t) pong_stack + sizeof(pong_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + /* wait for thread to come up */ + l4_ipc_receive(tid, 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + + while (14101973) + { + for (int j = 10; j--;) + { + + dword_t i; +#define ROUNDS 100000 + + i = ROUNDS; +#define FACTOR (8) + i /= FACTOR; i *= FACTOR; + outdec(i); kd_display(": "); + rdpmc(0,&cnt0); + __asm__ __volatile__ ("rdtsc" : "=a"(in): : "edx"); + for (;i; i -= FACTOR) + { +#if (__ARCH__ != x86) + l4_ipc_call(tid, + 0, + 0, 0, 0, + 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); +#else + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); + __asm__ __volatile__ ( + "mov $0, %%ebp \n\t" + IPC_SYSENTER + : "=a" (dummy), "=c" (dummy), "=S" (tid.raw) + : "a"(0), "c" (L4_IPC_NEVER.raw), "S"(tid.raw) + : "edx", "ebx", "edi"); +#endif + } + __asm__ __volatile__ ("rdtsc" : "=a"(out): : "edx"); + rdpmc(0,&cnt1); + printf("rdpmc(0) = %Ld\n", cnt0); + printf("rdpmc(0) = %Ld\n", cnt1); + printf("events: %ld.%02ld\n", + (((long)(cnt1-cnt0) )/(ROUNDS*2)), + (((long)(cnt1-cnt0)*100)/(ROUNDS*2))%100); + printf("%d cycles RTT\n", out-in); + outdec(out-in); kd_display(" cycles RTT\\r\\n"); + }; + enter_kdebug("done"); + } +} + + diff --git a/apps/bench/pingpong/Makefile b/apps/bench/pingpong/Makefile new file mode 100644 index 0000000..415415d --- /dev/null +++ b/apps/bench/pingpong/Makefile @@ -0,0 +1,23 @@ +include ../../Makeconf + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include +LDFLAGS += -N -L../../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ --save-temps +SFLAGS += --save-temps + +TARGET = $(notdir $(shell "pwd")) + +LINKBASE=0x00400000 + +all: $(TARGET).stripped + +$(TARGET): $(OBJS) Makefile ../../lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) -lio -lgcc + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/bench/pingpong/crt0-arm.S b/apps/bench/pingpong/crt0-arm.S new file mode 100644 index 0000000..c10848b --- /dev/null +++ b/apps/bench/pingpong/crt0-arm.S @@ -0,0 +1,29 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: crt0-arm.S + * Description: Startup code for ARM family processors. + * + * @LICENSE@ + * + * $Id: crt0-arm.S,v 1.1 2001/12/10 17:04:37 skoglund Exp $ + * + ********************************************************************/ +#include + + .globl _start +_start: + ldr sp, 2f + bl main +1: b 1b +2: .word _stack_top + + .globl atexit +atexit: + mov pc, lr + + .bss +_stack_bottom: + .space 8192 +_stack_top: diff --git a/apps/bench/pingpong/crt0-x86.S b/apps/bench/pingpong/crt0-x86.S new file mode 100644 index 0000000..3599507 --- /dev/null +++ b/apps/bench/pingpong/crt0-x86.S @@ -0,0 +1,36 @@ + .text + .global _start + .global _stext +_stext: +_start: + int3 + nop + leal __stack, %esp + pushl %ebx /* mbi ptr */ + pushl %eax /* mb magic */ + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/bench/pingpong/main.c b/apps/bench/pingpong/main.c new file mode 100644 index 0000000..4898d66 --- /dev/null +++ b/apps/bench/pingpong/main.c @@ -0,0 +1,352 @@ +#include + +#include +#include + + +//#define PERFMON + +#define PING_PONG_PRIO 128 + +int MIGRATE = 0; +int INTER_AS = 1; +int SMALL_AS = 0; + + +#if 1 +extern "C" void memset(char* p, char c, int size) +{ + for (;size--;) + *(p++)=c; +} +#endif + + +static inline void rdpmc(int no, qword_t* res) +{ +#if (__ARCH__ == x86) + dword_t dummy; + __asm__ __volatile__ ( +#if defined(PERFMON) + "rdpmc" +#else + "" +#endif + : "=a"(*(dword_t*)res), "=d"(*((dword_t*)res + 1)), "=c"(dummy) + : "c"(no) + : "memory"); +#endif +} + + +#if defined(CONFIG_ARCH_X86) +#define rdtsc(x) __asm__ __volatile__ ("rdtsc" : "=a"(x): : "edx"); +#else +#define rdtsc(x) x = 0 +#endif + + + +#define WHATTODO \ + "sub %%ebp,%%ebp \n\t" \ + "sub %%ecx,%%ecx \n\t" \ + "sub %%eax,%%eax \n\t" \ + IPC_SYSENTER + + + +l4_threadid_t master_tid; +l4_threadid_t ping_tid; +l4_threadid_t pong_tid; + + +dword_t ping_stack[1024]; +dword_t pong_stack[1024]; + +void pong_thread(void) +{ +#if (__ARCH__ != x86) + dword_t dummy; + l4_msgdope_t dope; +#endif + l4_threadid_t t = ping_tid; + + if (MIGRATE) + while (!get_current_cpu()) + /* wait */; + + while(1) +#if (__ARCH__ != x86) + l4_ipc_call(t, + 0, + 3, 2, 1, + 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); +#else + __asm__ __volatile__ ( + "pushl %%ebp \n\t" + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + "popl %%ebp \n\t" + : + : "S"(t.raw) + : "eax", "ecx", "edx", "ebx", "edi"); +#endif +} + +void ping_thread(void) +{ + dword_t in, out; +#ifdef PERFMON + qword_t cnt0,cnt1; +#endif + dword_t dummy; + l4_msgdope_t dope; + l4_threadid_t t = pong_tid; + dword_t go = 1; + + /* Wait for pong thread to come up. */ + l4_ipc_receive(t, 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + + while (go) + { + for (int j = 10; j--;) + { + dword_t i; +#define ROUNDS 100000 + i = ROUNDS; +#define FACTOR (8) + i /= FACTOR; i *= FACTOR; +#ifdef PERFMON + rdpmc(0,&cnt0); +#endif + rdtsc(in); + register l4_threadid_t t = pong_tid; + for (;i; i -= FACTOR) + { +#if (__ARCH__ != x86) + for (int j = 0; j < FACTOR; j++) + l4_ipc_call(t, + 0, + 1, 2, 3, + 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); +#else + __asm__ __volatile__ ( + "pushl %%ebp \n\t" + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + WHATTODO + "popl %%ebp \n\t" + : + : "S"(t.raw) + : "eax", "ecx", "edx", "ebx", "edi"); +#endif + } + rdtsc(out); +#ifdef PERFMON + rdpmc(0,&cnt1); + printf("rdpmc(0) = %Ld\n", cnt0); + printf("rdpmc(1) = %Ld\n", cnt1); + printf("events: %ld.%02ld\n", + (((long)(cnt1-cnt0) )/(ROUNDS*2)), + (((long)(cnt1-cnt0)*100)/(ROUNDS*2))%100); +#endif + printf("%d cycles (%d)\n", + (out-in), + (unsigned int) (((long)(out-in) )/(ROUNDS*2))); + outdec((out-in)/2); kd_display(" cycles\\r\\n"); + } + enter_kdebug("done"); + + for (;;) + { + outstring("What now?\r\n" + " g - Continue\r\n" + " q - Quit/New measurement\r\n\r\n"); + char c = kd_inchar(); + if ( c == 'g' ) { break; } + if ( c == 'q' ) { go = 0; break; } + } + } + + /* Tell master that we're finished. */ + l4_ipc_send(master_tid, 0, 0, 0, 0, L4_IPC_NEVER, &dope); + + for (;;) + l4_sleep(0); + /* NOTREACHED */ +} + + +#define PAGE_BITS 12 +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +dword_t pager_stack[512]; + +void pager(void) +{ + l4_threadid_t t; + l4_msgdope_t dope; + dword_t dw0, dw1, dw2; + dword_t map = 2; + + while (4) + { + l4_ipc_wait(&t, 0, &dw0, &dw1, &dw2, L4_IPC_NEVER, &dope); + + while(5) + { + /* touch page */ + // *((volatile dword_t*) dw0) = *((volatile dword_t*) dw0); + dw0 &= PAGE_MASK; + dw1 = dw0 | 0x32; + l4_ipc_reply_and_wait(t, (void *) map, + dw0, dw1, dw2, + &t, 0, + &dw0, &dw1, &dw2, + L4_IPC_NEVER, &dope); + if (L4_IPC_ERROR(dope)) + { + printf("%s: error reply_and_wait (%x)\n", + __FUNCTION__, dope.raw); + break; + } + } + } +} + +int main(void) +{ + l4_threadid_t thepager, foo; + l4_msgdope_t dope; + dword_t dummy; + +// printf("KVER=%x\n", ({int v; asm("hlt" : "=a"(v)); v;})); + +// printf("KVER=%x\n", l4_get_kernelversion()); + +// enter_kdebug("xxx"); +// __asm__ __volatile__ ("int $30;jmp 1f;.ascii \"huhu\";1:"); +// enter_kdebug("yyy"); + + printf("KTEST using the following code sequence for IPC:\n"); + outstring("KTEST using the following code sequence for IPC:\n"); + printf("->->->->->-\n"); outstring("->->->->->-\n\r\t"); + printf("%s", IPC_SYSENTER); outstring(IPC_SYSENTER); + printf("\r-<-<-<-<-<-\n"); outstring("\r-<-<-<-<-<-\n"); + + /* Create pager */ + thepager = master_tid = l4_myself(); + thepager.id.thread = 1; + l4_thread_ex_regs(thepager, + (dword_t) pager, + (dword_t) pager_stack + sizeof(pager_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + for (;;) + { + for (;;) + { + outstring("\nPlease select ipc type:\n"); + outstring("\r\n" + "0: INTER-AS\r\n" + "1: INTER-AS (small)\r\n" + "2: INTRA-AS\r\n" + "3: XCPU\r\n"); + char c = kd_inchar(); + if (c == '0') { INTER_AS=1; MIGRATE=0; SMALL_AS=0; break; }; + if (c == '1') { INTER_AS=1; MIGRATE=0; SMALL_AS=1; break; }; + if (c == '2') { INTER_AS=0; MIGRATE=0; SMALL_AS=0; break; }; + if (c == '3') { INTER_AS=0; MIGRATE=1; SMALL_AS=0; break; }; + } + + extern dword_t _end, _start; + for (ptr_t x = (&_start); x < &_end; x++) + { + dword_t q; + q = *(volatile dword_t*)x; + } + + ping_tid = pong_tid = master_tid; + + if (INTER_AS) + { + ping_tid.id.task += 1; + pong_tid.id.task += 2; + ping_tid.id.thread = 0; + pong_tid.id.thread = 0; + + l4_task_new(pong_tid, 255, + (dword_t) &pong_stack[1024], + (dword_t) pong_thread, thepager); + + l4_task_new(ping_tid, 255, + (dword_t) &ping_stack[1024], + (dword_t) ping_thread, thepager); + +#ifdef PING_PONG_PRIO + l4_set_prio(ping_tid, PING_PONG_PRIO); + l4_set_prio(pong_tid, PING_PONG_PRIO); +#endif + + if (SMALL_AS) + { + l4_set_small(ping_tid, l4_make_small_id(2, 0)); + l4_set_small(pong_tid, l4_make_small_id(2, 1)); + } + + if (MIGRATE) + l4_migrate_thread(pong_tid, 1); + } + else + { + ping_tid.id.thread = 2; + pong_tid.id.thread = 3; + foo = get_current_pager(master_tid); + + l4_thread_ex_regs(pong_tid, + (dword_t) pong_thread, + (dword_t) pong_stack + sizeof(pong_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + l4_thread_ex_regs(ping_tid, + (dword_t) ping_thread, + (dword_t) ping_stack + sizeof(ping_stack), + &foo, &foo, &dummy, &dummy, &dummy); + + if (MIGRATE) + l4_migrate_thread(pong_tid, 1); + } + + /* Wait for measurement to finish. */ + l4_ipc_receive(ping_tid, 0, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &dope); + + if (INTER_AS) + { + l4_task_new(ping_tid, 0, 0, 0, L4_NIL_ID); + l4_task_new(pong_tid, 0, 0, 0, L4_NIL_ID); + } + } + + for (;;) + enter_kdebug("EOW"); +} diff --git a/apps/include/.cvsignore b/apps/include/.cvsignore new file mode 100644 index 0000000..0e56cf2 --- /dev/null +++ b/apps/include/.cvsignore @@ -0,0 +1 @@ +config.h diff --git a/apps/include/config.h b/apps/include/config.h new file mode 100644 index 0000000..3fc1cc0 --- /dev/null +++ b/apps/include/config.h @@ -0,0 +1,21 @@ +/* + * Automatically generated C config: don't edit + */ +#define AUTOCONF_INCLUDED +/* + * Architecture + */ +#define CONFIG_ARCH_X86 1 +#define CONFIG_ARCH_X86_I586 1 +/* + * Kernel Configuration + */ +#define CONFIG_VERSION_X0 1 +#define CONFIG_L4_NEWSIGMA0 1 +#define CONFIG_IO_FLEXPAGES 1 +/* + * Base Applications + */ +#define CONFIG_BUILD_SIGMA0 1 +#define LBS0_X86 0x00020000 +#define CONFIG_LIBIO_OUTSCRN 1 diff --git a/apps/include/l4/.cvsignore b/apps/include/l4/.cvsignore new file mode 100644 index 0000000..0e56cf2 --- /dev/null +++ b/apps/include/l4/.cvsignore @@ -0,0 +1 @@ +config.h diff --git a/apps/include/l4/arch b/apps/include/l4/arch new file mode 120000 index 0000000..f4bad79 --- /dev/null +++ b/apps/include/l4/arch @@ -0,0 +1 @@ +x86 \ No newline at end of file diff --git a/apps/include/l4/arm/kernel.h b/apps/include/l4/arm/kernel.h new file mode 100644 index 0000000..8760d2a --- /dev/null +++ b/apps/include/l4/arm/kernel.h @@ -0,0 +1,80 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: l4/arm/kernel.h + * Description: Kernel info page for ARM architectures. + * + * @LICENSE@ + * + * $Id: kernel.h,v 1.2 2001/12/13 08:34:48 uhlig Exp $ + * + ********************************************************************/ +#ifndef __L4__ARM__KERNEL_H__ +#define __L4__ARM__KERNEL_H__ + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; + byte_t reserved[7]; + + dword_t kdebug_init; + dword_t kdebug_exception; + struct { + dword_t low; + dword_t high; + } kdebug_memory; + + dword_t sigma0_esp, sigma0_eip; + struct { + dword_t low; + dword_t high; + } sigma0_memory; + + dword_t sigma1_esp, sigma1_eip; + struct { + dword_t low; + dword_t high; + } sigma1_memory; + + dword_t root_esp, root_eip; + struct { + dword_t low; + dword_t high; + } root_memory; + + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; + + struct { + dword_t low; + dword_t high; + } main_memory; + + struct { + dword_t low; + dword_t high; + } reserved0; + + struct { + dword_t low; + dword_t high; + } reserved1; + + struct { + dword_t low; + dword_t high; + } dedicated[5]; + + volatile dword_t clock; + +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + + +#endif /* !__L4__ARM__KERNEL_H__ */ diff --git a/apps/include/l4/arm/l4.h b/apps/include/l4/arm/l4.h new file mode 100644 index 0000000..4d7a36b --- /dev/null +++ b/apps/include/l4/arm/l4.h @@ -0,0 +1,754 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: l4/arm/l4.h + * Description: Data types and syscall bindings for ARM. + * + * @LICENSE@ + * + * $Id: l4.h,v 1.13 2002/10/01 04:37:27 ud3 Exp $ + * + ********************************************************************/ +#ifndef __L4__ARM__L4_H__ +#define __L4__ARM__L4_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(L4_NO_SYSCALL_INLINES) || defined(__GENERATE_L4LIB__) +# define L4_INLINE +#else +# define L4_INLINE extern __inline__ +#endif + + +/* +** +** Data type definitions. +** +*/ + +typedef qword_t cpu_time_t; + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t raw; + l4_fpage_struct_t fp; +} l4_fpage_t; + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U +#define L4_FP_ADDRMASK 0xfffff000U +#define L4_WHOLE_ADDRESS_SPACE (32) + + +#define L4_IPC_OPEN_IPC 1 + + + +/* +** +** Prototypes. +** +*/ + +L4_INLINE l4_threadid_t l4_myself (void); +L4_INLINE int l4_nchief (l4_threadid_t destination, + l4_threadid_t *next_chief); +L4_INLINE void l4_fpage_unmap (l4_fpage_t fpage, + dword_t mask); +L4_INLINE l4_fpage_t l4_fpage (dword_t address, + dword_t size, + dword_t write, + dword_t grant); +L4_INLINE void l4_thread_switch (l4_threadid_t destintaion); +L4_INLINE void l4_yield (void); +L4_INLINE void l4_thread_ex_regs (l4_threadid_t destination, + dword_t ip, + dword_t sp, +#if defined(CONFIG_VERSION_X0) + l4_threadid_t *preempter, +#endif + l4_threadid_t *pager, + dword_t *old_ip, + dword_t *old_sp, + dword_t *old_cpsr); +#if defined(CONFIG_VERSION_X0) +L4_INLINE void l4_task_new (l4_threadid_t dest, + dword_t mcp, + dword_t usp, + dword_t uip, + l4_threadid_t pager); +#elif defined(CONFIG_VERSION_X1) +L4_INLINE void l4_create_thread (l4_threadid_t tid, + l4_threadid_t master, + l4_threadid_t pager, + dword_t uip, + dword_t usp); +#endif +L4_INLINE cpu_time_t l4_thread_schedule(l4_threadid_t dest, + l4_sched_param_t param, + l4_threadid_t *ext_preempter, + l4_threadid_t *partner, + l4_sched_param_t *old_param); + + + + +/* +** +** System call identification numbers (these must match the ones defined +** within the kernel). +** +*/ + +#ifndef L4_NO_SYSCALL_INLINES + +#ifdef EXCEPTION_VECTOR_RELOCATED + +#define L4_SYSCALL_MAGIC_OFFSET 8 +#define L4_SYSCALL_IPC (-0x00000004-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_ID_NEAREST (-0x00000008-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_FPAGE_UNMAP (-0x0000000C-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_THREAD_SWITCH (-0x00000010-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_THREAD_SCHEDULE (-0x00000014-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_LTHREAD_EX_REGS (-0x00000018-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_CREATE_THREAD (-0x0000001C-L4_SYSCALL_MAGIC_OFFSET) +#define L4_SYSCALL_ENTER_KDEBUG (-0x00000020-L4_SYSCALL_MAGIC_OFFSET) + +#else + +#define L4_SYSCALL_IPC 0x00000004 +#define L4_SYSCALL_ID_NEAREST 0x00000008 +#define L4_SYSCALL_FPAGE_UNMAP 0x0000000C +#define L4_SYSCALL_THREAD_SWITCH 0x00000010 +#define L4_SYSCALL_THREAD_SCHEDULE 0x00000014 +#define L4_SYSCALL_LTHREAD_EX_REGS 0x00000018 +#define L4_SYSCALL_CREATE_THREAD 0x0000001C +#define L4_SYSCALL_ENTER_KDEBUG 0x00000020 + +#endif /* !EXCEPTION_VECTOR_RELOCATED */ + +#define IPC_SYSENTER \ + " mov lr, pc \n" \ + " mov pc, %0 \n" + + + + +/* +** +** Kdebug stuff. +** +*/ + +#define enter_kdebug(text...) \ +__asm__ __volatile__ ( \ + " mov lr, pc \n" \ + " mov pc, %0 \n" \ + " b 1f \n" \ + " .ascii \"" text "\" \n" \ + " .byte 0 \n" \ + " .align 2 \n" \ + "1: \n" \ + : \ + : "i" (L4_SYSCALL_ENTER_KDEBUG) \ + : "lr") + + +L4_INLINE void outstring(const char* x) +{ + __asm__ __volatile__ ( + " mov r0, %1 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " cmp lr, #2 \n" + : + : "i" (L4_SYSCALL_ENTER_KDEBUG), "r"(x) + : "r0", "lr"); +} + +L4_INLINE void outdec(const dword_t x) +{ +} + +L4_INLINE void kd_display(const char* x) +{ +} + +L4_INLINE char kd_inchar() +{ + char c; + __asm__ __volatile__ ( + " mov lr, pc \n" + " mov pc, %1 \n" + " cmp lr, #13 \n" + " mov %0, r0 \n" + : "=r" (c) + : "i" (L4_SYSCALL_ENTER_KDEBUG) + : "r0", "lr"); + return c; +} + + +/* +** +** Syscall binding implementation. +** +*/ + +L4_INLINE l4_threadid_t l4_myself(void) +{ + l4_threadid_t id; + + __asm__ __volatile__ ( + " mov r0, %2 \n" + " mov lr, pc \n" + " mov pc, %1 \n" + " mov %0, r0 \n" + :"=r" (id) + :"i" (L4_SYSCALL_ID_NEAREST), + "i" (L4_NIL_ID.raw) + :"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + + return id; +} + + + +L4_INLINE void l4_fpage_unmap(l4_fpage_t fpage, dword_t mask) +{ + __asm__ __volatile__ ( + " mov r0, %1 @ l4_fpage_unmap \n" + " mov r1, %2 \n" + " mov pc, %0 \n" + : + :"i" (L4_SYSCALL_FPAGE_UNMAP), + "ri" (fpage.raw), + "ri" (mask) + :"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); +} + + + +L4_INLINE l4_fpage_t l4_fpage(dword_t address, + dword_t size, + dword_t write, + dword_t grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_FP_ADDRMASK) >> 12 }}); +} + + + +L4_INLINE void l4_thread_switch(l4_threadid_t dest) +{ + __asm__ __volatile__ ( + " mov r0, %1 @ l4_thread_switch \n" + " mov lr, pc \n" + " mov pc, %0 \n" + : + :"i" (L4_SYSCALL_THREAD_SWITCH), + "r" (dest) + :"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); +} + + + +L4_INLINE void l4_yield(void) +{ + l4_thread_switch(L4_NIL_ID); +} + + + +L4_INLINE void l4_thread_ex_regs(l4_threadid_t destination, + dword_t ip, + dword_t sp, +#if defined(CONFIG_VERSION_X0) + l4_threadid_t *preempter, +#endif + l4_threadid_t *pager, + dword_t *old_ip, + dword_t *old_sp, + dword_t *old_cpsr) +{ + struct { + l4_threadid_t tid; + dword_t ip; + dword_t sp; + l4_threadid_t pager; + dword_t flags; + } x = { destination, ip, sp, *pager, 0 }; + +#if defined(CONFIG_VERSION_X0) + x.tid.raw = destination.id.thread; +#endif + + __asm__ __volatile__ ( + " ldr r0, %1 @ l4_lthread_ex_regs \n" + " ldr r1, %2 \n" + " ldr r2, %3 \n" + " ldr r3, %4 \n" + + " mov lr, pc \n" + " mov pc, %0 \n" + + " str r0, %1 \n" + " str r1, %2 \n" + " str r2, %3 \n" + " str r3, %4 \n" + " str r4, %5 \n" + + : + : + "i" (L4_SYSCALL_LTHREAD_EX_REGS), + "m" (x.tid), + "m" (x.ip), + "m" (x.sp), + "m" (x.pager), + "m" (x.flags) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + + *pager = x.pager; + *old_ip = x.ip; + *old_sp = x.sp; + *old_cpsr = x.flags; +} + +#if defined(CONFIG_VERSION_X0) + +L4_INLINE void l4_task_new(l4_threadid_t dest, + dword_t mcp, + dword_t usp, + dword_t uip, + l4_threadid_t pager) +{ + dword_t x[] = {dest.raw, mcp, pager.raw, uip, usp}; + + __asm__ __volatile__ (" \n" + " /* l4_task_new() */ \n" + " ldr r0, %1 \n" + " ldr r1, %2 \n" + " ldr r2, %3 \n" + " ldr r3, %4 \n" + " ldr r4, %5 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + : + :"i" (L4_SYSCALL_CREATE_THREAD), + "m" (x[0]), "m" (x[1]), "m" (x[2]), "m" (x[3]), "m" (x[4]) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + +} + +#elif defined(CONFIG_VERSION_X1) + +L4_INLINE void l4_create_thread(l4_threadid_t tid, + l4_threadid_t master, + l4_threadid_t pager, + dword_t uip, + dword_t usp) +{ + dword_t x[] = {tid.raw, master.raw, pager.raw, uip, usp}; + + __asm__ __volatile__ ( + "\n\t/* create_thread(start) */ \n" + " ldr r0, %1 \n" + " ldr r1, %2 \n" + " ldr r2, %3 \n" + " ldr r3, %4 \n" + " ldr r4, %5 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + "\t/* create_thread(end) */ \n" + : + :"i" (L4_SYSCALL_CREATE_THREAD), + "m" (x[0]), "m" (x[1]), "m" (x[2]), "m" (x[3]), "m" (x[4]) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + +} + +#endif /* CONFIG_VERSION_X1 */ + +L4_INLINE cpu_time_t l4_thread_schedule(l4_threadid_t dest, + l4_sched_param_t param, + l4_threadid_t *ext_preempter, + l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + /* external preempter and ipc partner are ignored */ + __asm__ __volatile__ ( + "/* l4_thread_schedule */ \n" + " mov r0, %4 \n" + " mov r1, %3 \n" + + " mov lr, pc \n" + " mov pc, %2 \n" + + " mov r0, %1 \n" + + + :"=r" (partner), + "=r" (*old_param) + :"i" (L4_SYSCALL_THREAD_SCHEDULE), + "r" (dest), + "r" (param) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r10", "r11", "r12", "r14"); + + return 0; +} + + + +L4_INLINE int l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, + dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + union { + struct { + dword_t rcv; + l4_timeout_t timeout; + } in; + struct { + dword_t dw0; + dword_t dw1; + dword_t dw2; + l4_threadid_t src; + l4_msgdope_t result; + } out; + } x = { in: {((dword_t) rcv_msg | L4_IPC_OPEN_IPC), timeout}}; + + /* sys_ipc */ + asm volatile( + "/* l4_ipc_wait(start) */ \n" + " ldr r2, %1 \n" + " ldr r3, %7 \n" + " mov r1, #0xFFFFFFFF \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " str r0, %6 \n" + " str r1, %2 \n" + " str r4, %3 \n" + " str r5, %4 \n" + " str r6, %5 \n" + "\t/* l4_ipc_wait(end) */ \n" + : + : "i" (L4_SYSCALL_IPC), + "m" (x.in.rcv), + "m" (x.out.src), + "m" (x.out.dw0), + "m" (x.out.dw1), + "m" (x.out.dw2), + "m" (x.out.result), + "m" (x.in.timeout) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + *rcv_dword0 = x.out.dw0; + *rcv_dword1 = x.out.dw1; + *rcv_dword2 = x.out.dw2; + *result = x.out.result; + *src = x.out.src; + + return result->md.error_code; +} + + + +L4_INLINE int l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, + dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + union { + struct { + l4_threadid_t src; + dword_t rcv; + l4_timeout_t timeout; + } in; + struct { + dword_t dw0; + dword_t dw1; + dword_t dw2; + l4_msgdope_t result; + } out; + } x = { in: {src, (dword_t) rcv_msg, timeout}}; + + /* sys_ipc */ + asm volatile( + "/* l4_ipc_receive(start) */ \n" + " ldr r1, %2 \n" + " ldr r2, %1 \n" + " ldr r3, %7 \n" + " mov r1, #0xFFFFFFFF \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " str r0, %6 \n" + " str r1, %2 \n" + " str r4, %3 \n" + " str r5, %4 \n" + " str r6, %5 \n" + "\t/* l4_ipc_receive(end) */ \n" + : + : "i" (L4_SYSCALL_IPC), + "m" (x.in.rcv), + "m" (x.in.src), + "m" (x.out.dw0), + "m" (x.out.dw1), + "m" (x.out.dw2), + "m" (x.out.result), + "m" (x.in.timeout) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory" + ); + *rcv_dword0 = x.out.dw0; + *rcv_dword1 = x.out.dw1; + *rcv_dword2 = x.out.dw2; + *result = x.out.result; +#if defined(CONFIG_VERSION_X1) + *src = x.out.src; +#endif + + return result->md.error_code; +} + + + +L4_INLINE int l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, + dword_t snd_dword1, + dword_t snd_dword2, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct + { + dword_t tid; + dword_t snd_dsc; + dword_t timeout; + dword_t dw0; + dword_t dw1; + dword_t dw2; + l4_msgdope_t result; + } x = {dest.raw, (dword_t) snd_msg, timeout.raw, + snd_dword0, snd_dword1, snd_dword2}; + + __asm__ __volatile__ ( + "/* l4_ipc_send(start) */ \n" + " ldr r0, %1 \n" + " ldr r1, %2 \n" + " mov r2, %3 \n" + " ldr r4, %4 \n" + " ldr r5, %5 \n" + " ldr r6, %6 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " str r0, %7 \n" + "\t/*l4_ipc_send(end) */ \n" + : + : "i" (L4_SYSCALL_IPC), + "m" (x.tid), + "m" (x.snd_dsc), + "i" (~0U), + "m" (x.dw0), + "m" (x.dw1), + "m" (x.dw2), + "m" (x.result) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory" + ); + + *result = x.result; + + return result->md.error_code; +} + + + +L4_INLINE int l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, + dword_t snd_dword1, + dword_t snd_dword2, + void *rcv_msg, + dword_t *rcv_dword0, + dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct + { + dword_t tid; + dword_t snd_dsc; + dword_t rcv_dsc; + dword_t timeout; + dword_t dw0; + dword_t dw1; + dword_t dw2; + l4_msgdope_t result; + } x = {dest.raw, (dword_t) snd_msg, (dword_t) rcv_msg, timeout.raw, + snd_dword0, snd_dword1, snd_dword2}; + + __asm__ __volatile__ ( + "/* l4_ipc_call(start) */ \n" + " ldr r0, %1 \n" + " ldr r1, %2 \n" + " ldr r2, %3 \n" + " ldr r3, %8 \n" + " ldr r4, %4 \n" + " ldr r5, %5 \n" + " ldr r6, %6 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " str r0, %7 \n" + " str r4, %4 \n" + " str r5, %5 \n" + " str r6, %6 \n" + "\t/*l4_ipc_call(end) */ \n" + : + : "i" (L4_SYSCALL_IPC), + "m" (x.tid), + "m" (x.snd_dsc), + "m" (x.rcv_dsc), + "m" (x.dw0), + "m" (x.dw1), + "m" (x.dw2), + "m" (x.result), + "m" (x.timeout) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + *rcv_dword0 = x.dw0; + *rcv_dword1 = x.dw1; + *rcv_dword2 = x.dw2; + *result = x.result; + + return result->md.error_code; +} + + + +L4_INLINE int l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, + dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, + dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct + { + dword_t tid; + dword_t snd_dsc; + dword_t rcv_dsc; + l4_timeout_t timeout; + dword_t dw0; + dword_t dw1; + dword_t dw2; + l4_msgdope_t result; + } x = {dest.raw, (dword_t) snd_msg, (dword_t) rcv_msg | L4_IPC_OPEN_IPC, + timeout, snd_dword0, snd_dword1, snd_dword2}; + + __asm__ __volatile__ ( + "/* l4_ipc_reply_and_wait(start) */ \n" + " ldr r0, %1 \n" + " ldr r1, %2 \n" + " ldr r2, %3 \n" + " ldr r3, %8 \n" + " ldr r4, %4 \n" + " ldr r5, %5 \n" + " ldr r6, %6 \n" + " mov lr, pc \n" + " mov pc, %0 \n" + " str r0, %7 \n" + " str r1, %1 \n" + " str r4, %4 \n" + " str r5, %5 \n" + " str r6, %6 \n" + "\t/*l4_ipc_reply_and_wait(end) */ \n" + : + : "i" (L4_SYSCALL_IPC), + "m" (x.tid), + "m" (x.snd_dsc), + "m" (x.rcv_dsc), + "m" (x.dw0), + "m" (x.dw1), + "m" (x.dw2), + "m" (x.result), + "m" (x.timeout) + :"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r14", "memory"); + *rcv_dword0 = x.dw0; + *rcv_dword1 = x.dw1; + *rcv_dword2 = x.dw2; + src->raw = x.tid; + *result = x.result; + + return result->md.error_code; + return 0; +} + + +#endif /* !NO_SYSCALL_INLINES */ + +#ifdef __cplusplus +} +#endif + + +#endif /* !__L4__ARM__L4_H__ */ diff --git a/apps/include/l4/helpers.h b/apps/include/l4/helpers.h new file mode 100755 index 0000000..dfd0823 --- /dev/null +++ b/apps/include/l4/helpers.h @@ -0,0 +1,179 @@ +/********************************************************************* + * + * Copyright (C) 2000-2003, Karlsruhe University + * + * File path: l4/helpers.h + * Description: helper functions making live with l4 easier + * + * @LICENSE@ + * + * $Id: helpers.h,v 1.10 2003/02/19 15:55:54 sgoetz Exp $ + * + ********************************************************************/ + +#ifndef __L4_HELPERS_H__ +#define __L4_HELPERS_H__ + +#define M_BITS 8 + +#define is_good_m(x) ((x) < (1 << M_BITS)) + +#define best_m1(x) (x) +#define best_m2(x) (is_good_m(x) ? x : best_m1(x>>2)) +#define best_m3(x) (is_good_m(x) ? x : best_m2(x>>2)) +#define best_m4(x) (is_good_m(x) ? x : best_m3(x>>2)) +#define best_m5(x) (is_good_m(x) ? x : best_m4(x>>2)) +#define best_m6(x) (is_good_m(x) ? x : best_m5(x>>2)) +#define best_m7(x) (is_good_m(x) ? x : best_m6(x>>2)) +#define best_m8(x) (is_good_m(x) ? x : best_m7(x>>2)) +#define best_m9(x) (is_good_m(x) ? x : best_m8(x>>2)) +#define best_m10(x) (is_good_m(x) ? x : best_m9(x>>2)) +#define best_m11(x) (is_good_m(x) ? x : best_m10(x>>2)) +#define best_m12(x) (is_good_m(x) ? x : best_m11(x>>2)) +#define best_m13(x) (is_good_m(x) ? x : best_m12(x>>2)) +#define best_m14(x) (is_good_m(x) ? x : best_m13(x>>2)) +#define best_mant(x) (is_good_m(x) ? x : best_m14(x>>2)) + +#define best_e1(x) (1) +#define best_e2(x) (is_good_m(x) ? 2 : best_e1(x>>2)) +#define best_e3(x) (is_good_m(x) ? 3 : best_e2(x>>2)) +#define best_e4(x) (is_good_m(x) ? 4 : best_e3(x>>2)) +#define best_e5(x) (is_good_m(x) ? 5 : best_e4(x>>2)) +#define best_e6(x) (is_good_m(x) ? 6 : best_e5(x>>2)) +#define best_e7(x) (is_good_m(x) ? 7 : best_e6(x>>2)) +#define best_e8(x) (is_good_m(x) ? 8 : best_e7(x>>2)) +#define best_e9(x) (is_good_m(x) ? 9 : best_e8(x>>2)) +#define best_e10(x) (is_good_m(x) ? 10 : best_e9(x>>2)) +#define best_e11(x) (is_good_m(x) ? 11 : best_e10(x>>2)) +#define best_e12(x) (is_good_m(x) ? 12 : best_e11(x>>2)) +#define best_e13(x) (is_good_m(x) ? 13 : best_e12(x>>2)) +#define best_e14(x) (is_good_m(x) ? 14 : best_e13(x>>2)) +#define best_exp(x) (is_good_m(x) ? 15 : best_e14(x>>2)) + + +#define l4_time(ms) best_mant(ms), best_exp(ms) + + +#define mus(x) (x) +#define mills(x) (1000*mus(x)) +#define secs(x) (1000*mills(x)) +#define mins(x) (60*secs(x)) +#define hours(x) (60*mins(x)) + + + +L4_INLINE +void create_thread(int id, void *ip, void *stack, l4_threadid_t pager) +{ + l4_threadid_t tid, preempter; + dword_t flags; + tid.id.thread = id; + + l4_thread_ex_regs(tid, (dword_t)ip, (dword_t)stack, +#if defined(CONFIG_VERSION_X0) + &preempter, +#endif + &pager, (dword_t*) &flags, + (dword_t *) &ip, (dword_t * )&stack); +} + +L4_INLINE +l4_threadid_t get_current_pager(l4_threadid_t myself) +{ + l4_threadid_t preempter = L4_INVALID_ID, pager = L4_INVALID_ID; + dword_t dummy; + + if (l4_is_nil_id(myself)) + myself = l4_myself(); + l4_thread_ex_regs(myself, ~0, ~0, +#if defined(CONFIG_VERSION_X0) + &preempter, +#endif + &pager, &dummy, &dummy, &dummy); + + return pager; +} + +L4_INLINE +int associate_interrupt(int nr) +{ + dword_t dummy; + l4_msgdope_t result; + + return l4_ipc_receive(L4_INTERRUPT(nr), 0, &dummy, &dummy, &dummy, + L4_IPC_TIMEOUT_NULL, &result); +} + +L4_INLINE +void l4_sleep(dword_t us) +{ + dword_t dummy; + l4_msgdope_t result; + + l4_ipc_receive(L4_NIL_ID, 0, &dummy, &dummy, &dummy, + us ? (l4_timeout_t) {timeout : { best_exp(us), best_exp(us), 0, 0, best_mant(us), best_mant(us)}} : L4_IPC_NEVER, &result); +} + +/* xxx: hack for L4-KA -- ecx return's the current cpu on smp systems */ +#if defined(CONFIG_ARCH_X86) +L4_INLINE dword_t get_current_cpu(void) +{ + dword_t cpu; + __asm__ __volatile__("pushl %%ebp \n" + "xorl %%esi, %%esi \n" + "int $0x31 \n" + "popl %%ebp \n" + : "=c"(cpu) + : + : "eax", "ebx", "edx", "esi", "edi"); + return cpu; +} +#else +#define get_current_cpu() (0) +#endif + +L4_INLINE void l4_migrate_thread(l4_threadid_t tid, dword_t cpu) +{ + l4_sched_param_t schedparam; + l4_threadid_t foo_id = L4_INVALID_ID; + l4_thread_schedule(tid, (l4_sched_param_t) {sched_param:0xFFFFFFFF}, &foo_id, &foo_id, &schedparam); + schedparam.sp.small = 0; + schedparam.sp.zero = cpu + 1; + foo_id = L4_INVALID_ID; + l4_thread_schedule(tid, schedparam, &foo_id, &foo_id, &schedparam); +} + +L4_INLINE void l4_set_prio(l4_threadid_t tid, dword_t prio) +{ + l4_sched_param_t schedparam; + l4_threadid_t foo_id = L4_INVALID_ID; + l4_thread_schedule(tid, (l4_sched_param_t) {sched_param:0xFFFFFFFF}, &foo_id, &foo_id, &schedparam); + schedparam.sp.small = 0; + schedparam.sp.zero = 0; + schedparam.sp.prio = prio; + foo_id = L4_INVALID_ID; + l4_thread_schedule(tid, schedparam, &foo_id, &foo_id, &schedparam); +} + +L4_INLINE dword_t l4_make_small_id(dword_t size, dword_t num) +{ + return ((num << 1) | 1) << (size - 1); +} + +L4_INLINE void l4_set_small(l4_threadid_t tid, dword_t small) +{ + l4_sched_param_t schedparam; + l4_threadid_t foo_id = L4_INVALID_ID; + + l4_thread_schedule(tid, (l4_sched_param_t) {sched_param:0xFFFFFFFF}, + &foo_id, &foo_id, &schedparam); + + schedparam.sp.small = small; + schedparam.sp.zero = 0; + foo_id = L4_INVALID_ID; + + l4_thread_schedule(tid, schedparam, &foo_id, &foo_id, &schedparam); +} + + +#endif /* __L4_HELPERS_H__ */ diff --git a/apps/include/l4/l4.h b/apps/include/l4/l4.h new file mode 100644 index 0000000..3caf5a3 --- /dev/null +++ b/apps/include/l4/l4.h @@ -0,0 +1,256 @@ +/********************************************************************* + * + * Copyright (C) 2001-2002, Karlsruhe University + * + * File path: l4/l4.h + * Description: standard l4 include file + * + * @LICENSE@ + * + * $Id: l4.h,v 1.13 2002/07/18 13:45:46 sgoetz Exp $ + * + ********************************************************************/ + +#ifndef __L4__L4_H__ +#define __L4__L4_H__ + + + + +/********************************************************************** + * + * base types + * + **********************************************************************/ + +/* architecture dependent types ??? +#include +*/ + +typedef unsigned long long qword_t; +typedef unsigned int dword_t; +typedef unsigned short word_t; +typedef unsigned char byte_t; + +typedef signed long long sqword_t; +typedef signed int sdword_t; +typedef signed short sword_t; +typedef signed char sbyte_t; + +typedef dword_t* ptr_t; + +#ifndef NULL +#define NULL (0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + + + +#if defined(L4_NO_SYSCALL_INLINES) || defined(__GENERATE_L4LIB__) +# define L4_INLINE +#else +# define L4_INLINE extern __inline__ +#endif + + + + +/********************************************************************** + * + * configuration ??? + * + **********************************************************************/ + + +/* architecture configuration +#include +*/ +#include +#define L4_NUMBITS_THREADS 22 + + + + + + + + +/********************************************************************** + * + * thread ids + * + **********************************************************************/ + + +#if defined(CONFIG_VERSION_X0) +typedef union { + struct { + unsigned version : 10; + unsigned thread : 6; + unsigned task : 8; + unsigned chief : 8; + } id; + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {0,1,0,0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {1,0,2,4} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {1,0,4,4} }) +#define L4_INTERRUPT(x) ((l4_threadid_t) { raw : (x + 1) }) + +#elif defined(CONFIG_VERSION_X1) +typedef union { + struct { + unsigned thread :L4_NUMBITS_THREADS; + unsigned version :(32-L4_NUMBITS_THREADS); + } id; + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {thread:1, version:0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {thread:2, version:0} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {thread:3, version:0} }) + +#else +#error unknown kernel interface specification +#endif + + +#define L4_NIL_ID ((l4_threadid_t) { raw : 0 }) +#define L4_INVALID_ID ((l4_threadid_t) { raw : ~0 }) + +#define l4_is_nil_id(id) ((id).raw == L4_NIL_ID.raw) +#define l4_is_invalid_id(id) ((id).raw == L4_INVALID_ID.raw) + +#ifdef __cplusplus +static inline int operator == (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw == t2.raw; +} + +static inline int operator != (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw != t2.raw; +} +#endif /* __cplusplus */ + + + + + + + +/********************************************************************** + * + * flexpages + * + **********************************************************************/ +/********************************************************************** + * + * timeouts + * + **********************************************************************/ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t raw; + l4_timeout_struct_t timeout; +} l4_timeout_t; + +#define L4_IPC_NEVER ((l4_timeout_t) { raw: 0}) +#define L4_IPC_TIMEOUT_NULL ((l4_timeout_t) { timeout: {15, 15, 15, 15, 0, 0}}) +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {timeout: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +/********************************************************************** + * + * ipc message dopes + * + **********************************************************************/ + +typedef union +{ + struct { + dword_t msg_deceited :1; + dword_t fpage_received :1; + dword_t msg_redirected :1; + dword_t src_inside :1; + dword_t error_code :4; + dword_t strings :5; + dword_t dwords :19; + } md; + dword_t raw; +} l4_msgdope_t; + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR(x) ((x).md.error_code) + +/* + * IPC results + +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + */ + + + + +/********************************************************************** + * + * sched params + * + **********************************************************************/ + +/********************************************************************** + * + * system calls + * + **********************************************************************/ +#include + + + + + + + +#endif /* !__L4__L4_H__ */ diff --git a/apps/include/l4/libide.h b/apps/include/l4/libide.h new file mode 100644 index 0000000..079dad0 --- /dev/null +++ b/apps/include/l4/libide.h @@ -0,0 +1,45 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: l4/libide.h + * Description: Interface for the IDE driver. + * + * @LICENSE@ + * + * $Id: libide.h,v 1.2 2001/12/13 08:18:58 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4__LIBIDE_H__ +#define __L4__LIBIDE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define L4_IDE_SECTOR_SIZE 512 + +typedef union l4_idearg_t l4_idearg_t; +union l4_idearg_t { + struct { + unsigned pos :24; + unsigned length :5; + unsigned drive :2; + unsigned write :1; + } args; + + dword_t raw; +}; + +int ide_init(void); +int ide_read(dword_t __drive, dword_t __sec, void *__buf, dword_t __length); +int ide_write(dword_t __drive, dword_t __sec, void *__buf, dword_t __length); + + +#ifdef __cplusplus +} +#endif + +#endif /* !__L4__LIBIDE_H__ */ diff --git a/apps/include/l4/malloc.h b/apps/include/l4/malloc.h new file mode 100644 index 0000000..1015e6b --- /dev/null +++ b/apps/include/l4/malloc.h @@ -0,0 +1,45 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: malloc.h + * Description: Interface for malloc(3) and friends. + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Log: malloc.h,v $ + * Revision 1.1 2000/09/26 10:14:06 skoglund + * Interface defs for malloc(3) and friends. + * + * + ********************************************************************/ +#ifndef __L4__MALLOC_H__ +#define __L4__MALLOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +void *malloc(int __size); +void free(void *__ptr); + + +#ifdef __cplusplus +} +#endif + +#endif /* !__L4__MALLOC_H__ */ diff --git a/apps/include/l4/rmgr/librmgr.h b/apps/include/l4/rmgr/librmgr.h new file mode 100644 index 0000000..72445db --- /dev/null +++ b/apps/include/l4/rmgr/librmgr.h @@ -0,0 +1,40 @@ +#ifndef __L4_I386_RMGR_H +#define __L4_I386_RMGR_H + +#include + +extern int have_rmgr; +extern l4_threadid_t rmgr_id; + +#ifdef __cplusplus +extern "C" { +#endif + +int rmgr_init(void); + +int rmgr_set_small_space(l4_threadid_t dest, int num); +int rmgr_set_prio(l4_threadid_t dest, int num); +int rmgr_get_prio(l4_threadid_t dest, int *num); + +int rmgr_get_task(int num); +int rmgr_delete_task(int num); +int rmgr_get_irq(int num); + +int rmgr_get_task_id(char *module_name, l4_threadid_t *thread_id); + +l4_taskid_t rmgr_task_new(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + +l4_taskid_t rmgr_task_new_with_prio(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, + l4_threadid_t pager, + l4_sched_param_t sched_param); + +int rmgr_free_fpage(l4_fpage_t fp); +int rmgr_free_page(dword_t address); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/include/l4/rmgr/rmgr.h b/apps/include/l4/rmgr/rmgr.h new file mode 100644 index 0000000..ad21688 --- /dev/null +++ b/apps/include/l4/rmgr/rmgr.h @@ -0,0 +1,56 @@ +#ifndef __L4_SERVER_RMGR_H__ +#define __L4_SERVER_RMGR_H__ + +#include + +#define RMGR_LTHREAD_PAGER (0) +#define RMGR_LTHREAD_SUPER (1) + +#define RMGR_RMGR (0) /* PROTOCOL: rmgr meta protocol */ +#define RMGR_RMGR_PING (0xf3) /* ping -- returns ~arg in d2 */ + +#define RMGR_RMGR_MSG(action, arg) L4_PROTO_MSG(RMGR_RMGR, (action), (arg)) + +#define RMGR_MEM (1) /* PROTOCOL: memory operations */ +#define RMGR_MEM_FREE (1) /* free physical page */ +#define RMGR_MEM_FREE_FP (2) /* free an fpage */ + +#define RMGR_MEM_MSG(action) L4_PROTO_MSG(RMGR_MEM, (action), 0) + +#define RMGR_TASK (2) /* PROTOCOL: task operations */ +#define RMGR_TASK_ALLOC (1) /* allocate task number */ +#define RMGR_TASK_GET (2) /* allocate specific task number */ +#define RMGR_TASK_FREE (3) /* free task number */ +#define RMGR_TASK_CREATE (4) /* create a task XXX */ +#define RMGR_TASK_DELETE (5) /* delete a task */ +#define RMGR_TASK_SET_SMALL (6) /* set a task's small address space number */ +#define RMGR_TASK_SET_PRIO (7) /* set a task's priority */ +#define RMGR_TASK_GET_ID (8) /* get task id by module name */ + +#define RMGR_TASK_CREATE_WITH_PRIO (9) /* create a task and set priority XXX */ +#define RMGR_TASK_SET_ID (10) + +#define RMGR_TASK_MSG(action, taskno) \ + L4_PROTO_MSG(RMGR_TASK, (action), (taskno)) + +#define RMGR_IRQ (3) +#define RMGR_IRQ_GET (2) /* allocate an interrupt number */ +#define RMGR_IRQ_FREE (3) /* free an interrupt number */ + +#define RMGR_IRQ_MSG(action, intno) \ + L4_PROTO_MSG(RMGR_IRQ, (action), (intno)) + +#define RMGR_SYNC (4) +#define RMGR_WAIT_EVENT (1) +#define RMGR_SIGNAL_EVENT (2) +#define RMGR_ENTER_CRITICAL_SECTION (3) +#define RMGR_LEAVE_CRITICAL_SECTION (4) + +#define RMGR_SYNC_MSG(action, ident) \ + L4_PROTO_MSG(RMGR_SYNC, (action), (ident)) + +#endif + + + + diff --git a/apps/include/l4/rmgr/server_proto.h b/apps/include/l4/rmgr/server_proto.h new file mode 100644 index 0000000..78f9745 --- /dev/null +++ b/apps/include/l4/rmgr/server_proto.h @@ -0,0 +1,20 @@ +#ifndef __L4_SERVER_PROTO_H__ +#define __L4_SERVER_PROTO_H__ + +#include + +typedef struct { + word_t param; + byte_t action; + byte_t proto; +} l4_proto_struct_t; + +typedef union { + l4_proto_struct_t proto; + dword_t request; +} l4_proto_t; + +#define L4_PROTO_MSG(proto, action, param) \ + (((proto) << 24) | ((action) << 16) | (param)) + +#endif diff --git a/apps/include/l4/sigma0.h b/apps/include/l4/sigma0.h new file mode 100644 index 0000000..4c7c920 --- /dev/null +++ b/apps/include/l4/sigma0.h @@ -0,0 +1,197 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, 2002, University of Karlsruhe + * + * File path: l4/sigma0.h + * Description: Interface functions for new sigma0 protocol. + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Id: sigma0.h,v 1.4 2002/05/07 19:36:50 skoglund Exp $ + * + ********************************************************************/ +#ifndef __L4__SIGMA0_H__ +#define __L4__SIGMA0_H__ + + +#ifdef __cplusplus +#define l4_sigma0_getpage_rcvpos l4_sigma0_getpage +#define l4_sigma0_getany_rcvpos l4_sigma0_getany +#define l4_sigma0_getkerninfo_rcvpos l4_sigma0_getkerninfo +#endif + +/* + * Prototypes. + */ + +L4_INLINE dword_t l4_sigma0_getpage(l4_threadid_t s0, l4_fpage_t fp); +L4_INLINE dword_t l4_sigma0_getpage_rcvpos(l4_threadid_t s0, l4_fpage_t fp, + l4_fpage_t rcv); +L4_INLINE dword_t l4_sigma0_getany(l4_threadid_t s0, dword_t size); +L4_INLINE dword_t l4_sigma0_getany_rcvpos(l4_threadid_t s0, dword_t size, + l4_fpage_t rcv); +L4_INLINE dword_t l4_sigma0_getkerninfo(l4_threadid_t s0); +L4_INLINE dword_t l4_sigma0_getkerninfo_rcvpos(l4_threadid_t s0, + l4_fpage_t rcv); +L4_INLINE int l4_sigma0_freepage(l4_threadid_t s0, l4_fpage_t fp); + + + +/* + * Implementation. + */ + +L4_INLINE dword_t l4_sigma0_getpage(l4_threadid_t s0, l4_fpage_t fp) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, + NULL, + 0x3, 0, fp.raw | 0x3, + (void *) l4_fpage(0, L4_WHOLE_ADDRESS_SPACE, 1, 0).raw, + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + +L4_INLINE dword_t l4_sigma0_getpage_rcvpos(l4_threadid_t s0, l4_fpage_t fp, + l4_fpage_t rcv) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, + NULL, + 0x3, 0, fp.raw | 0x3, + (void *) rcv.raw, + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + + +L4_INLINE dword_t l4_sigma0_getany(l4_threadid_t s0, dword_t size) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, + NULL, + 0x3, 0, l4_fpage(0, size, 0, 0).raw | 0x1, + (void *) l4_fpage(0, L4_WHOLE_ADDRESS_SPACE, 1, 0).raw, + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + +L4_INLINE dword_t l4_sigma0_getany_rcvpos(l4_threadid_t s0, dword_t size, + l4_fpage_t rcv) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, + NULL, + 0x3, 0, l4_fpage(0, size, 0, 0).raw | 0x1, + (void *) rcv.raw, + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + + +L4_INLINE dword_t l4_sigma0_getkerninfo(l4_threadid_t s0) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, NULL, + 0x1, 0, 0, + (void *) l4_fpage(0, L4_WHOLE_ADDRESS_SPACE, 1, 0).raw, + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + +L4_INLINE dword_t l4_sigma0_getkerninfo_rcvpos(l4_threadid_t s0, + l4_fpage_t rcv) +{ + l4_msgdope_t result; + dword_t dummy, addr; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_call(s0, NULL, + 0x1, 0, 0, + (void *) (rcv.raw | 0x2), + &addr, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return 0; + + return addr; +} + +L4_INLINE int l4_sigma0_freepage(l4_threadid_t s0, l4_fpage_t fp) +{ + l4_msgdope_t result; + + if ( s0.raw == 0 ) s0 = L4_SIGMA0_ID; + + l4_ipc_send(s0, + NULL, + 0, 0, (fp.raw & ~0x3) | 0x2, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + return -1; + + return 0; +} + +#endif /* !__L4__SIGMA0_H__ */ diff --git a/apps/include/l4/sys b/apps/include/l4/sys new file mode 120000 index 0000000..205a58a --- /dev/null +++ b/apps/include/l4/sys @@ -0,0 +1 @@ +arch/sys \ No newline at end of file diff --git a/apps/include/l4/x86/compiler.h b/apps/include/l4/x86/compiler.h new file mode 100644 index 0000000..56dc9e3 --- /dev/null +++ b/apps/include/l4/x86/compiler.h @@ -0,0 +1,39 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/compiler.h + * Description: compiler specifications + * + * @LICENSE@ + * + * $Id: compiler.h,v 1.2 2001/12/13 08:36:40 uhlig Exp $ + * + ********************************************************************/ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/apps/include/l4/x86/idt.h b/apps/include/l4/x86/idt.h new file mode 100644 index 0000000..5a97b3e --- /dev/null +++ b/apps/include/l4/x86/idt.h @@ -0,0 +1,35 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/idt.h + * Description: idt entry specification + * (see: IA-32 architecture reference manual) + * + * @LICENSE@ + * + * $Id: idt.h,v 1.2 2001/12/13 08:36:40 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_IDT_H__ +#define __L4_X86_IDT_H__ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + +#endif /* __L4_X86_IDT_H__ */ diff --git a/apps/include/l4/x86/ipc.h b/apps/include/l4/x86/ipc.h new file mode 100755 index 0000000..53dbb30 --- /dev/null +++ b/apps/include/l4/x86/ipc.h @@ -0,0 +1,339 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/ipc.h + * Description: IPC bindings for x86 + * + * @LICENSE@ + * + * $Id: ipc.h,v 1.8 2001/12/13 08:36:40 uhlig Exp $ + * + ********************************************************************/ +#ifndef __L4_X86_IPC_H__ +#define __L4_X86_IPC_H__ + + +#if !defined(CONFIG_L4_SYSENTEREXIT) +#define IPC_SYSENTER "int $0x30 \n\t" +#else +#define OLD_IPC_SYSENTER \ +"push %%ecx \n\t" \ +"push %%ebp \n\t" \ +"push $0x23 /* linear_space_exec */ \n\t" \ +"push $0f /* offset ret_addr */ \n\t" \ +"mov %%esp,%%ecx \n\t" \ +"sysenter /* = db 0x0F,0x34 */ \n\t" \ +"mov %%ebp,%%edx \n\t" \ +"0: \n\t" +#define IPC_SYSENTER \ +"push %%ecx \n\t" \ +"push %%ebp \n\t" \ +"push $0x1b /* linear_space_exec */ \n\t" \ +"push $0f /* offset ret_addr */ \n\t" \ +"mov %%esp,%%ecx \n\t" \ +"sysenter /* = db 0x0F,0x34 */ \n\t" \ +"mov %%ebp,%%edx \n\t" \ +"0: \n\t" +#endif + + /* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Prototypes + */ + +L4_INLINE int +l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int +l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + +/* + * Implementation + */ + +#define SCRATCH_MEMORY 1 +#ifdef __pic__ + +#error no version X bindings with __pic__ enabled + +#else /* __pic__ */ + +L4_INLINE int +l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dw[3] = {snd_dword0, snd_dword1, snd_dword2}; + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl 8(%%edx), %%edi \n\t" + "movl (%%edx), %%edx \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=D" (*rcv_dword2) /* EDI, 3 */ + : + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 5, rcv msg -> ebp */ + "S" (dest), /* ESI, 6, dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dw[0]) /* EDX, 1, */ +#ifdef SCRATCH_MEMORY + : "memory" +#endif /* SCRATCH_MEMORY */ + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dw[3] = {snd_dword0, snd_dword1, snd_dword2}; +#if 1 + asm volatile( + "pushl %%ecx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%edx), %%ebx \n\t" /* get send values */ + "movl 8(%%edx), %%edi \n\t" + "movl (%%edx), %%edx \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ecx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=D" (*rcv_dword2), /* EDI, 3 */ + "=S" (*src) /* ESI, 4 */ + : + "c" (timeout), /* ECX, 5 */ + "3" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 6 -> ebp rcv_msg */ + "4" (dest.raw), /* ESI ,4 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dw) /* EDX, 1 */ + ); +#endif + return L4_IPC_ERROR(*result); +} + + + +// ok + +L4_INLINE int +l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dummy; + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%edx \n\t" + "pushl %%esi \n\t" + "pushl %%edi \n\t" + "movl %8 ,%%ebp \n\t" + IPC_SYSENTER + "popl %%edi \n\t" + "popl %%esi \n\t" + "popl %%edx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=b" (dummy), + "=c" (dummy) + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (snd_dword2), /* EDI, 4 */ + "S" (dest.raw), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH_MEMORY + : "memory" +#endif /* SCRATCH_MEMORY */ + ); + return L4_IPC_ERROR(*result); +}; + + +// ok +L4_INLINE int +l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ecx \n\t" + "movl %%ebx,%%ebp \n\t" + IPC_SYSENTER + "popl %%ecx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (*rcv_dword2), /* EDI,3 */ + "=S" (src->raw) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ + +#ifdef SCRATCH_MEMORY + :"memory" +#endif /* SCRATCH_MEMORY */ + ); + return L4_IPC_ERROR(*result); +} + +// ok + +L4_INLINE int +l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ecx \n\t" + "pushl %%esi \n\t" + "movl %%ebx,%%ebp \n\t" + IPC_SYSENTER + "popl %%esi \n\t" + "popl %%ecx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (*rcv_dword2) /* EDI,3 */ + : + "c" (timeout), /* ECX, 4 */ + "S" (src.raw), /* ESI, 6 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ + : +#ifdef SCRATCH_MEMORY + "memory" +#endif /* SCRATCH_MEMORY */ + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int l4_ipc_sleep(int man, int exp) +{ + l4_msgdope_t result; + l4_timeout_t timeout = ((l4_timeout_t) { timeout: {exp, 0, 0, 0, 0, man}}); + + asm volatile ( + "pushl %%ebp \n" + "pushl %%ecx \n" + "subl %%ebp, %%ebp \n" + "subl %%esi, %%esi \n" + IPC_SYSENTER + "popl %%ecx \n" + "popl %%ebp \n" + : + "=a" (result) + : + "c" (timeout.raw), + "0" (L4_IPC_NIL_DESCRIPTOR) + : + "ebx", "esi", "edi", "edx" + ); + return 0; +} + +#endif /* __pic__ */ + + +#endif /* __L4_X86_IPC_H__ */ + diff --git a/apps/include/l4/x86/kdebug.h b/apps/include/l4/x86/kdebug.h new file mode 100755 index 0000000..5f22033 --- /dev/null +++ b/apps/include/l4/x86/kdebug.h @@ -0,0 +1,132 @@ +/********************************************************************* + * + * Copyright (C) 1999 - 2002, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/kdebug.h + * Description: kernel debugger protocol + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.7 2002/03/13 13:34:58 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_KDEBUG_H__ +#define __L4_X86_KDEBUG_H__ + + +#define enter_kdebug(text...) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text...) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE char kd_inchar(void) +{ + /* be aware that this stops the entire box until a key is pressed */ + char c; + __asm__ __volatile__ ( + "int $3 \n\t" + "cmpb $13, %%al \n\t" + : "=a" (c)); + return c; +} + +#endif /* __L4_X86_KDEBUG_H__ */ diff --git a/apps/include/l4/x86/kernel.h b/apps/include/l4/x86/kernel.h new file mode 100755 index 0000000..3f2c35e --- /dev/null +++ b/apps/include/l4/x86/kernel.h @@ -0,0 +1,84 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: l4/x86/kernel.h + * Description: kernel info page for x86 + * + * @LICENSE@ + * + * $Id: kernel.h,v 1.4 2001/12/13 08:36:40 uhlig Exp $ + * + ********************************************************************/ +#ifndef __L4__X86__KERNEL_H__ +#define __L4__X86__KERNEL_H__ + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; + byte_t reserved[7]; + + /* The following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section + 2.9 of the L4 Reference Manual. */ + dword_t kdebug_init; + dword_t kdebug_exception; + struct { + dword_t low; + dword_t high; + } kdebug_memory; + + dword_t sigma0_esp, sigma0_eip; + struct { + dword_t low; + dword_t high; + } sigma0_memory; + + dword_t sigma1_esp, sigma1_eip; + struct { + dword_t low; + dword_t high; + } sigma1_memory; + + dword_t root_esp, root_eip; + struct { + dword_t low; + dword_t high; + } root_memory; + + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; + + struct { + dword_t low; + dword_t high; + } main_memory; + + struct { + dword_t low; + dword_t high; + } reserved0; + + struct { + dword_t low; + dword_t high; + } reserved1; + + struct { + dword_t low; + dword_t high; + } dedicated[5]; + + volatile dword_t clock; + +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + + +#endif /* !__L4__X86__KERNEL_H__ */ diff --git a/apps/include/l4/x86/l4.h b/apps/include/l4/x86/l4.h new file mode 100644 index 0000000..f41170d --- /dev/null +++ b/apps/include/l4/x86/l4.h @@ -0,0 +1,22 @@ +/********************************************************************* + * + * Copyright (C) 1999-2003, Karlsruhe University + * + * File path: l4/x86/l4.h + * Description: standard include file for l4/x86 + * + * @LICENSE@ + * + * $Id: l4.h,v 1.3 2003/02/19 15:29:52 sgoetz Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_L4_H__ +#define __L4_X86_L4_H__ + +#include "types.h" +#include "kdebug.h" +#include "syscalls.h" +#include "ipc.h" + +#endif /* __L4_X86_L4_H__ */ diff --git a/apps/include/l4/x86/syscalls.h b/apps/include/l4/x86/syscalls.h new file mode 100755 index 0000000..42dd346 --- /dev/null +++ b/apps/include/l4/x86/syscalls.h @@ -0,0 +1,418 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe and Dresden University + * + * filename: syscalls.h + * + */ + +#ifndef __L4_X86_SYSCALLS_H__ +#define __L4_X86_SYSCALLS_H__ + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + +L4_INLINE void +l4_yield (void); + + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__ ( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (fpage), + "=c" (map_mask) + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi" + ); +} + + +/* + * L4 id myself + */ +// ok +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__ + __volatile__ ( + +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.raw) /* ESI, 0 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + +// ok +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->raw), /* ESI, 0 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.raw) /* ESI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +// ok +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( + + "pushl %%ebx \n\t" +#ifdef __pic__ + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x35 \n\t" /* execute system call */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->raw), /* ESI, 3 */ + "=b" (preempter->raw) /* EBX, 4 */ + : + "0" (destination.id.thread), + "1" (esp), + "2" (eip), + "3" (pager->raw), /* ESI */ +#ifdef __pic__ + "D" (preempter->raw) /* EDI */ +#else + "b" (preempter->raw) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "edi" +#endif + ); +} + + +/* + * L4 thread switch + */ + +// ok +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (destination.raw) + : + "S" (destination.raw) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi" + ); +} + +/* + * L4 thread schedule + */ +// ok +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "movl %%ebx, %%edi \n\t" + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((dword_t*)&temp)[0]), /* ECX, 1 */ + "=d" (((dword_t*)&temp)[1]), /* EDX, 2 */ + "=S" (partner->raw), /* ESI, 3 */ +#ifdef __pic__ + "=D" (ext_preempter->raw) /* EDI, 4 */ +#else + "=b" (ext_preempter->raw) +#endif + : +#ifdef __pic__ + "2" (ext_preempter->raw), /* EDX, 2 */ +#else + "b" (ext_preempter->raw), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.raw) /* ESI */ +#ifndef __pic__ + : "edi" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +// ok +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.raw), /* ESI, 0 */ + "=a"(esp), "=b"(esp), "=c"(esp), "=d"(esp) + : + "b" (pager.raw), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.raw) /* ESI */ + : + "edi" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.raw), /* ESI, 0 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination.raw), /* ESI */ + "D" (pager.raw) /* EDI */ + : + "eax", "ecx", "edx", "edi" + ); + return temp_id; +} +#endif /* __pic__ */ + + +L4_INLINE void +l4_yield (void) +{ + l4_thread_switch(L4_NIL_ID); +} + +L4_INLINE dword_t +l4_get_kernelversion(void) +{ + dword_t v; + __asm__ ("hlt" : "=a" (v)); + return v; +} + +#endif + + + + + + + + + + + + + diff --git a/apps/include/l4/x86/types.h b/apps/include/l4/x86/types.h new file mode 100755 index 0000000..cd1e9c4 --- /dev/null +++ b/apps/include/l4/x86/types.h @@ -0,0 +1,119 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/types.h + * Description: type declarations + * + * @LICENSE@ + * + * $Id: types.h,v 1.4 2002/06/07 16:59:25 skoglund Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_TYPES_H__ +#define __L4_X86_TYPES_H__ + +/* + * L4 unique identifiers + */ +typedef l4_threadid_t l4_taskid_t; +typedef long long cpu_time_t; + + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} l4_intrid_struct_t; + +typedef union { + dword_t dw; + l4_intrid_struct_t id; +} l4_intrid_t; + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned uncacheable:1; + unsigned unbufferable:1; + unsigned zero:2; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + dword_t raw; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, 0, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + + +#endif /* __L4_TYPESL4X_H__ */ + + diff --git a/apps/include/l4io.h b/apps/include/l4io.h new file mode 100644 index 0000000..92ca60a --- /dev/null +++ b/apps/include/l4io.h @@ -0,0 +1,21 @@ +#ifndef __L4IO_H__ +#define __L4IO_H__ + +#include "stdarg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int vsnprintf(char *str, int size, const char *fmt, va_list ap); +int printf(const char *fmt, ...); +void putc(int c); +int getc(void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* !__L4IO_H__ */ diff --git a/apps/include/l4ms/l4.h b/apps/include/l4ms/l4.h new file mode 100644 index 0000000..9a358b8 --- /dev/null +++ b/apps/include/l4ms/l4.h @@ -0,0 +1,247 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: l4ms/l4.h + * Description: standard l4 include file + * + * @LICENSE@ + * + * $Id: l4.h,v 1.2 2001/12/13 08:47:07 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4__L4_H__ +#define __L4__L4_H__ + + + + +/********************************************************************** + * + * base types + * + **********************************************************************/ + +/* architecture dependent types ??? +#include +*/ + +typedef unsigned __int64 qword_t; +typedef unsigned __int32 dword_t; +typedef unsigned __int16 word_t; +typedef unsigned __int8 byte_t; + +typedef signed __int64 sqword_t; +typedef signed __int32 sdword_t; +typedef signed __int16 sword_t; +typedef signed __int8 sbyte_t; + +typedef dword_t* ptr_t; + +#ifndef NULL +#define NULL (0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + + + +#if defined(L4_NO_SYSCALL_INLINES) || defined(__GENERATE_L4LIB__) +# define L4_INLINE +#else +# define L4_INLINE extern __inline +#endif + + + + +/********************************************************************** + * + * configuration ??? + * + **********************************************************************/ + + +#define L4_NUMBITS_THREADS 22 + +/********************************************************************** + * + * thread ids + * + **********************************************************************/ + + +#if defined(CONFIG_VERSION_X0) +typedef union { + struct { + unsigned version : 10; + unsigned thread : 6; + unsigned task : 8; + unsigned chief : 8; + } x0id; + struct { + unsigned version : 10; + unsigned thread : 6+8; + unsigned chief : 8; + } id; + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {0,1,0,0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {0,0,2,0} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {0,0,4,0} }) +#define L4_INTERRUPT(x) ((l4_threadid_t) { raw : {x + 1 } }) + +#elif defined(CONFIG_VERSION_X1) +typedef union { + struct { + unsigned thread :L4_NUMBITS_THREADS; + unsigned version :(32-L4_NUMBITS_THREADS); + } id; + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {thread:1, version:0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {thread:2, version:0} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {thread:3, version:0} }) + +#else +#error unknown kernel interface specification +#endif + + +#define L4_NIL_ID ((l4_threadid_t) { raw : 0 }) +#define L4_INVALID_ID ((l4_threadid_t) { raw : ~0 }) + +#define l4_is_nil_id(id) ((id).raw == L4_NIL_ID.raw) +#define l4_is_invalid_id(id) ((id).raw == L4_INVALID_ID.raw) + +#ifdef __cplusplus +static inline int operator == (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw == t2.raw; +} + +static inline int operator != (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw != t2.raw; +} +#endif /* __cplusplus */ + + + + + + + +/********************************************************************** + * + * flexpages + * + **********************************************************************/ +/********************************************************************** + * + * timeouts + * + **********************************************************************/ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t raw; + l4_timeout_struct_t timeout; +} l4_timeout_t; + +#define L4_IPC_NEVER ((l4_timeout_t) { raw: {0}}) +#define L4_IPC_TIMEOUT_NULL ((l4_timeout_t) { timeout: {15, 15, 15, 15, 0, 0}}) + +/********************************************************************** + * + * ipc message dopes + * + **********************************************************************/ + +typedef union +{ + struct { + dword_t msg_deceited :1; + dword_t fpage_received :1; + dword_t msg_redirected :1; + dword_t src_inside :1; + dword_t error_code :4; + dword_t strings :5; + dword_t dwords :19; + } md; + dword_t raw; +} l4_msgdope_t; + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR(x) ((x).md.error_code) + +/* + * IPC results + +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + */ + + + + +/********************************************************************** + * + * sched params + * + **********************************************************************/ + +/********************************************************************** + * + * system calls + * + **********************************************************************/ +#include + + + + + + + +#endif /* !__L4__L4_H__ */ diff --git a/apps/include/l4ms/x86/compiler.h b/apps/include/l4ms/x86/compiler.h new file mode 100644 index 0000000..bd81b9c --- /dev/null +++ b/apps/include/l4ms/x86/compiler.h @@ -0,0 +1,39 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: l4ms/x86/compiler.h + * Description: compiler helpers - not adopted yet + * + * @LICENSE@ + * + * $Id: compiler.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/apps/include/l4ms/x86/idt.h b/apps/include/l4ms/x86/idt.h new file mode 100644 index 0000000..82a5896 --- /dev/null +++ b/apps/include/l4ms/x86/idt.h @@ -0,0 +1,35 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4ms/x86/idt.h + * Description: idt entry specification + * (see: IA-32 architecture reference manual) + * + * @LICENSE@ + * + * $Id: idt.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_IDT_H__ +#define __L4_X86_IDT_H__ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + +#endif /* __L4_X86_IDT_H__ */ diff --git a/apps/include/l4ms/x86/ipc.h b/apps/include/l4ms/x86/ipc.h new file mode 100644 index 0000000..5013ddb --- /dev/null +++ b/apps/include/l4ms/x86/ipc.h @@ -0,0 +1,262 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4ms/x86/ipc.h + * Description: ipc syscalls + * + * @LICENSE@ + * + * $Id: ipc.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_IPC_H__ +#define __L4_X86_IPC_H__ + + /* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Prototypes + */ + +L4_INLINE int +l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int +l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + +/* + * Implementation + */ + + +L4_INLINE int +l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t send_msg; + dword_t rcv_msg; + } tmp = { + ((dword_t)snd_msg) & (~L4_IPC_DECEIT), + ((dword_t)rcv_msg) & (~L4_IPC_OPEN_IPC) + }; + __asm { + lea eax, tmp; + mov ecx, timeout; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edi, snd_dword2; + mov esi, dest; + push ebp; + mov ebp, [eax + 4]; + mov eax, [eax]; + int 0x30; + pop ebp; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t send_msg; + dword_t rcv_msg; + } tmp = { + ((dword_t)snd_msg) & (~L4_IPC_DECEIT), + ((dword_t)rcv_msg) | L4_IPC_OPEN_IPC + }; + __asm { + lea eax, tmp; + mov ecx, timeout; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edi, snd_dword2; + mov esi, dest; + push ebp; + mov ebp, [eax + 4]; + mov eax, [eax]; + int 0x30; + pop ebp; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _snd_msg = ((dword_t)snd_msg) & (~L4_IPC_DECEIT); + __asm { + mov eax, _snd_msg; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edx, snd_dword2; + mov esi, dest; + mov ecx, timeout; + push ebp; + mov ebp, L4_IPC_NIL_DESCRIPTOR; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _rcv_msg = ((int)rcv_msg) | L4_IPC_OPEN_IPC; + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + push ebp; + mov ebp, _rcv_msg; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, src; + mov [ecx], esi; + } + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _rcv_msg = ((int)rcv_msg) & (~L4_IPC_OPEN_IPC); + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + push ebp; + mov ebp, _rcv_msg; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, src; + mov [ecx], esi; + } + return L4_IPC_ERROR(*result); +} + +#if 0 +L4_INLINE int l4_ipc_sleep(int man, int exp) +{ + l4_msgdope_t result; + l4_timeout_t timeout = ((l4_timeout_t.timeout) {exp, 0, 0, 0, 0, man}); + + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + sub esi, esi; /* no send */ + push ebp; + mov ebp, L4_NIL_ID; + int 0x30; + popl ebp; + mov ecx, result; + mov [ecx], eax; + } + return 0; +} +#endif + +#endif /* __L4_X86_IPC_H__ */ + diff --git a/apps/include/l4ms/x86/kdebug.h b/apps/include/l4ms/x86/kdebug.h new file mode 100644 index 0000000..30c3153 --- /dev/null +++ b/apps/include/l4ms/x86/kdebug.h @@ -0,0 +1,120 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: l4ms/x86/kdebug.h + * Description: kdebug interface - not adopted yet + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_KDEBUG_H__ +#define __L4_X86_KDEBUG_H__ + + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_X86_KDEBUG_H__ */ diff --git a/apps/include/l4ms/x86/kernel.h b/apps/include/l4ms/x86/kernel.h new file mode 100644 index 0000000..f4adf7a --- /dev/null +++ b/apps/include/l4ms/x86/kernel.h @@ -0,0 +1,45 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/kernel.h + * Description: kernel info page + * + * @LICENSE@ + * + * $Id: kernel.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; + byte_t reserved[7]; + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/apps/include/l4ms/x86/l4.h b/apps/include/l4ms/x86/l4.h new file mode 100644 index 0000000..e2552c5 --- /dev/null +++ b/apps/include/l4ms/x86/l4.h @@ -0,0 +1,26 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe + * + * filename: l4.h + * + * $Log: l4.h,v $ + * Revision 1.1 2000/03/11 10:29:38 uhlig + * include files for the Microsoft C compiler. + * This allows to compile L4/x86 files with devstudio. + * currently untested on a real box - only by looking at the generated asm. + * + * Revision 1.1 2000/02/15 11:20:40 uhlig + * x86 cbindings + * + * + */ + +#ifndef __L4_X86_L4_H__ +#define __L4_X86_L4_H__ + +#include "types.h" +//#include "kdebug.h" +#include "syscalls.h" +#include "ipc.h" + +#endif __L4_X86_L4_H__ \ No newline at end of file diff --git a/apps/include/l4ms/x86/syscalls.h b/apps/include/l4ms/x86/syscalls.h new file mode 100644 index 0000000..06f8728 --- /dev/null +++ b/apps/include/l4ms/x86/syscalls.h @@ -0,0 +1,219 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * and Dresden University + * + * File path: l4/x86/syscalls.h + * Description: syscalls + * + * @LICENSE@ + * + * $Id: syscalls.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_SYSCALLS_H__ +#define __L4_X86_SYSCALLS_H__ + + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + + +/* + * L4 flex page unmap + */ +L4_INLINE void +l4_fpage_unmap(dword_t fpage, dword_t map_mask) +{ + __asm { + mov eax, fpage; + mov ecx, map_mask; + push ebp; + int 0x32; + pop ebp; + } +} + + +/* + * L4 id myself + */ +L4_INLINE +l4_threadid_t l4_myself(void) +{ + l4_threadid_t temp_id; + __asm { + mov esi, 0; + push ebp; + int 0x31; + pop ebp; + mov temp_id, esi + } + return temp_id; +} + + +/* + * L4 id next chief + */ + +// ok +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int tmp_type; + __asm { + mov esi, destination.raw; + push ebp; + int 0x31; + pop ebp; + mov ebx, next_chief + mov [ebx], esi; + mov tmp_type, eax; + } + return tmp_type; +} + +/* + * L4 lthread_ex_regs + */ +// ok +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t uip, dword_t usp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + int tid = destination.id.thread; + __asm { + mov eax, tid; + mov ecx, usp; + mov edx, uip; + mov esi, pager + mov esi, [esi]; + mov edi, preempter; + mov edi, [edi]; + push ebp; + int 0x35; + pop ebp; + mov ebx, preempter; + mov [ebx], edi; + mov ebx, pager + mov [ebx], esi; + mov ebx, old_eip; + mov [ebx], edx; + mov ebx, old_esp; + mov [ebx], ecx; + mov ebx, old_eflags; + mov [ebx], eax; + } +} + + +/* + * L4 thread switch + */ + +// ok +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm { + mov esi, destination; + push ebp; + int 0x33; + pop ebp; + } +} + + + +/* + * L4 thread schedule + */ +// ok +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + union { + cpu_time_t time; + dword_t t[2]; + } tmp; + + __asm { + mov eax, param; + mov edx, ext_preempter; + mov edx, [edx] + mov esi, dest; + push ebp; + int 0x34; + pop ebp; + mov tmp.t[0], ecx; + mov tmp.t[4], edx; + mov ecx, old_param + mov [ecx], eax; + mov ecx, partner + mov [ecx], esi; + mov ecx, ext_preempter; + mov [ecx], ebx; + } + return tmp.time; +} + + + +/* + * L4 task new + */ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t usp, dword_t uip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + + __asm { + mov ebx, pager; + mov eax, mcp_or_new_chief; + mov ecx, usp; + mov edx, uip; + mov esi, destination; + push ebp; + int 0x36; + pop ebp; + mov temp_id, eax; + } + return temp_id; +} + +#endif + + + + + + + + + + + + + diff --git a/apps/include/l4ms/x86/types.h b/apps/include/l4ms/x86/types.h new file mode 100644 index 0000000..b718ccd --- /dev/null +++ b/apps/include/l4ms/x86/types.h @@ -0,0 +1,116 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: l4ms/x86/types.h + * Description: type declarations + * + * @LICENSE@ + * + * $Id: types.h,v 1.2 2001/12/13 08:47:30 uhlig Exp $ + * + ********************************************************************/ + +#ifndef __L4_X86_TYPES_H__ +#define __L4_X86_TYPES_H__ + +/* + * L4 unique identifiers + */ +typedef l4_threadid_t l4_taskid_t; +typedef qword_t cpu_time_t; + + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} l4_intrid_struct_t; + +typedef union { + dword_t dw; + l4_intrid_struct_t id; +} l4_intrid_t; + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + + +#if 0 +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} +#endif + +#endif /* __L4_TYPESL4X_H__ */ + + diff --git a/apps/include/multiboot.h b/apps/include/multiboot.h new file mode 100644 index 0000000..cad35e6 --- /dev/null +++ b/apps/include/multiboot.h @@ -0,0 +1,176 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: multiboot.h + * Description: Multiboot heeader definitions. + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Log: multiboot.h,v $ + * Revision 1.1 2000/09/21 11:02:27 skoglund + * Moved multiboot definitions away from the l4 specific parts of the include + * tree. + * + * Revision 1.1 2000/09/20 13:39:25 skoglund + * Structures used for accessing the multiboot headers. + * + * + ********************************************************************/ +#ifndef __MULTIBOOT_H__ +#define __MULTIBOOT_H__ + + +typedef struct multiboot_header_t multiboot_header_t; +typedef struct multiboot_info_t multiboot_info_t; +typedef struct multiboot_module_t multiboot_module_t; +typedef struct multiboot_mmap_t multiboot_mmap_t; + + + +struct multiboot_header_t +{ + unsigned long magic; + unsigned long flags; + unsigned long checksum; /* magic + flags + checksum == 0 */ + + /* + * The following fields are only present if MULTIBOOT_EXTENDED_HDR + * flag is set. + */ + unsigned long header_addr; + unsigned long load_addr; + unsigned long load_end_addr; + unsigned long bss_end_addr; + unsigned long entry; +}; + +/* Indicates start of the multiboot header. */ +#define MULTIBOOT_MAGIC 0x1badb002 + + +/* Flag value indicating that all boot modules are 4KB page aligned. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Flag indicating that mem_* fields of multiboot_info_t must be present. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Flag value indicating an extended multiboot header. */ +#define MULTIBOOT_EXTENDED_HDR 0x00010000 + + +/* This value in EAX indicates multiboot compliant startup. */ +#define MULTIBOOT_VALID 0x2badb002 + + + + + +struct multiboot_info_t +{ + unsigned long flags; + + /* Amount of available memory (0 -> mem_lower * 1KB, and + 1MB -> mem_upper * 1KB). [Bit 0] */ + unsigned long mem_lower; + unsigned long mem_upper; + + /* The BIOS disk device that program was loaded from. [Bit 1] */ + struct { + unsigned char drive; + unsigned char part1; + unsigned char part2; + unsigned char part3; + } boot_device; + + /* Null terminated commandline passed to the program. [Bit 2] */ + char *cmdline; + + /* List of boot modules. [Bit 3] */ + unsigned long mods_count; + multiboot_module_t *mods_addr; + + /* Symbol information. [Bit 4 or 5] */ + union + { + /* Location and size of a.out symbol table. [Bit 4] */ + struct + { + unsigned long tabsize; + unsigned long strsize; + unsigned long addr; + unsigned long reserved; + } aout; + + /* Location specification of elf section headers. [Bit 5] */ + struct + { + unsigned long num; + unsigned long size; + unsigned long addr; + unsigned long shndx; + } elf; + + } syms; + + /* Location and size of memory map provided by BIOS. [Bit 6] */ + unsigned long mmap_length; + multiboot_mmap_t *mmap_addr; +}; + +#define MULTIBOOT_MEM (1L << 0) +#define MULTIBOOT_BOOT_DEVICE (1L << 1) +#define MULTIBOOT_CMDLINE (1L << 2) +#define MULTIBOOT_MODS (1L << 3) +#define MULTIBOOT_AOUT_SYMS (1L << 4) +#define MULTIBOOT_ELF_SHDR (1L << 5) +#define MULTIBOOT_MMAP (1L << 6) + + + +struct multiboot_module_t +{ + /* Physical start and end addresses of the module. */ + unsigned long mod_start; + unsigned long mod_end; + + /* ASCII string associated with module (e.g., command line). */ + char *string; + + /* Must be set to `0'. */ + unsigned long reserved; +}; + + + + +struct multiboot_mmap_t +{ + unsigned long size; + unsigned long BaseAddrLow; + unsigned long BaseAddrHigh; + unsigned long LengthLow; + unsigned long LengthHigh; + unsigned long Type; + + /* Optional padding as indicated by `size'. */ +}; + +/* Type value indicating available RAM. */ +#define MULTIBOOT_MMAP_RAM 1 + + +#endif /* !__MULTIBOOT_H__ */ diff --git a/apps/include/stdarg.h b/apps/include/stdarg.h new file mode 100644 index 0000000..5f19264 --- /dev/null +++ b/apps/include/stdarg.h @@ -0,0 +1,44 @@ +#ifndef L4__STDARG_H +#define L4__STDARG_H + +#ifndef va_start + +typedef unsigned long * va_list; + + +/* + * Update ap to point to the parameter that follows lastarg. + */ +#define va_start(ap,larg) ap = (va_list) ((char *) &larg + sizeof(larg)) + + +/* + * The following macro gets the size of ptype and rounds it up to the + * nearest number modulo int (typically 4). This is done because + * arguments passed to functions will not occupy less space on the + * stack than 4 bytes (the size of an int). + */ +#define __va_size_rounded(ptype) \ + ( ((sizeof(ptype) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) + + +/* + * First advance the parameter pointer to the next parameter on stack. + * Then return the value of the parameter that we have poped. + */ +#define va_arg(ap,ptype) \ +({ \ + ap = (va_list) ((char *) (ap) + __va_size_rounded(ptype)); \ + *( (ptype *) (void *) ((char *) (ap) - __va_size_rounded(ptype)) ); \ +}) + + +/* + * va_end should do nothing. + */ +#define va_end(ap) + + +#endif /* !va_start */ + +#endif /* !L4__STDARG_H */ diff --git a/apps/includems/l4/l4.h b/apps/includems/l4/l4.h new file mode 100644 index 0000000..dbf3fb4 --- /dev/null +++ b/apps/includems/l4/l4.h @@ -0,0 +1,289 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe + * + * filename: l4.h + * + * $Log: l4.h,v $ + * Revision 1.1 2000/05/16 14:41:10 uhlig + * include files for x86 (mostly tested) + * with these files it is possible to compile l4 apps with MSDEV-Studio + * simply add includems into the include search path (before you include + * the normal include path) and ms-c will function properly + * + * Revision 1.1 2000/03/11 10:29:38 uhlig + * include files for the Microsoft C compiler. + * This allows to compile L4/x86 files with devstudio. + * currently untested on a real box - only by looking at the generated asm. + * + * Revision 1.6 2000/02/24 21:53:13 ud3 + * updated l4_threadid_t to conform with kernel declaration + * + * Revision 1.5 2000/02/17 13:42:39 skoglund + * Fixed error in the L4_NIL_ID and L4_INVALID_ID definitions. + * + * Revision 1.4 2000/02/14 20:46:17 uhlig + * timeouts added + * + * Revision 1.3 2000/02/14 19:57:37 ud3 + * updated version X.0 sigma0 id to 2 and X.0 root task id to 4 + * + * Revision 1.2 2000/02/08 14:55:41 ud3 + * *** empty log message *** + * + * Revision 1.1 2000/02/07 23:27:17 ud3 + * Yet another try to build a plain userland. + * + * + */ + +#ifndef __L4__L4_H__ +#define __L4__L4_H__ + + + + +/********************************************************************** + * + * base types + * + **********************************************************************/ + +/* architecture dependent types ??? +#include +*/ + +typedef unsigned __int64 qword_t; +typedef unsigned __int32 dword_t; +typedef unsigned __int16 word_t; +typedef unsigned __int8 byte_t; + +typedef signed __int64 sqword_t; +typedef signed __int32 sdword_t; +typedef signed __int16 sword_t; +typedef signed __int8 sbyte_t; + +typedef unsigned __int64 QWORD; +typedef unsigned __int32 DWORD; +typedef unsigned __int16 WORD; +typedef unsigned __int8 BYTE; + +typedef const char * LPCSTR; +typedef char * LPSTR; +typedef void * LPVOID; + + +typedef dword_t* ptr_t; + +#ifndef NULL +#define NULL (0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + + + +#if defined(L4_NO_SYSCALL_INLINES) || defined(__GENERATE_L4LIB__) +# define L4_INLINE +#else +# define L4_INLINE extern __inline +#endif + + + + +/********************************************************************** + * + * configuration ??? + * + **********************************************************************/ + + +#define L4_NUMBITS_THREADS 22 + +/********************************************************************** + * + * thread ids + * + **********************************************************************/ + + +#if defined(CONFIG_VERSION_X0) +union l4_threadid_t { + struct { + unsigned version : 10; + unsigned thread : 6; + unsigned task : 8; + unsigned chief : 8; + } x0id; + struct { + unsigned version : 10; + unsigned thread : 6+8; + unsigned chief : 8; + } id; + dword_t raw; + inline l4_threadid_t(dword_t _raw) { raw = _raw; } + inline l4_threadid_t() {} +}; +typedef union l4_threadid_t l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {0,1,0,0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {0,0,2,0} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {0,0,4,0} }) +#define L4_INTERRUPT(x) ((dword_t)(x + 1)) + +#elif defined(CONFIG_VERSION_X1) +typedef union { + struct { + unsigned thread :L4_NUMBITS_THREADS; + unsigned version :(32-L4_NUMBITS_THREADS); + } id; + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { id : {thread:1, version:0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { id : {thread:2, version:0} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { id : {thread:3, version:0} }) + +#else +#error unknown kernel interface specification +#endif + + +#define L4_NIL_ID ((dword_t) 0) +#define L4_INVALID_ID ((dword_t)~0) + +#define l4_is_nil_id(id) ((id).raw == L4_NIL_ID) +#define l4_is_invalid_id(id) ((id).raw == L4_INVALID_ID) + +#ifdef __cplusplus +static inline int operator == (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw == t2.raw; +} + +static inline int operator != (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw != t2.raw; +} + +#endif /* __cplusplus */ + + + + + + + +/********************************************************************** + * + * flexpages + * + **********************************************************************/ +/********************************************************************** + * + * timeouts + * + **********************************************************************/ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +union l4_timeout_t { + dword_t raw; + l4_timeout_struct_t timeout; + l4_timeout_t() {} + l4_timeout_t(dword_t _raw) { raw = _raw; } +}; +typedef union l4_timeout_t l4_timeout_t; + +#define L4_IPC_NEVER (0U) +#define L4_IPC_TIMEOUT_NULL (0xFFFF0000U) + +/********************************************************************** + * + * ipc message dopes + * + **********************************************************************/ + +typedef union +{ + struct { + dword_t msg_deceited :1; + dword_t fpage_received :1; + dword_t msg_redirected :1; + dword_t src_inside :1; + dword_t error_code :4; + dword_t strings :5; + dword_t dwords :19; + } md; + dword_t raw; +} l4_msgdope_t; + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR(x) ((x).md.error_code) + +/* + * IPC results + +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + */ + + + + +/********************************************************************** + * + * sched params + * + **********************************************************************/ + +/********************************************************************** + * + * system calls + * + **********************************************************************/ +#include + + + + + + + +#endif /* !__L4__L4_H__ */ diff --git a/apps/includems/l4/x86/compiler.h b/apps/includems/l4/x86/compiler.h new file mode 100644 index 0000000..f66c827 --- /dev/null +++ b/apps/includems/l4/x86/compiler.h @@ -0,0 +1,22 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +//#include + +#endif diff --git a/apps/includems/l4/x86/idt.h b/apps/includems/l4/x86/idt.h new file mode 100644 index 0000000..f148f45 --- /dev/null +++ b/apps/includems/l4/x86/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2000/05/16 14:41:10 uhlig Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/apps/includems/l4/x86/ipc.h b/apps/includems/l4/x86/ipc.h new file mode 100644 index 0000000..0e5e221 --- /dev/null +++ b/apps/includems/l4/x86/ipc.h @@ -0,0 +1,204 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe and Dresden University + * + * filename: l4/x86/ipc.h + * + */ +#ifndef __L4_X86_IPC_H__ +#define __L4_X86_IPC_H__ + + /* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + +L4_INLINE int +l4_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t send_msg; + dword_t rcv_msg; + } tmp = { + ((dword_t)snd_msg) & (~L4_IPC_DECEIT), + ((dword_t)rcv_msg) & (~L4_IPC_OPEN_IPC) + }; + __asm { + lea eax, tmp; + mov ecx, timeout; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edi, snd_dword2; + mov esi, dest; + push ebp; + mov ebp, [eax + 4]; + mov eax, [eax]; + int 0x30; + pop ebp; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t send_msg; + dword_t rcv_msg; + } tmp = { + ((dword_t)snd_msg) & (~L4_IPC_DECEIT), + ((dword_t)rcv_msg) | L4_IPC_OPEN_IPC + }; + __asm { + lea eax, tmp; + mov ecx, timeout; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edi, snd_dword2; + mov esi, dest; + push ebp; + mov ebp, [eax + 4]; + mov eax, [eax]; + int 0x30; + pop ebp; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + dword_t snd_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _snd_msg = ((dword_t)snd_msg) & (~L4_IPC_DECEIT); + __asm { + mov eax, _snd_msg; + mov edx, snd_dword0; + mov ebx, snd_dword1; + mov edx, snd_dword2; + mov esi, dest; + mov ecx, timeout; + push ebp; + mov ebp, L4_IPC_NIL_DESCRIPTOR; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + } + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _rcv_msg = ((int)rcv_msg) | L4_IPC_OPEN_IPC; + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + push ebp; + mov ebp, _rcv_msg; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, src; + mov [ecx], esi; + } + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t _rcv_msg = ((int)rcv_msg) & (~L4_IPC_OPEN_IPC); + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + push ebp; + mov ebp, _rcv_msg; + int 0x30; + pop ebp; + mov ecx, result; + mov [ecx], eax; + mov ecx, rcv_dword0; + mov [ecx], edx; + mov ecx, rcv_dword1; + mov [ecx], ebx; + mov ecx, rcv_dword2; + mov [ecx], edi; + mov ecx, src; + mov [ecx], esi; + } + return L4_IPC_ERROR(*result); +} + +#if 0 +L4_INLINE int l4_ipc_sleep(int man, int exp) +{ + l4_msgdope_t result; + l4_timeout_t timeout = ((l4_timeout_t.timeout) {exp, 0, 0, 0, 0, man}); + + __asm { + mov ecx, timeout; + mov eax, L4_IPC_NIL_DESCRIPTOR; + sub esi, esi; /* no send */ + push ebp; + mov ebp, L4_NIL_ID; + int 0x30; + popl ebp; + mov ecx, result; + mov [ecx], eax; + } + return 0; +} +#endif + +#endif /* __L4_X86_IPC_H__ */ + diff --git a/apps/includems/l4/x86/kdebug.h b/apps/includems/l4/x86/kdebug.h new file mode 100644 index 0000000..3ba61f7 --- /dev/null +++ b/apps/includems/l4/x86/kdebug.h @@ -0,0 +1,82 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe and Dresden University + * + * filename: l4/x86/kdebug.h + * + */ + +#ifndef __L4_X86_KDEBUG_H__ +#define __L4_X86_KDEBUG_H__ + +/* + * prototypes + */ +L4_INLINE void outchar(char c) +{ + __asm { + mov al, c; + int 0x3; + cmp al, 0 + } +} + +L4_INLINE void enter_kdebug(char *text) +{ + __asm { + mov eax, text + int 0x3 + cmp al, 2 + int 0x3 + nop + nop + } +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + __asm { + mov eax, text + int 0x3 + cmp al, 2 + } +} + +L4_INLINE void outhex32(int number) +{ + __asm { + mov eax, number + int 0x3 + cmp al, 5 + } +} + +L4_INLINE void outhex20(int number) +{ + __asm { + mov eax, number + int 0x3 + cmp al, 6 + } +} + +L4_INLINE void outhex16(int number) +{ + __asm { + mov eax, number + int 0x3 + cmp al, 7 + } +} + +L4_INLINE void outdec(int number) +{ + __asm { + mov eax, number + int 0x3 + cmp al, 11 + } +} + + +#endif /* __L4_X86_KDEBUG_H__ */ diff --git a/apps/includems/l4/x86/kernel.h b/apps/includems/l4/x86/kernel.h new file mode 100644 index 0000000..09e57a3 --- /dev/null +++ b/apps/includems/l4/x86/kernel.h @@ -0,0 +1,47 @@ +/* + * $Id: kernel.h,v 1.1 2000/05/16 14:41:10 uhlig Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/apps/includems/l4/x86/l4.h b/apps/includems/l4/x86/l4.h new file mode 100644 index 0000000..64db4a0 --- /dev/null +++ b/apps/includems/l4/x86/l4.h @@ -0,0 +1,27 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe + * + * filename: l4.h + * + * $Log: l4.h,v $ + * Revision 1.1 2000/05/16 14:41:10 uhlig + * include files for x86 (mostly tested) + * with these files it is possible to compile l4 apps with MSDEV-Studio + * simply add includems into the include search path (before you include + * the normal include path) and ms-c will function properly + * + * Revision 1.1 2000/02/15 11:20:40 uhlig + * x86 cbindings + * + * + */ + +#ifndef __L4_X86_L4_H__ +#define __L4_X86_L4_H__ + +#include "types.h" +#include "kdebug.h" +#include "syscalls.h" +#include "ipc.h" + +#endif __L4_X86_L4_H__ \ No newline at end of file diff --git a/apps/includems/l4/x86/syscalls.h b/apps/includems/l4/x86/syscalls.h new file mode 100644 index 0000000..719ef09 --- /dev/null +++ b/apps/includems/l4/x86/syscalls.h @@ -0,0 +1,212 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe and Dresden University + * + * filename: l4/x86/syscalls.h + * + */ + +#ifndef __L4_X86_SYSCALLS_H__ +#define __L4_X86_SYSCALLS_H__ + + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + + +/* + * L4 flex page unmap + */ +L4_INLINE void +l4_fpage_unmap(dword_t fpage, dword_t map_mask) +{ + __asm { + mov eax, fpage; + mov ecx, map_mask; + push ebp; + int 0x32; + pop ebp; + } +} + + +/* + * L4 id myself + */ +L4_INLINE +l4_threadid_t l4_myself(void) +{ + l4_threadid_t temp_id; + __asm { + mov esi, 0; + push ebp; + int 0x31; + pop ebp; + mov temp_id, esi + } + return temp_id; +} + + +/* + * L4 id next chief + */ + +// ok +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int tmp_type; + __asm { + mov esi, destination.raw; + push ebp; + int 0x31; + pop ebp; + mov ebx, next_chief + mov [ebx], esi; + mov tmp_type, eax; + } + return tmp_type; +} + +/* + * L4 lthread_ex_regs + */ +// ok +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t uip, dword_t usp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + int tid = destination.id.thread; + __asm { + mov eax, tid; + mov ecx, usp; + mov edx, uip; + mov esi, pager + mov esi, [esi]; + mov edi, preempter; + mov edi, [edi]; + push ebp; + int 0x35; + pop ebp; + mov ebx, preempter; + mov [ebx], edi; + mov ebx, pager + mov [ebx], esi; + mov ebx, old_eip; + mov [ebx], edx; + mov ebx, old_esp; + mov [ebx], ecx; + mov ebx, old_eflags; + mov [ebx], eax; + } +} + + +/* + * L4 thread switch + */ + +// ok +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm { + mov esi, destination; + push ebp; + int 0x33; + pop ebp; + } +} + + + +/* + * L4 thread schedule + */ +// ok +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + union { + cpu_time_t time; + dword_t t[2]; + } tmp; + + __asm { + mov eax, param; + mov edx, ext_preempter; + mov edx, [edx] + mov esi, dest; + push ebp; + int 0x34; + pop ebp; + mov tmp.t[0], ecx; + mov tmp.t[4], edx; + mov ecx, old_param + mov [ecx], eax; + mov ecx, partner + mov [ecx], esi; + mov ecx, ext_preempter; + mov [ecx], ebx; + } + return tmp.time; +} + + + +/* + * L4 task new + */ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t usp, dword_t uip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + + __asm { + mov ebx, pager; + mov eax, mcp_or_new_chief; + mov ecx, usp; + mov edx, uip; + mov esi, destination; + push ebp; + int 0x36; + pop ebp; + mov temp_id, eax; + } + return temp_id; +} + +#endif + + + + + + + + + + + + + diff --git a/apps/includems/l4/x86/types.h b/apps/includems/l4/x86/types.h new file mode 100644 index 0000000..eb16a2d --- /dev/null +++ b/apps/includems/l4/x86/types.h @@ -0,0 +1,110 @@ +/********************************************************************** + * (c) 1999, 2000 by University of Karlsruhe and Dresden University + * + * filename: l4/x86/types.h + * + */ + +#ifndef __L4_X86_TYPES_H__ +#define __L4_X86_TYPES_H__ + +/* + * L4 unique identifiers + */ +typedef l4_threadid_t l4_taskid_t; +typedef qword_t cpu_time_t; + + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} l4_intrid_struct_t; + +typedef union { + dword_t dw; + l4_intrid_struct_t id; +} l4_intrid_t; + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + + +#if 0 +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} +#endif + +#endif /* __L4_TYPESL4X_H__ */ + + diff --git a/apps/lib/Makefile b/apps/lib/Makefile new file mode 100644 index 0000000..1c5ecd4 --- /dev/null +++ b/apps/lib/Makefile @@ -0,0 +1,24 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: lib/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.4 2001/11/30 14:24:22 ud3 Exp $ +## +###################################################################### +include ../Makeconf + +SUBDIRS = l4 io + +all: $(SUBDIRS) + +$(SUBDIRS):: + @cd $@ && $(MAKE) + +clean: + @for d in $(SUBDIRS); do \ + (cd $${d} && $(MAKE) clean) \ + done diff --git a/apps/lib/ide/Makefile b/apps/lib/ide/Makefile new file mode 100644 index 0000000..bdbe815 --- /dev/null +++ b/apps/lib/ide/Makefile @@ -0,0 +1,23 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: lib/ide/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.2 2001/11/30 14:24:22 ud3 Exp $ +## +###################################################################### +include ../../Makeconf $(wildcard .depend) + +LIB = ../libide.a + +SRCS = libide.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) cvrs $@ $^ + diff --git a/apps/lib/ide/libide.c b/apps/lib/ide/libide.c new file mode 100644 index 0000000..9a45ccd --- /dev/null +++ b/apps/lib/ide/libide.c @@ -0,0 +1,121 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/ide/libide.c + * Description: Interface functions for the IDE driver. Note that + * the current version only support writes of up to + * 32KB, and disk sizes of up to 8GB. + * + * @LICENSE@ + * + * $Id: libide.c,v 1.2 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include + +#define PAGE_BITS (12) +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +static l4_threadid_t idedrv_id; + + +/* + * Function ide_init () + * + * Must be invoked prior to ide_read() or ide_write(). + * + */ +int ide_init(void) +{ + // TODO: this should not be hardcoded. + idedrv_id.raw = 0x04050001; + + return 0; +} + + +/* + * Function ide_read (drive, sec, buf, length) + * + * Invokes an IPC to the IDE driver. The buffer is mapped to the + * driver, and the driver unmaps the buffer prior to sending the + * reply IPC. + * + */ +int ide_read(dword_t drive, dword_t sec, void *buf, dword_t length) +{ + l4_msgdope_t result; + dword_t dw0, dw1, dw2; + l4_fpage_t fp; + l4_idearg_t arg; + int r; + + length = (length + L4_IDE_SECTOR_SIZE-1) & ~(L4_IDE_SECTOR_SIZE-1); + + arg.args.pos = sec; + arg.args.length = length / L4_IDE_SECTOR_SIZE; + arg.args.drive = drive; + arg.args.write = 0; + + /* Create fpage that contains the buffer. */ + dw0 = (dword_t) buf & PAGE_MASK; + dw1 = ((dword_t) buf + length + PAGE_SIZE-1) & PAGE_MASK; + for ( r = PAGE_BITS-1, dw2 = (dw1-dw0) >> PAGE_BITS; + dw2 > 0; + dw2 >>= 1, r++ ) {} + fp = l4_fpage(dw0, r, 1, 0); + + r = l4_ipc_call(idedrv_id, + (void *) 2, /* Map fpage */ + (dword_t) buf, (dword_t) fp.fpage, (dword_t) arg.raw, + (void *) 0, + &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); + + return r; +} + + +/* + * Function ide_write (drive, sec, buf, length) + * + * Invokes an IPC to the IDE driver. The buffer is mapped read- + * only to the driver, and the driver unmaps the buffer prior to + * sending the reply IPC. + * + */ +int ide_write(dword_t drive, dword_t sec, void *buf, dword_t length) +{ + l4_msgdope_t result; + dword_t dw0, dw1, dw2; + l4_fpage_t fp; + l4_idearg_t arg; + int r; + + length = (length + L4_IDE_SECTOR_SIZE-1) & ~(L4_IDE_SECTOR_SIZE-1); + + arg.args.pos = sec; + arg.args.length = length / L4_IDE_SECTOR_SIZE; + arg.args.drive = drive; + arg.args.write = 1; + + /* Create fpage that contains the buffer. */ + dw0 = (dword_t) buf & PAGE_MASK; + dw1 = ((dword_t) buf + length + PAGE_SIZE-1) & PAGE_MASK; + for ( r = PAGE_BITS-1, dw2 = (dw1-dw0) >> PAGE_BITS; + dw2 > 0; + dw2 >>= 1, r++ ) {} + fp = l4_fpage(dw0, r, 0, 0); + + r = l4_ipc_call(idedrv_id, + (void *) 2, /* Map fpage */ + (dword_t) buf, (dword_t) fp.fpage, (dword_t) arg.raw, + (void *) 0, + &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); + + return r; +} diff --git a/apps/lib/io/.cvsignore b/apps/lib/io/.cvsignore new file mode 100644 index 0000000..4671378 --- /dev/null +++ b/apps/lib/io/.cvsignore @@ -0,0 +1 @@ +.depend diff --git a/apps/lib/io/Makefile b/apps/lib/io/Makefile new file mode 100644 index 0000000..0f16882 --- /dev/null +++ b/apps/lib/io/Makefile @@ -0,0 +1,47 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: lib/io/Makefile +## Description: +## +## @LICENSE@ +## +## $Id: Makefile,v 1.10 2001/11/30 14:24:22 ud3 Exp $ +## +###################################################################### +include ../../Makeconf $(wildcard .depend) + +LIBS = ../libio.a ../libionative.a + +SRCS = $(ARCH)-$(PLATFORM)-putc.c \ + $(ARCH)-$(PLATFORM)-getc.c \ + get_hex.c print.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include +CPPFLAGS += -DUSE_L4_TYPES + +ifneq ($(MODE),) +all: $(MAKECMDGOALS) + ifeq ($(MODE), ionative) + CPPFLAGS += -DNATIVE + endif + +$(MAKECMDGOALS): $(OBJS) + $(AR) cvrs $@ $^ + +else + +all: $(LIBS) + +../lib%.a: $(SRCS) + $(MAKE) "MODE=$*" $@ +endif + + +.INTERMEDIATE: $(OBJS) + + +clean:: + @rm -f *~ *.i *.ii *.s $(OBJS) $(LIBS) diff --git a/apps/lib/io/arm-brutus-getc.c b/apps/lib/io/arm-brutus-getc.c new file mode 100644 index 0000000..ad8753a --- /dev/null +++ b/apps/lib/io/arm-brutus-getc.c @@ -0,0 +1,32 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-brutus-getc.c + * Description: serial getc() for StrongARM 1100 based Brutus board + * + * @LICENSE@ + * + * $Id: arm-brutus-getc.c,v 1.5 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include "brutus-uart.h" + + +int getc(void) +{ + volatile dword_t tmp; + + /* + * Wait till the receive FIFO has something in it. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_RNE) ); + + /* + * Read a character from the receive FIFO. + */ + return (byte_t) ( L4_UART_UTDR ); +} diff --git a/apps/lib/io/arm-brutus-putc.c b/apps/lib/io/arm-brutus-putc.c new file mode 100644 index 0000000..6e4e5f1 --- /dev/null +++ b/apps/lib/io/arm-brutus-putc.c @@ -0,0 +1,34 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-brutus-putc.c + * Description: serial putc() for StrongARM 1100 based Brutus board + * + * @LICENSE@ + * + * $Id: arm-brutus-putc.c,v 1.7 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include "brutus-uart.h" + +void putc(int c) +{ + volatile dword_t tmp; + + /* + * Wait till the transmit FIFO has a free slot. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_TNF) ); + + /* + * Add the character to the transmit FIFO. + */ + L4_UART_UTDR = (dword_t) c; + + if ( c == '\n' ) + putc('\r'); +} diff --git a/apps/lib/io/arm-dnard-getc.c b/apps/lib/io/arm-dnard-getc.c new file mode 100644 index 0000000..9fc015c --- /dev/null +++ b/apps/lib/io/arm-dnard-getc.c @@ -0,0 +1,23 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-dnard-getc.c + * Description: serial getc() for StrongARM 110 based DNARD board + * + * @LICENSE@ + * + * $Id: arm-dnard-getc.c,v 1.7 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include + +#include "arm-dnard-uart.h" + +int getc(void) +{ + while (!(STATUS(COM1) & 0x01)); + return DATA(COM1); +}; + + diff --git a/apps/lib/io/arm-dnard-putc.c b/apps/lib/io/arm-dnard-putc.c new file mode 100644 index 0000000..0f54034 --- /dev/null +++ b/apps/lib/io/arm-dnard-putc.c @@ -0,0 +1,25 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-dnard-putc.c + * Description: serial putc() for StrongARM 110 based DNARD board + * + * @LICENSE@ + * + * $Id: arm-dnard-putc.c,v 1.9 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include + +#include "arm-dnard-uart.h" + +void putc(int c) +{ + while (!(STATUS(COM1) & 0x60)); + DATA(COM1) = c; + + if (c == '\n') + putc('\r'); +}; + diff --git a/apps/lib/io/arm-dnard-uart.h b/apps/lib/io/arm-dnard-uart.h new file mode 100644 index 0000000..cbc5682 --- /dev/null +++ b/apps/lib/io/arm-dnard-uart.h @@ -0,0 +1,23 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm-dnard-uart.h + * Description: Macros for serial ports on DNARD + * + * @LICENSE@ + * + * $Id: arm-dnard-uart.h,v 1.2 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ + +#if defined(NATIVE) +#define COM1 0x400003f8 +#define COM2 0x400002f8 +#else +#define COM1 0xFFF003f8 +#define COM2 0xFFF002f8 +#endif + +#define DATA(x) (*(volatile byte_t*) ((x))) +#define STATUS(x) (*(volatile byte_t*) ((x)+5)) diff --git a/apps/lib/io/arm-ep7211-getc.c b/apps/lib/io/arm-ep7211-getc.c new file mode 100644 index 0000000..e337d25 --- /dev/null +++ b/apps/lib/io/arm-ep7211-getc.c @@ -0,0 +1,12 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-ep7211-getc.c + * Description: serial getc() for EP7211 board + * + * @LICENSE@ + * + * $Id: arm-ep7211-getc.c,v 1.2 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ diff --git a/apps/lib/io/arm-ep7211-putc.c b/apps/lib/io/arm-ep7211-putc.c new file mode 100644 index 0000000..591194b --- /dev/null +++ b/apps/lib/io/arm-ep7211-putc.c @@ -0,0 +1,23 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-ep7211-putc.c + * Description: serial putc() for EP7211 board + * + * @LICENSE@ + * + * $Id: arm-ep7211-putc.c,v 1.2 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include "arm-ep7211-uart.h" + +void putc(int c) +{ + while (STATUS(HWBASE2) & UTXFF); + DATA(HWBASE2) = c; + + if (c == '\n') + putc('\r'); +} diff --git a/apps/lib/io/arm-ep7211-uart.h b/apps/lib/io/arm-ep7211-uart.h new file mode 100644 index 0000000..88f29d8 --- /dev/null +++ b/apps/lib/io/arm-ep7211-uart.h @@ -0,0 +1,15 @@ + +#if defined(NATIVE) +#define HWBASE 0x80000000 +#else +#define HWBASE 0xFFF00000 +#endif + +#define HWBASE1 (HWBASE + 0x00000000) +#define HWBASE2 (HWBASE + 0x00001000) + +#define DATA(x) (*(volatile byte_t*) (((x)+0x480))) +#define STATUS(x) (*(volatile dword_t*) (((x)+0x140))) + +#define UTXFF (1 << 23) +#define URXFE (1 << 22) diff --git a/apps/lib/io/arm-pleb-getc.c b/apps/lib/io/arm-pleb-getc.c new file mode 100644 index 0000000..11f7d1a --- /dev/null +++ b/apps/lib/io/arm-pleb-getc.c @@ -0,0 +1,32 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-pleb-getc.c + * Description: serial getc() for StrongARM 1100 based PLEB + * + * @LICENSE@ + * + * $Id: arm-pleb-getc.c,v 1.1 2001/12/27 17:07:07 ud3 Exp $ + * + ********************************************************************/ +#include +#include "pleb-uart.h" + + +int getc(void) +{ + volatile dword_t tmp; + + /* + * Wait till the receive FIFO has something in it. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_RNE) ); + + /* + * Read a character from the receive FIFO. + */ + return (byte_t) ( L4_UART_UTDR ); +} diff --git a/apps/lib/io/arm-pleb-putc.c b/apps/lib/io/arm-pleb-putc.c new file mode 100644 index 0000000..9f8c565 --- /dev/null +++ b/apps/lib/io/arm-pleb-putc.c @@ -0,0 +1,34 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/arm-pleb-putc.c + * Description: serial putc() for StrongARM 1100 based PLEB + * + * @LICENSE@ + * + * $Id: arm-pleb-putc.c,v 1.1 2001/12/27 17:07:07 ud3 Exp $ + * + ********************************************************************/ +#include +#include "pleb-uart.h" + +void putc(int c) +{ + volatile dword_t tmp; + + /* + * Wait till the transmit FIFO has a free slot. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_TNF) ); + + /* + * Add the character to the transmit FIFO. + */ + L4_UART_UTDR = (dword_t) c; + + if ( c == '\n' ) + putc('\r'); +} diff --git a/apps/lib/io/brutus-uart.h b/apps/lib/io/brutus-uart.h new file mode 100644 index 0000000..11b5716 --- /dev/null +++ b/apps/lib/io/brutus-uart.h @@ -0,0 +1,101 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: brutus-uart.h + * Description: Macros for serial port handling on Brutus + * + * @LICENSE@ + * + * $Id: brutus-uart.h,v 1.4 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__BRUTUS__UART_H +#define L4__ARM__BRUTUS__UART_H + +/* + * Base address of UART + */ +#ifdef NATIVE +# define L4_UART_BASE 0x80050000 +#else +# define L4_UART_BASE 0xFFF20000 +#endif + +/* Control registers */ +#define L4_UART_UTCR0 *((volatile dword_t *) (L4_UART_BASE + 0x00)) +#define L4_UART_UTCR1 *((volatile dword_t *) (L4_UART_BASE + 0x04)) +#define L4_UART_UTCR2 *((volatile dword_t *) (L4_UART_BASE + 0x08)) +#define L4_UART_UTCR3 *((volatile dword_t *) (L4_UART_BASE + 0x0c)) + +/* Data register */ +#define L4_UART_UTDR *((volatile dword_t *) (L4_UART_BASE + 0x14)) + +/* Status registers */ +#define L4_UART_UTSR0 *((volatile dword_t *) (L4_UART_BASE + 0x1c)) +#define L4_UART_UTSR1 *((volatile dword_t *) (L4_UART_BASE + 0x20)) + + + +/* + * Bits defined in control register 0. + */ +#define L4_UART_PE (1 << 0) /* Parity enable */ +#define L4_UART_OES (1 << 1) /* Odd/even parity select */ +#define L4_UART_SBS (1 << 2) /* Stop bit select */ +#define L4_UART_DSS (1 << 3) /* Data size select */ +#define L4_UART_SCE (1 << 4) /* Sample clock rate enable */ +#define L4_UART_RCE (1 << 5) /* Receive clk. rate edge select */ +#define L4_UART_TCE (1 << 6) /* Transmit clk. rate edge select */ + + +/* + * Bits defined in control register 3. + */ +#define L4_UART_RXE (1 << 0) /* Receiver enable */ +#define L4_UART_TXE (1 << 1) /* Transmitter enable */ +#define L4_UART_BRK (1 << 2) /* Break */ +#define L4_UART_RIO (1 << 3) /* Receive FIFO interrupt enable */ +#define L4_UART_TIE (1 << 4) /* Transmit FIFO interrupt enable */ +#define L4_UART_LBM (1 << 5) /* Loopback mode */ + + +/* + * Baud rate devisror (contained in control registers 1 and 2). + */ +#define L4_UART_GET_BRD() \ + ( (((l4_uint32_t) L4_UART_UTCR1 & 0x0f) << 8) + \ + (l4_uint8_t) L4_UART_UTCR2 ) + +#define L4_UART_SET_BRD(brd) \ + ( *(l4_uint32_t *) L4_UART_UTCR1 = brd & 0xff, \ + *(l4_uint32_t *) L4_UART_UTCR2 = (brd >> 8) & 0x0f ) \ + +#define L4_BRD_TO_BAUDRATE(brd) (3686400 / ((brd+1) << 4)) +#define L4_BAUDRATE_TO_BRD(rate) (3686400 / (rate << 4) - 1) + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TFS (1 << 0) /* Transmit FIFO service req. */ +#define L4_UART_RFS (1 << 1) /* Receive FIFO service req. */ +#define L4_UART_RID (1 << 2) /* Receiver idle */ +#define L4_UART_RBB (1 << 3) /* Receiver begin of break */ +#define L4_UART_REB (1 << 4) /* Receiver end of break */ +#define L4_UART_EIF (1 << 5) /* Error in FIFO */ + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TBY (1 << 0) /* Transmitter busy flag */ +#define L4_UART_RNE (1 << 1) /* Receiver FIFO not empty */ +#define L4_UART_TNF (1 << 2) /* Transmitter FIFO not full */ +#define L4_UART_PRE (1 << 3) /* Parity error */ +#define L4_UART_FRE (1 << 4) /* Framing error */ +#define L4_UART_ROR (1 << 5) /* Receive FIFO overrun */ + + + +#endif /* !L4__ARM__BRUTUS__UART_H */ diff --git a/apps/lib/io/get_hex.c b/apps/lib/io/get_hex.c new file mode 100644 index 0000000..3d149ea --- /dev/null +++ b/apps/lib/io/get_hex.c @@ -0,0 +1,50 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/get_hex.c + * Description: generic get_hex() based on putc() and getc() + * + * @LICENSE@ + * + * $Id: get_hex.c,v 1.7 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ + +#include +#include + +word_t +get_hex(void) +{ + word_t val = 0; + char c, t; + int i = 0; + + while ((t = c = getc()) != '\r') + { + switch(c) + { + case '0' ... '9': + c -= '0'; + break; + + case 'a' ... 'f': + c -= 'a' - 'A'; + case 'A' ... 'F': + c = c - 'A' + 10; + break; + default: + continue; + }; + val <<= 4; + val += c; + + /* let the user see what happened */ + putc(t); + + if (++i == 8) + break; + }; + return val; +} diff --git a/apps/lib/io/mini-print.c b/apps/lib/io/mini-print.c new file mode 100644 index 0000000..a8f864e --- /dev/null +++ b/apps/lib/io/mini-print.c @@ -0,0 +1,104 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/mini-print.c + * Description: tiny version of printf + * + * @LICENSE@ + * + * $Id: mini-print.c,v 1.3 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include + +void print_hex(dword_t val); +void print_string(char* s); +void print_dec(dword_t val); + +static const byte_t hexchars[] = "0123456789ABCDEF"; + +void print_hex(dword_t val) +{ + signed int i; /* becomes negative */ + for (i=28; i >= 0; i -= 4) + putc(hexchars[(val >> i) & 0xF]); +}; + +void print_string(char* s) +{ + while (*s) + putc(*s++); +}; + + +void print_dec(dword_t val) +{ + char buff[16]; + dword_t i = 14; + + buff[15] = '\0'; + do + { + buff[i] = (val % 10) + '0'; + val = val / 10; + i--; + } while(val); + + + print_string(&buff[i+1]); + +}; + + + + +int printf(const char* format, ...) +{ + dword_t ret = 1; + dword_t i = 0; + +#define arg(x) (((ptr_t) &format)[(x)+1]) + + /* sanity check */ + if (format == NULL) + return 0; + + while (*format) + { + switch (*(format)) + { + case '%': + switch (*(++format)) + { + case 'c': + putc(arg(i)); + break; + case 'd': + print_dec(arg(i)); + break; + case 'p': + case 'x': + print_hex((dword_t)arg(i)); + break; + case 's': + print_string((char*) arg(i)); + break; + default: + print_string("?"); + break; + }; + i++; + break; + default: + putc(*format); + if(*format == '\n') + putc('\r'); + break; + }; + format++; + }; + return ret; +}; + diff --git a/apps/lib/io/pleb-uart.h b/apps/lib/io/pleb-uart.h new file mode 100644 index 0000000..cee4665 --- /dev/null +++ b/apps/lib/io/pleb-uart.h @@ -0,0 +1,101 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/pleb-uart.h + * Description: Macros for serial port handling on PLEB + * + * @LICENSE@ + * + * $Id: pleb-uart.h,v 1.1 2001/12/27 17:07:07 ud3 Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__PLEB__UART_H +#define L4__ARM__PLEB__UART_H + +/* + * Base address of UART + */ +#ifdef NATIVE +# define L4_UART_BASE 0x80050000 +#else +# define L4_UART_BASE 0xFFF20000 +#endif + +/* Control registers */ +#define L4_UART_UTCR0 *((volatile dword_t *) (L4_UART_BASE + 0x00)) +#define L4_UART_UTCR1 *((volatile dword_t *) (L4_UART_BASE + 0x04)) +#define L4_UART_UTCR2 *((volatile dword_t *) (L4_UART_BASE + 0x08)) +#define L4_UART_UTCR3 *((volatile dword_t *) (L4_UART_BASE + 0x0c)) + +/* Data register */ +#define L4_UART_UTDR *((volatile dword_t *) (L4_UART_BASE + 0x14)) + +/* Status registers */ +#define L4_UART_UTSR0 *((volatile dword_t *) (L4_UART_BASE + 0x1c)) +#define L4_UART_UTSR1 *((volatile dword_t *) (L4_UART_BASE + 0x20)) + + + +/* + * Bits defined in control register 0. + */ +#define L4_UART_PE (1 << 0) /* Parity enable */ +#define L4_UART_OES (1 << 1) /* Odd/even parity select */ +#define L4_UART_SBS (1 << 2) /* Stop bit select */ +#define L4_UART_DSS (1 << 3) /* Data size select */ +#define L4_UART_SCE (1 << 4) /* Sample clock rate enable */ +#define L4_UART_RCE (1 << 5) /* Receive clk. rate edge select */ +#define L4_UART_TCE (1 << 6) /* Transmit clk. rate edge select */ + + +/* + * Bits defined in control register 3. + */ +#define L4_UART_RXE (1 << 0) /* Receiver enable */ +#define L4_UART_TXE (1 << 1) /* Transmitter enable */ +#define L4_UART_BRK (1 << 2) /* Break */ +#define L4_UART_RIO (1 << 3) /* Receive FIFO interrupt enable */ +#define L4_UART_TIE (1 << 4) /* Transmit FIFO interrupt enable */ +#define L4_UART_LBM (1 << 5) /* Loopback mode */ + + +/* + * Baud rate devisror (contained in control registers 1 and 2). + */ +#define L4_UART_GET_BRD() \ + ( (((l4_uint32_t) L4_UART_UTCR1 & 0x0f) << 8) + \ + (l4_uint8_t) L4_UART_UTCR2 ) + +#define L4_UART_SET_BRD(brd) \ + ( *(l4_uint32_t *) L4_UART_UTCR1 = brd & 0xff, \ + *(l4_uint32_t *) L4_UART_UTCR2 = (brd >> 8) & 0x0f ) \ + +#define L4_BRD_TO_BAUDRATE(brd) (3686400 / ((brd+1) << 4)) +#define L4_BAUDRATE_TO_BRD(rate) (3686400 / (rate << 4) - 1) + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TFS (1 << 0) /* Transmit FIFO service req. */ +#define L4_UART_RFS (1 << 1) /* Receive FIFO service req. */ +#define L4_UART_RID (1 << 2) /* Receiver idle */ +#define L4_UART_RBB (1 << 3) /* Receiver begin of break */ +#define L4_UART_REB (1 << 4) /* Receiver end of break */ +#define L4_UART_EIF (1 << 5) /* Error in FIFO */ + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TBY (1 << 0) /* Transmitter busy flag */ +#define L4_UART_RNE (1 << 1) /* Receiver FIFO not empty */ +#define L4_UART_TNF (1 << 2) /* Transmitter FIFO not full */ +#define L4_UART_PRE (1 << 3) /* Parity error */ +#define L4_UART_FRE (1 << 4) /* Framing error */ +#define L4_UART_ROR (1 << 5) /* Receive FIFO overrun */ + + + +#endif /* !L4__ARM__PLEB__UART_H */ diff --git a/apps/lib/io/print.c b/apps/lib/io/print.c new file mode 100644 index 0000000..ccab220 --- /dev/null +++ b/apps/lib/io/print.c @@ -0,0 +1,543 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/print.c + * Description: fully featured printf + * + * @LICENSE@ + * + * $Id: print.c,v 1.11 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include +#include + +/* + * Function strlen (s) + * + * Return the length of string `s', not including the terminating + * `\0' character. + * + */ +static int strlen(const char *s) +{ + int n; + + for ( n = 0; *s++ != '\0'; n++ ) + ; + + return n; +} + + +/* + * Function print_string (s) + * + * Print string `s' to terminal (or some kind of output). + * + */ +static void print_string(char *s) +{ + while ( *s ) + putc(*s++); +} + + +/* + * Function vsnprintf (str, size, fmt, ap) + * + * Formated output conversion according to format string `fmt' and + * argument list `ap'. The formated string is stored in `out'. If + * the formated string is longer tha `outsize' characters, the + * string is truncated. + * + * The format conversion works as in printf(3), except for the + * conversions; e, E, g, and G which are not supported. + * + */ +int vsnprintf(char *str, int size, const char *fmt, va_list ap) +{ + char convert[64]; + int f_left, f_sign, f_space, f_zero, f_alternate; + int f_long, f_short, f_ldouble; + int width, precision; + int i, c, base, sign, signch, numdigits, numpr = 0, someflag; + unsigned int uval, uval2; + double fval; + char *digits, *string, *p = str; + l4_threadid_t tid; + +#define PUTCH(ch) do { \ + if ( size-- <= 0 ) \ + goto Done; \ + *p++ = (ch); \ + } while (0) + +#define PUTSTR(st) do { \ + char *s = (st); \ + while ( *s != '\0' ) { \ + if ( size-- <= 0 ) \ + goto Done; \ + *p++ = *s++; \ + } \ + } while (0) + +#define PUTDEC(num) do { \ + uval = num; \ + numdigits = 0; \ + do { \ + convert[ numdigits++ ] = digits[ uval % 10 ]; \ + uval /= 10; \ + } while ( uval > 0 ); \ + while ( numdigits > 0 ) \ + PUTCH( convert[--numdigits] ); \ + } while (0) + +#define LEFTPAD(num) do { \ + int cnt = (num); \ + if ( ! f_left && cnt > 0 ) \ + while ( cnt-- > 0 ) \ + PUTCH( f_zero ? '0' : ' ' ); \ + } while (0) + +#define RIGHTPAD(num) do { \ + int cnt = (num); \ + if ( f_left && cnt > 0 ) \ + while ( cnt-- > 0 ) \ + PUTCH( ' ' ); \ + } while (0) + + /* + * Make room for null-termination. + */ + size--; + + /* + * Sanity check on fmt string. + */ + if ( fmt == NULL ) { + PUTSTR( "(null fmt string)" ); + goto Done; + } + + while ( size > 0 ) { + /* + * Copy characters until we encounter '%'. + */ + while ( (c = *fmt++) != '%' ) { + if ( size-- <= 0 || c == '\0' ) + goto Done; + *p++ = c; + } + + f_left = f_sign = f_space = f_zero = f_alternate = 0; + someflag = 1; + + /* + * Parse flags. + */ + while ( someflag ) { + switch ( *fmt ) { + case '-': f_left = 1; fmt++; break; + case '+': f_sign = 1; fmt++; break; + case ' ': f_space = 1; fmt++; break; + case '0': f_zero = 1; fmt++; break; + case '#': f_alternate = 1; fmt++; break; + default: someflag = 0; break; + } + } + + /* + * Parse field width. + */ + if ( (c = *fmt) == '*' ) { + width = va_arg( ap, int ); + fmt++; + } else if ( c >= '0' && c <= '9' ) { + width = 0; + while ( (c = *fmt++) >= '0' && c <= '9' ) { + width *= 10; + width += c - '0'; + } + fmt--; + } else { + width = -1; + } + + /* + * Parse precision. + */ + if ( *fmt == '.' ) { + if ( (c = *++fmt) == '*' ) { + precision = va_arg( ap, int ); + fmt++; + } else if ( c >= '0' && c <= '9' ) { + precision = 0; + while ( (c = *fmt++) >= '0' && c <= '9' ) { + precision *= 10; + precision += c - '0'; + } + fmt--; + } else { + precision = -1; + } + } else { + precision = -1; + } + + f_long = f_short = f_ldouble = 0; + + /* + * Parse length modifier. + */ + switch ( *fmt ) { + case 'h': f_short = 1; fmt++; break; + case 'l': f_long = 1; fmt++; break; + case 'L': f_ldouble = 1; fmt++; break; + } + + sign = 1; + + /* + * Parse format conversion. + */ + switch ( c = *fmt++ ) { + + case 'b': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 2; + digits = "01"; + goto Print_unsigned; + + case 'o': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 8; + digits = "012345678"; + goto Print_unsigned; + + case 'p': + precision = width = 8; + f_alternate = 1; + case 'x': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 16; + digits = "0123456789abcdef"; + goto Print_unsigned; + + case 'X': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 16; + digits = "0123456789ABCDEF"; + goto Print_unsigned; + + case 'd': + case 'i': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 10; + digits = "0123456789"; + goto Print_signed; + + case 'u': + uval = f_long ? va_arg( ap, long ) : va_arg( ap, int ); + base = 10; + digits = "0123456789"; + + Print_unsigned: + sign = 0; + + Print_signed: + signch = 0; + uval2 = uval; + + /* + * Check for sign character. + */ + if ( sign ) { + if ( f_sign && (long) uval >= 0 ) { + signch = '+'; + } else if ( f_space && (long) uval >= 0 ) { + signch = ' '; + } else if ( (long) uval < 0 ) { + signch = '-'; + uval = -( (long) uval ); + } + } + + /* + * Create reversed number string. + */ + numdigits = 0; + do { + convert[ numdigits++ ] = digits[ uval % base ]; + uval /= base; + } while ( uval > 0 ); + + /* + * Calculate the actual size of the printed number. + */ + numpr = numdigits > precision ? numdigits : precision; + if ( signch ) + numpr++; + if ( f_alternate && uval2 != 0 ) { + if ( base == 8 ) + numpr++; + else if ( base == 16 || base == 2 ) + numpr += 2; + } + + /* + * Insert left padding. + */ + if ( ! f_left && width > numpr ) { + if ( f_zero ) { + numpr = width; + } else { + for ( i = width - numpr; i > 0; i-- ) + PUTCH(' '); + } + } + + /* + * Insert sign character. + */ + if ( signch ) { + PUTCH( signch ); + numpr--; + } + + /* + * Insert number prefix. + */ + if ( f_alternate && uval2 != 0 ) { + if ( base == 2 ) { + numpr--; + PUTCH('%'); + } else if ( base == 8 ) { + numpr--; + PUTCH('0'); + } else if ( base == 16 ) { + numpr -= 2; + PUTSTR("0x"); + } + } + + /* + * Insert zero padding. + */ + for ( i = numpr - numdigits; i > 0; i-- ) + PUTCH('0'); + + /* + * Insert number. + */ + while ( numdigits > 0 ) + PUTCH( convert[--numdigits] ); + + RIGHTPAD( width - numpr - (signch ? 1 : 0) ); + break; + + + case 'f': + fval = va_arg( ap, double ); + if ( precision == -1 ) + precision = 6; + + /* + * Check for sign character. + */ + if ( f_sign && fval >= 0.0 ) { + signch = '+'; + } else if ( f_space && fval >= 0.0 ) { + signch = ' '; + } else if ( fval < 0.0 ) { + signch = '-'; + fval = -fval; + } else { + signch = 0; + } + + /* + * Get the integer part of the number. If the floating + * point value is greater than the maximum value of an + * unsigned long, the result is undefined. + */ + uval = (unsigned long) fval; + numdigits = 0; + do { + convert[ numdigits++ ] = '0' + uval % 10; + uval /= 10; + } while ( uval > 0 ); + + /* + * Calculate the actual size of the printed number. + */ + numpr = numdigits + (signch ? 1 : 0); + if ( precision > 0 ) + numpr += 1 + precision; + + LEFTPAD( width - numpr ); + + /* + * Insert sign character. + */ + if ( signch ) + PUTCH( signch ); + + /* + * Insert integer number. + */ + while ( numdigits > 0 ) + PUTCH( convert[--numdigits] ); + + /* + * Insert precision. + */ + if ( precision > 0 ) { + /* + * Truncate number to fractional part only. + */ + while ( fval >= 1.0 ) + fval -= (double) (unsigned long) fval; + + PUTCH('.'); + + /* + * Insert precision digits. + */ + while ( precision-- > 0 ) { + fval *= 10.0; + uval = (unsigned long) fval; + PUTCH( '0' + uval ); + fval -= (double) (unsigned long) fval; + } + } + + RIGHTPAD( width - numpr ); + break; + + case 't': + tid = va_arg( ap, l4_threadid_t ); + if ( l4_is_invalid_id(tid) ) { + PUTSTR("INVALID_ID"); + break; + } else if ( l4_is_nil_id(tid) ) { + PUTSTR("NIL_ID"); + break; + } + digits = "0123456789"; + +#if defined(CONFIG_VERSION_X0) + PUTSTR("task="); + PUTDEC(tid.id.task); + PUTCH(','); +#endif + PUTSTR("thread="); + PUTDEC(tid.id.thread); + PUTSTR(",ver="); + PUTDEC(tid.id.version); + break; + + + case 's': + string = va_arg( ap, char * ); + + /* + * Sanity check. + */ + if ( string == NULL ) { + PUTSTR( "(null)" ); + break; + } + + if ( width > 0 ) { + /* + * Calculate printed size. + */ + numpr = strlen( string ); + if ( precision >= 0 && precision < numpr ) + numpr = precision; + + LEFTPAD( width - numpr ); + } + + /* + * Insert string. + */ + if ( precision >= 0 ) { + while ( precision-- > 0 && (c = *string++) != '\0' ) + PUTCH( c ); + } else { + while ( (c = *string++) != '\0' ) + PUTCH( c ); + } + + RIGHTPAD( width - numpr ); + break; + + case 'c': + PUTCH( va_arg( ap, int ) ); + break; + + case '%': + PUTCH('%'); + break; + + case 'n': + **((int **) ap) = p - str; + break; + + default: + PUTCH('%'); + PUTCH(c); + break; + } + } + Done: + + /* + * Null terminate string. + */ + *p = '\0'; + + /* + * Return size of printed string. + */ + return p - str; +} + + +/* + * Function printf (fmt, ...) + * + * Print formated string to terminal like printf(3). + * + */ +int printf(const char *fmt, ...) +{ + char outbuf[256]; + va_list ap; + int r; + + /* + * Safety check + */ + if ( fmt == NULL ) + return 0; + + /* + * Print into buffer. + */ + va_start(ap, fmt); + r = vsnprintf(outbuf, sizeof(outbuf), fmt, ap); + va_end(ap); + + /* + * Output to terminal. + */ + if ( r > 0 ) + print_string(outbuf); + + return r; +} diff --git a/apps/lib/io/x86-i586-getc.c b/apps/lib/io/x86-i586-getc.c new file mode 100644 index 0000000..8894840 --- /dev/null +++ b/apps/lib/io/x86-i586-getc.c @@ -0,0 +1,68 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/x86-i586-getc.c + * Description: keyboard getc() for x86-based PCs + * + * @LICENSE@ + * + * $Id: x86-i586-getc.c,v 1.3 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ + +#include + +/* No SHIFT key support!!! */ + +#define INLINE static inline + +INLINE unsigned char inb(dword_t port) +{ + unsigned char tmp; + __asm__ __volatile__("inb %1, %0\n" + : "=al"(tmp) + : "dN"(port)); + return tmp; +}; + +#define KBD_STATUS_REG 0x64 +#define KBD_CNTL_REG 0x64 +#define KBD_DATA_REG 0x60 + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ + +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) + +static unsigned char keyb_layout[128] = + "\000\0331234567890-+\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/"; /* 0x60 - 0x6f */ + + +char getc() +{ + static unsigned char last_key = 0; + char c; + while(1) { + unsigned char status = kbd_read_status(); + while (status & KBD_STAT_OBF) { + unsigned char scancode; + scancode = kbd_read_input(); + if (scancode & 0x80) + last_key = 0; + else if (last_key != scancode) + { + //printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[scancode]); + last_key = scancode; + c = keyb_layout[scancode]; + if (c > 0) return c; + } + } + } +} diff --git a/apps/lib/io/x86-i586-putc.c b/apps/lib/io/x86-i586-putc.c new file mode 100644 index 0000000..6a5ab05 --- /dev/null +++ b/apps/lib/io/x86-i586-putc.c @@ -0,0 +1,85 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/io/x86-i586-putc.c + * Description: putc() for x86-based PCs, serial and screen + * + * @LICENSE@ + * + * $Id: x86-i586-putc.c,v 1.6 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_LIBIO_OUTCOM) + +#define COMPORT CONFIG_LIBIO_COMPORT + +static inline byte_t inb(dword_t port) +{ + byte_t tmp; + + if (port < 0x100) /* GCC can optimize this if constant */ + __asm__ __volatile__ ("inb %w1, %0" :"=al"(tmp) :"dN"(port)); + else + __asm__ __volatile__ ("inb %%dx, %0" :"=al"(tmp) :"d"(port)); + + return tmp; +} + +static inline void outb(dword_t port, byte_t val) +{ + if (port < 0x100) /* GCC can optimize this if constant */ + __asm__ __volatile__ ("outb %1, %w0" : :"dN"(port), "al"(val)); + else + __asm__ __volatile__ ("outb %1, %%dx" : :"d"(port), "al"(val)); +} + + +void putc(char c) +{ + while (!(inb(COMPORT+5) & 0x60)); + outb(COMPORT,c); + if (c == '\n') + putc('\r'); +} + +#else /* CONFIG_LIBIO_OUTSCRN */ + +#define DISPLAY ((char*)0xb8000 + 15*160) +#define COLOR 7 +#define NUM_LINES 10 +unsigned __cursor = 0; + +void putc(char c) +{ + int i; + + switch(c) { + case '\r': + break; + case '\n': + __cursor += (160 - (__cursor % 160)); + break; + case '\t': + for ( i = 0; i < (8 - (__cursor % 8)); i++ ) + { + DISPLAY[__cursor++] = ' '; + DISPLAY[__cursor++] = COLOR; + } + break; + default: + DISPLAY[__cursor++] = c; + DISPLAY[__cursor++] = COLOR; + } + if ((__cursor / 160) == NUM_LINES) { + for (i = 40; i < 40*NUM_LINES; i++) + ((dword_t*)DISPLAY)[i - 40] = ((dword_t*)DISPLAY)[i]; + for (i = 0; i < 40; i++) + ((dword_t*)DISPLAY)[40*(NUM_LINES-1) + i] = 0; + __cursor -= 160; + } +} + +#endif diff --git a/apps/lib/l4/.cvsignore b/apps/lib/l4/.cvsignore new file mode 100644 index 0000000..f82cde4 --- /dev/null +++ b/apps/lib/l4/.cvsignore @@ -0,0 +1,2 @@ +.depend + diff --git a/apps/lib/l4/Makefile b/apps/lib/l4/Makefile new file mode 100644 index 0000000..5e035f5 --- /dev/null +++ b/apps/lib/l4/Makefile @@ -0,0 +1,32 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: lib/l4/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.4 2001/11/30 14:24:22 ud3 Exp $ +## +###################################################################### +include ../../Makeconf + +LIB = ../libl4.a + +SRCS = libl4.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) cvrs $@ $^ + +clean: + @rm -f *~ *.i *.ii *.s $(OBJS) $(LIB) + +.depend: $(SRCS) + $(CC) -M $(CPPFLAGS) $(SRCS) > .depend + +include .depend diff --git a/apps/lib/l4/libl4.c b/apps/lib/l4/libl4.c new file mode 100644 index 0000000..c463f68 --- /dev/null +++ b/apps/lib/l4/libl4.c @@ -0,0 +1,14 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/l4/libl4.c + * Description: non-inlined version of L4 system calls + * + * @LICENSE@ + * + * $Id: libl4.c,v 1.2 2001/11/30 14:24:22 ud3 Exp $ + * + ********************************************************************/ +#define __GENERATE_L4LIB__ 1 +#include diff --git a/apps/lib/l4malloc/.cvsignore b/apps/lib/l4malloc/.cvsignore new file mode 100644 index 0000000..4671378 --- /dev/null +++ b/apps/lib/l4malloc/.cvsignore @@ -0,0 +1 @@ +.depend diff --git a/apps/lib/l4malloc/Makefile b/apps/lib/l4malloc/Makefile new file mode 100644 index 0000000..03962eb --- /dev/null +++ b/apps/lib/l4malloc/Makefile @@ -0,0 +1,23 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: lib/l4malloc/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.2 2001/11/30 14:24:23 ud3 Exp $ +## +###################################################################### +include ../../Makeconf $(wildcard .depend) + +LIB = ../libl4malloc.a + +SRCS = libl4malloc.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) cvrs $@ $^ + diff --git a/apps/lib/l4malloc/libl4malloc.c b/apps/lib/l4malloc/libl4malloc.c new file mode 100644 index 0000000..0853784 --- /dev/null +++ b/apps/lib/l4malloc/libl4malloc.c @@ -0,0 +1,330 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: lib/l4malloc/libl4malloc.c + * Description: A simple malloc(3)/free(3) interface using the + * sigma0 protocol for allocating pages. It is assumed + * that the current application's pager will NOT unmap + * any of the allocated memory. Also note that this + * implementation can not release memory back to its + * pager since no such mechanism exists within the + * sigma0 protocol. + * + * @LICENSE@ + * + * $Id: libl4malloc.c,v 1.2 2001/11/30 14:24:23 ud3 Exp $ + * + ********************************************************************/ +#include +#include + + +#define PAGE_BITS (12) +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* Number of extra pages to allocate when allocating memory. */ +#define EXTRA_ALLOC 1 + + +/* + * Structure used to hold list of allocated/free memory areas. + */ + +struct node_t { + char *base; + int size; + struct node_t *next; + struct node_t *prev; +}; + + +/* List of free memory areas. */ +static struct node_t head; +static struct node_t tail; + +/* List of allocated memory areas. */ +static struct node_t a_head; +static struct node_t a_tail; + +static int memory_in_pool; +static dword_t heap_start; +static dword_t heap_end; +static l4_threadid_t my_pager; + + + +static void *malloc_get_pages(int num) +{ + l4_msgdope_t result; + dword_t dummy; + void *ret = (void *) heap_end; + + while ( num-- ) + { + /* Allocate a page using the sigma0 protocol. */ + l4_ipc_call(my_pager, 0, + 0xfffffffc, 0, 0, + (void *) l4_fpage(heap_end, PAGE_BITS, 1, 0).fpage, + &dummy, &dummy, &dummy, + L4_IPC_NEVER, &result); + + if ( result.md.error_code || (! result.md.fpage_received) ) + enter_kdebug("malloc: could not grab more pages"); + + heap_end += PAGE_SIZE; + } + + return ret; +} + + +static void malloc_free_pages(void *ptr, int num) +{ +} + + + +/* + * Function malloc (size) + * + * Allocate size bytes worth of memory. Return a pointer to the + * newly allocated memory, or NULL if memory could not be allocated. + * + */ +void *malloc(int size) +{ + struct node_t *tmp, *tmp2; + int pages_allocated; + static int init = 0; + + /* + * If this is the first call to malloc, we need to initialize the + * list holding memory available for the process, and memory + * allocated by the process. + */ + if ( init == 0 ) + { + extern long _end; + dword_t dummy; + l4_threadid_t preempter; + + head.next = &tail; + tail.prev = &head; + + a_head.next = &a_tail; + a_tail.prev = &a_head; + + heap_start = (((unsigned long) &_end) + PAGE_SIZE-1) & PAGE_MASK; + heap_end = heap_start; + memory_in_pool = 0; + + l4_thread_ex_regs(l4_myself(), ~0, ~0, + &preempter, &my_pager, + &dummy, &dummy, &dummy); + + init = 1; + } + + /* + * Traverse the list of available memory, searching for a block of + * at least size bytes. + */ + tmp = head.next; + while( tmp != &tail ) + { + if ( tmp->size >= size + sizeof(struct node_t) ) + { + /* + * We have to register all allocations since free() only + * give us a pointer to the loaction we should + * deallocate. The allocation is registered in the + * a_list. + */ + tmp2 = (struct node_t *) tmp->base; + tmp2->base = tmp->base + sizeof(struct node_t); + tmp2->size = size; + + /* Update size and base of the node we took memory from. */ + tmp->base += ( size + sizeof(struct node_t) ); + tmp->size -= ( size + sizeof(struct node_t) ); + + /* Insert allocation info into head of aloocation list. */ + tmp2->next = a_head.next; + tmp2->prev = &a_head; + a_head.next->prev = tmp2; + a_head.next = tmp2; + + memory_in_pool -= ( size + sizeof(struct node_t) ); + + /* + * Return the allocated memory. + */ + return (void *) tmp2->base; + } + tmp = tmp->next; + } + + /* + * We have to allocate more memory. + */ + pages_allocated = ((size + sizeof(struct node_t) + PAGE_SIZE-1) + >> PAGE_BITS) + EXTRA_ALLOC; + tmp = malloc_get_pages(pages_allocated); + + if ( tmp == NULL ) + return NULL; + + memory_in_pool += pages_allocated * PAGE_SIZE; + + /* + * Check if the memory region we allocated should be coalesced + * with the memory region of the last node in the memory list (we + * keep entries sorted in ascending order). + */ + if ( tail.prev->base + tail.prev->size == (char *) tmp ) + { + /* Yes. We should coalesce. */ + tail.prev->size += pages_allocated * PAGE_SIZE; + } + else + { + /* No. We can not coalesce. Create a new node. */ + tmp->size = pages_allocated * PAGE_SIZE - sizeof(struct node_t); + tmp->base = (char *) tmp + sizeof(struct node_t); + + /* + * Insert the allocated memory into the list of available + * memory for the process. + */ + tail.prev->next = tmp; + tmp->prev = tail.prev; + tmp->next = &tail; + tail.prev = tmp; + } + + /* + * Do one recursive call. We know that there is sufficient memory + * allocated. + */ + return malloc(size); +} + + +/* + * Function free (ptr) + * + * Free the memory space pointed to by ptr. + * + */ +void free(void *ptr) +{ + struct node_t *tmp, *tmp2; + + + /* + * Search the allocated list for entries describing ptr. + */ + tmp = a_head.next; + while ( tmp != &a_tail ) + { + if ( tmp->base == ptr ) + break; + tmp = tmp->next; + } + + /* If ptr was not a previously allocated memory area, return. */ + if ( tmp == &a_tail ) + return; + + /* Remove the node from the list of allocated entries. */ + tmp->prev->next = tmp->next; + tmp->next->prev = tmp->prev; + + /* + * Try to put the de-allocated memory back into the list of + * available memory. + */ + tmp2 = head.next; + while ( tmp2 != &tail ) + { + /* Check if we can coalesced tmp with tmp2 (before tmp2). */ + if ( tmp2->base == (tmp->base + tmp->size) ) + { + tmp2->base -= ( tmp->size + sizeof(struct node_t) ); + tmp2->size += ( tmp->size + sizeof(struct node_t) ); + return; + } + + /* Check if we can coalesced tmp with tmp2 (after tmp2). */ + if ( (tmp2->base + tmp2->size) == (char *) tmp ) + { + tmp2->size += tmp->size + sizeof(struct node_t); + return; + } + + /* Check if we should insert tmp before tmp2. */ + if ( tmp2->base > tmp->base ) + { + tmp2->prev->next = tmp; + tmp->prev = tmp2->prev; + tmp->next = tmp2; + tmp2->prev = tmp; + return; + } + +#if 0 + /* + * We can not free allocated pages since there is no such + * mechanism in the sigma0 RPC protocol. + */ +#error Unable to free pages using the sigma0 protocol. + + /* + * If there are more than 2 pages worth of memory in the pool, + * and we get across a node that is aligned on a page + * boundary, and is larger than 1 page, we free a part of that + * node. + */ + if ( memory_in_pool > (PAGE_SIZE * 2) && + !((unsigned long) tmp2->base & ~PAGE_MASK) && + tmp2->size > PAGE_SIZE ) + { + /* Make sure that the node still has some memory within it. */ + int delsize = (tmp2->size - 1) >> PAGE_SHIFT; + struct node_t *tmp3; + + memory_in_pool -= (delsize << PAGE_SHIFT); + + /* + * Create the new shrinked node. + */ + tmp3 = (struct node_t *) ((char *) tmp2 + delsize * PAGE_SIZE); + tmp3->base = (char *) tmp3 + sizeof(struct node_t); + tmp3->prev = tmp2->prev; + tmp3->next = tmp2->next; + tmp3->size = tmp2->size - delsize * PAGE_SIZE; + + tmp2->prev->next = tmp3; + tmp2->next->prev = tmp3; + + /* + * Free the pages removed from the pool. + */ + malloc_free_pages(tmp2, delsize); + tmp2 = tmp3; + } +#endif + + tmp2 = tmp2->next; + } + + /* + * Insert memory into end of list, creating a new node. + */ + tmp2->prev->next = tmp; + tmp->prev = tmp2->prev; + tmp->next = tmp2; + tmp2->prev = tmp; +} diff --git a/apps/lib/libio.a b/apps/lib/libio.a new file mode 100644 index 0000000..3f536fb Binary files /dev/null and b/apps/lib/libio.a differ diff --git a/apps/lib/libionative.a b/apps/lib/libionative.a new file mode 100644 index 0000000..61a12d8 Binary files /dev/null and b/apps/lib/libionative.a differ diff --git a/apps/lib/rmgr/Makefile b/apps/lib/rmgr/Makefile new file mode 100644 index 0000000..f0d21e8 --- /dev/null +++ b/apps/lib/rmgr/Makefile @@ -0,0 +1,14 @@ +include ../../Makeconf $(wildcard .depend) + +LIB = ../librmgr.a + +SRCS = librmgr.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES = ../../rmgr/include + +all: $(LIB) + +$(LIB): $(OBJS) + $(AR) cvrs $@ $^ + diff --git a/apps/lib/rmgr/librmgr.c b/apps/lib/rmgr/librmgr.c new file mode 100644 index 0000000..bb6ea09 --- /dev/null +++ b/apps/lib/rmgr/librmgr.c @@ -0,0 +1,312 @@ +/* communication with the L4 RMGR */ + +#include +#include +#include + +#define USE_PRIOS + +/* the interface we implement */ +#include +#include + +l4_threadid_t rmgr_id; +l4_threadid_t rmgr_pager_id; + +extern inline int rmgr_call(dword_t request, dword_t arg, dword_t *out); +extern int rmgr_call_string(char *string, dword_t request, + dword_t arg, dword_t *out1, dword_t *out2); + + +extern inline int rmgr_call_string(char *string, + dword_t request, + dword_t arg, + dword_t *out1, + dword_t *out2) +{ + l4_msgdope_t result; + dword_t r1, r2; + int err; + struct { + l4_fpage_t fp; + l4_msgdope_t size_dope; + l4_msgdope_t send_dope; + dword_t dw2[2]; + l4_strdope_t data; + } msg; + + msg.size_dope = L4_IPC_DOPE(2, 1); + msg.send_dope = L4_IPC_DOPE(2, 1); + msg.data.snd_size = strlen(string) + 1; + msg.data.snd_str = (dword_t)string; + err = l4_i386_ipc_call(rmgr_id, + &msg, request, arg, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + if (err) return err; + + if (out1) *out1 = r1; + if (out2) *out2 = r2; + return 0; +} + + +extern inline int rmgr_call(dword_t request, + dword_t arg, + dword_t *out) +{ + l4_msgdope_t result; + dword_t r1, r2; + int err; + + err = l4_i386_ipc_call(rmgr_id, + L4_IPC_SHORT_MSG, request, arg, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + + if (err) return err; + + if (out) *out = r2; + return r1; +} + +int rmgr_init(void) +{ + l4_msgdope_t result; + l4_threadid_t my_preempter, my_pager; + + my_preempter = my_pager = L4_INVALID_ID; + + /* + * get preempter and pager ids + */ +#if 0 + dword_t dummy; + l4_thread_ex_regs(l4_myself(), (dword_t)-1, (dword_t)-1, + &my_preempter, &my_pager, &dummy, &dummy, &dummy); +#else + l4_nchief(L4_INVALID_ID,&my_pager); +#endif + + rmgr_id = rmgr_pager_id = my_pager; + rmgr_id.id.lthread = RMGR_LTHREAD_SUPER; + rmgr_pager_id.id.lthread = RMGR_LTHREAD_PAGER; + + return (rmgr_call(RMGR_RMGR_MSG(RMGR_RMGR_PING, 0xbeef), 0, &result.msgdope) == 0 + && result.msgdope == ~0xbeef); +} + +int rmgr_set_small_space(l4_threadid_t dest, int num) +{ +#ifdef USE_SMALL_SPACES + l4_sched_param_t schedparam; + l4_threadid_t foo_id; + + return rmgr_call(RMGR_TASK_MSG(RMGR_TASK_SET_SMALL, num), dest.lh.low, 0); + + foo_id = L4_INVALID_ID; + l4_thread_schedule(dest, L4_INVALID_SCHED_PARAM, + &foo_id, &foo_id, &schedparam); + foo_id = L4_INVALID_ID; + schedparam.sp.small = L4_SMALL_SPACE(USE_SMALL_SPACES, num); + l4_thread_schedule(dest, schedparam, &foo_id, &foo_id, &schedparam); +#endif + + return 0; +} + +int rmgr_set_prio(l4_threadid_t dest, int num) +{ +#ifdef USE_PRIOS + l4_sched_param_t schedparam; + l4_threadid_t foo_id; + + static short mcp_below = 0xff; + + /* try to set directly first */ + if (num <= mcp_below) + { + foo_id = L4_INVALID_ID; + l4_thread_schedule(dest, L4_INVALID_SCHED_PARAM, + &foo_id, &foo_id, &schedparam); + if (!l4_is_invalid_sched_param(schedparam)) + { + schedparam.sp.prio = num; + foo_id = L4_INVALID_ID; + l4_thread_schedule(dest, schedparam, &foo_id, &foo_id, &schedparam); + if (!l4_is_invalid_sched_param(schedparam)) + return 0; + + mcp_below = num - 1; + if (mcp_below < 0) mcp_below = 0; + } + else + { + /* even failed to query the schedparam word... */ + mcp_below = 0; + } + } + + /* failed to set directly -- use the RMGR */ + return rmgr_call(RMGR_TASK_MSG(RMGR_TASK_SET_PRIO, num), dest.lh.low, 0); + +#else + return 0; +#endif +} + +/* cheat - query prio without rmgr involvement */ + +int +rmgr_get_prio(l4_threadid_t dest, int *num) +{ +#ifdef USE_PRIOS + l4_sched_param_t p; + l4_threadid_t foo_id = L4_INVALID_ID; + + l4_thread_schedule(dest, L4_INVALID_SCHED_PARAM, + &foo_id, &foo_id, &p); + + return *num = l4_is_invalid_sched_param(p) ? 0 : p.sp.prio; +#else + return 0; +#endif +} + + +int rmgr_get_task(int num) +{ + return rmgr_call(RMGR_TASK_MSG(RMGR_TASK_GET, num), 0, 0); +} + +int rmgr_get_irq(int num) +{ + return rmgr_call(RMGR_IRQ_MSG(RMGR_IRQ_GET, num), 0, 0); +} + +int rmgr_free_fpage(l4_fpage_t fp) +{ + return rmgr_call(RMGR_MEM_MSG(RMGR_MEM_FREE_FP), fp.fpage, 0); +} + +int rmgr_free_page(dword_t address) +{ + return rmgr_call(RMGR_MEM_MSG(RMGR_MEM_FREE),address, 0); +} + + +int rmgr_get_task_id(char *module_name, l4_threadid_t *thread_id) +{ + int err; + dword_t lo, hi; + + err = rmgr_call_string(module_name, RMGR_TASK_MSG(RMGR_TASK_GET_ID, 0), 0, + &lo, &hi); + if (err) { + *thread_id = L4_INVALID_ID; + return err; + } + thread_id->lh.low = lo; + thread_id->lh.high = hi; + return 0; +} + +l4_taskid_t rmgr_task_new(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_msgdope_t result; + dword_t r1, r2; + int err; + + static struct { + dword_t fp; + l4_msgdope_t size_dope; + l4_msgdope_t send_dope; + dword_t d1, d2; + l4_strdope_t data; + } msg = {0, L4_IPC_DOPE(2, 1), L4_IPC_DOPE(2, 1), 0, 0, + {16, 0, 0, 0}}; + + int deleting = l4_is_nil_id(pager); + + msg.data.snd_str = (dword_t) &esp; + + if (deleting) + err = l4_i386_ipc_call(rmgr_id, + L4_IPC_SHORT_MSG, + RMGR_TASK_MSG(RMGR_TASK_DELETE, dest.id.task), + 0, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + else + err = l4_i386_ipc_call(rmgr_id, + &msg, + RMGR_TASK_MSG(RMGR_TASK_CREATE, mcp_or_new_chief), + dest.lh.low, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + + if (err) + return L4_NIL_ID; + + return ((l4_threadid_t){lh: {r1, r2}}); +} + +l4_taskid_t rmgr_task_new_with_prio(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, + l4_threadid_t pager, + l4_sched_param_t sched_param) +{ + l4_msgdope_t result; + dword_t r1, r2; + int err; + + static struct { + dword_t fp; + l4_msgdope_t size_dope; + l4_msgdope_t send_dope; + dword_t d1, d2; + l4_strdope_t data; + } msg = {0, L4_IPC_DOPE(2, 1), L4_IPC_DOPE(2, 1), 0, 0, + {20, 0, 0, 0}}; + + int deleting = l4_is_nil_id(pager); + + msg.data.snd_str = (dword_t) &esp; + + if (deleting) + err = l4_i386_ipc_call(rmgr_id, + L4_IPC_SHORT_MSG, + RMGR_TASK_MSG(RMGR_TASK_DELETE, dest.id.task), + 0, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + else { + err = l4_i386_ipc_call(rmgr_id, + &msg, + RMGR_TASK_MSG(RMGR_TASK_CREATE_WITH_PRIO, + mcp_or_new_chief), + dest.lh.low, + L4_IPC_SHORT_MSG, &r1, &r2, + L4_IPC_NEVER, &result); + } + + if (err) + return L4_NIL_ID; + + return ((l4_threadid_t){lh: {r1, r2}}); +} + +int rmgr_set_task_id(char *module_name, l4_threadid_t thread_id) +{ + int err; + dword_t lo, hi; + + err = rmgr_call_string(module_name, + RMGR_TASK_MSG(RMGR_TASK_SET_ID, + thread_id.id.task), + thread_id.id.chief, + &lo, + &hi); + return err; +} diff --git a/apps/rmgr/COPYING b/apps/rmgr/COPYING new file mode 100644 index 0000000..63b1d84 --- /dev/null +++ b/apps/rmgr/COPYING @@ -0,0 +1,14 @@ +This program 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 +of the License, or (at your option) any later version. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. diff --git a/apps/rmgr/README b/apps/rmgr/README new file mode 100644 index 0000000..36260db --- /dev/null +++ b/apps/rmgr/README @@ -0,0 +1,15 @@ +This directory contains a modified version of RMGR. RMGR is part of +DROPS, a project of University of Dresden's Operating Systems Group. +DROPS is published under GPL as is this version of RMGR. + +Among the modifications mentioned above are: +o adaptation to L4 Version X.0 interface +o handling of L4/Ka kernels +o -maxmem option +o -roottask option + +Actually, RMGR links against OSKit libraries and the OSKit support +library of DROPS. However, we prefer to include these libs in binary +format to avoid having to build OSKit and half of DROPS to get just +RMGR. Sources of these libs are available on the DROPS download site. + diff --git a/apps/rmgr/include/flux/GNUmakefile b/apps/rmgr/include/flux/GNUmakefile new file mode 100644 index 0000000..588c639 --- /dev/null +++ b/apps/rmgr/include/flux/GNUmakefile @@ -0,0 +1,35 @@ +# +# Copyright (c) 1996-1994 The University of Utah and +# the Computer Systems Laboratory at the University of Utah (CSL). +# All rights reserved. +# +# Permission to use, copy, modify and distribute this software is hereby +# granted provided that (1) source code retains these copyright, permission, +# and disclaimer notices, and (2) redistributions including binaries +# reproduce the notices in supporting documentation, and (3) all advertising +# materials mentioning features or use of this software display the following +# acknowledgement: ``This product includes software developed by the +# Computer Systems Laboratory at the University of Utah.'' +# +# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS +# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF +# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +# +# CSL requests users of this software to return to csl-dist@cs.utah.edu any +# improvements that they make and grant CSL redistribution rights. +# + +#### Start of configuration section #### + +OSKIT_SRCDIR = .. +OBJDIR = .. + +prefix = /usr/local +exec_prefix = ${prefix} + +include $(OBJDIR)/Makeconf + +##### End of configuration section ##### + +include $(OSKIT_SRCDIR)/flux/GNUmakerules + diff --git a/apps/rmgr/include/flux/GNUmakefile.in b/apps/rmgr/include/flux/GNUmakefile.in new file mode 100644 index 0000000..735eda6 --- /dev/null +++ b/apps/rmgr/include/flux/GNUmakefile.in @@ -0,0 +1,35 @@ +# +# Copyright (c) 1996-1994 The University of Utah and +# the Computer Systems Laboratory at the University of Utah (CSL). +# All rights reserved. +# +# Permission to use, copy, modify and distribute this software is hereby +# granted provided that (1) source code retains these copyright, permission, +# and disclaimer notices, and (2) redistributions including binaries +# reproduce the notices in supporting documentation, and (3) all advertising +# materials mentioning features or use of this software display the following +# acknowledgement: ``This product includes software developed by the +# Computer Systems Laboratory at the University of Utah.'' +# +# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS +# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF +# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +# +# CSL requests users of this software to return to csl-dist@cs.utah.edu any +# improvements that they make and grant CSL redistribution rights. +# + +#### Start of configuration section #### + +OSKIT_SRCDIR = @top_srcdir@ +OBJDIR = @top_objdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +include $(OBJDIR)/Makeconf + +##### End of configuration section ##### + +include $(OSKIT_SRCDIR)/flux/GNUmakerules + diff --git a/apps/rmgr/include/flux/GNUmakerules b/apps/rmgr/include/flux/GNUmakerules new file mode 100644 index 0000000..593d7cc --- /dev/null +++ b/apps/rmgr/include/flux/GNUmakerules @@ -0,0 +1,53 @@ +# +# Copyright (c) 1996-1994 The University of Utah and +# the Computer Systems Laboratory at the University of Utah (CSL). +# All rights reserved. +# +# Permission to use, copy, modify and distribute this software is hereby +# granted provided that (1) source code retains these copyright, permission, +# and disclaimer notices, and (2) redistributions including binaries +# reproduce the notices in supporting documentation, and (3) all advertising +# materials mentioning features or use of this software display the following +# acknowledgement: ``This product includes software developed by the +# Computer Systems Laboratory at the University of Utah.'' +# +# THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS +# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF +# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +# +# CSL requests users of this software to return to csl-dist@cs.utah.edu any +# improvements that they make and grant CSL redistribution rights. +# + +all: machine + +HFILES := $(patsubst $(OSKIT_SRCDIR)/flux/%,%, \ + $(wildcard $(addprefix $(OSKIT_SRCDIR)/flux/, \ + *.h */*.h */*/*.h))) + +CLEAN_FILES += machine + +include $(OSKIT_SRCDIR)/GNUmakerules + +machine: + ln -s $(OSKIT_SRCDIR)/flux/$(HOST_ARCH) $@ + + +# How to install the header files. + +install: $(addprefix $(INSTALL_INCDIR)/flux/,$(HFILES)) \ + $(INSTALL_INCDIR)/flux/machine $(INSTALL_INCDIR)/flux/config.h + +$(INSTALL_INCDIR)/flux/config.h: $(OBJDIR)/flux/config.h + $(INSTALL) -m 644 $< $@ + +$(INSTALL_INCDIR)/flux/%.h: $(OSKIT_SRCDIR)/flux/%.h + -mkdir -p $(patsubst %/,%,$(dir $@)) + $(INSTALL) -m 644 $< $@ + +$(INSTALL_INCDIR)/flux/machine: + ln -s $(HOST_ARCH) $@ + +distclean: + rm -f config.h + diff --git a/apps/rmgr/include/flux/anno.h b/apps/rmgr/include/flux/anno.h new file mode 100644 index 0000000..ba47a98 --- /dev/null +++ b/apps/rmgr/include/flux/anno.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_ANNO_H_ +#define _FLUX_ANNO_H_ + +#include +#include + +/* + * One global variable of type 'struct anno_table' should be declared + * for each separate set of annotation entries that may exist. + */ +struct anno_table +{ + struct anno_entry *start; + struct anno_entry *end; +}; + +/* + * Declare a variable of this type in the special "anno" section + * to register an annotation. + */ +struct anno_entry +{ + integer_t val1; + integer_t val2; + integer_t val3; + struct anno_table *table; +}; + +/* + * This routine should be called once at program startup; + * it sorts all of the annotation entries appropriately + * and initializes the annotation tables they reside in. + */ +__FLUX_BEGIN_DECLS +void anno_init(void); +__FLUX_END_DECLS + +#include + +#endif /* _FLUX_ANNO_H_ */ diff --git a/apps/rmgr/include/flux/base_critical.h b/apps/rmgr/include/flux/base_critical.h new file mode 100644 index 0000000..583842a --- /dev/null +++ b/apps/rmgr/include/flux/base_critical.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This module implements a simple "global critical region" + * used throughout the OS toolkit to ensure proper serialization + * for various "touchy" but non-performance critical activities + * such as panicking, rebooting, debugging, etc. + * This critical region can safely be entered recursively; + * the only requirement is that "enter"s match exactly with "leave"s. + * + * The implementation of this module is machine-dependent, + * and generally disables interrupts and, on multiprocessors, + * grabs a recursive spin lock. + */ +#ifndef _FLUX_BASE_CRITICAL_H_ +#define _FLUX_BASE_CRITICAL_H_ + +#include + +__FLUX_BEGIN_DECLS +void base_critical_enter(void); +void base_critical_leave(void); +__FLUX_END_DECLS + +#endif /* _FLUX_BASE_CRITICAL_H_ */ diff --git a/apps/rmgr/include/flux/boolean.h b/apps/rmgr/include/flux/boolean.h new file mode 100644 index 0000000..b9b03a2 --- /dev/null +++ b/apps/rmgr/include/flux/boolean.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_BOOLEAN_H_ +#define _FLUX_BOOLEAN_H_ + +/* + * Pick up "boolean_t" type definition. + */ +#include + +/* + * Define the basic boolean constants if not defined already. + */ +#ifndef TRUE +#define TRUE ((boolean_t) 1) +#endif + +#ifndef FALSE +#define FALSE ((boolean_t) 0) +#endif + +#endif /* _FLUX_BOOLEAN_H_ */ diff --git a/apps/rmgr/include/flux/c/a.out.h b/apps/rmgr/include/flux/c/a.out.h new file mode 100644 index 0000000..13e35d3 --- /dev/null +++ b/apps/rmgr/include/flux/c/a.out.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_A_OUT_H_ +#define _FLUX_MC_A_OUT_H_ + +#include + +#endif /* _FLUX_MC_A_OUT_H_ */ diff --git a/apps/rmgr/include/flux/c/alloca.h b/apps/rmgr/include/flux/c/alloca.h new file mode 100644 index 0000000..4439c2f --- /dev/null +++ b/apps/rmgr/include/flux/c/alloca.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_ALLOCA_H_ +#define _FLUX_MC_ALLOCA_H_ + +#define alloca(size) __builtin_alloca(size) + +#endif _FLUX_MC_ALLOCA_H_ diff --git a/apps/rmgr/include/flux/c/assert.h b/apps/rmgr/include/flux/c/assert.h new file mode 100644 index 0000000..9b95542 --- /dev/null +++ b/apps/rmgr/include/flux/c/assert.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifdef NDEBUG + +#define assert(ignore) ((void)0) + +#else + +#include + +__FLUX_BEGIN_DECLS +extern void panic(const char *format, ...) __FLUX_NORETURN; +__FLUX_END_DECLS + +#define assert(expression) \ + ((void)((expression) ? 0 : \ + (panic(__FILE__":%u: failed assertion `"#expression"'", \ + __LINE__), 0))) + +#endif + +#endif /* _ASSERT_H_ */ diff --git a/apps/rmgr/include/flux/c/common.h b/apps/rmgr/include/flux/c/common.h new file mode 100644 index 0000000..4d42e84 --- /dev/null +++ b/apps/rmgr/include/flux/c/common.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Common private header file used by the Flux minimal C library headers. + * This header file does not cause any non-POSIX-reserved symbols to be defined. + * Also, all the symbols it defines are prefixed with __FLUX or __flux + * to increase the likelyhood that it can be used cleanly + * with or by the header files of other C libraries. + */ +#ifndef _FLUX_MC_COMMON_H_ +#define _FLUX_MC_COMMON_H_ + +#ifdef __cplusplus +#define __FLUX_BEGIN_DECLS extern "C" { +#define __FLUX_END_DECLS } +#else +#define __FLUX_BEGIN_DECLS +#define __FLUX_END_DECLS +#endif + +#ifndef __FLUX_INLINE +#define __FLUX_INLINE static __inline +#endif + +#ifdef __GNUC__ +#define __FLUX_NORETURN __attribute((noreturn)) +#else +#define __FLUX_NORETURN +#endif + +typedef unsigned short __flux_dev_t; /* device id */ +typedef unsigned long __flux_gid_t; /* group id */ +typedef unsigned long __flux_ino_t; /* inode number */ +typedef unsigned short __flux_mode_t; /* permissions */ +typedef unsigned short __flux_nlink_t; /* link count */ +typedef unsigned long __flux_uid_t; /* user id */ +typedef signed long __flux_pid_t; /* process id */ + + +/* Also include machine-dependent common definitions. */ +#include + +#endif /* _FLUX_MC_COMMON_H_ */ diff --git a/apps/rmgr/include/flux/c/ctype.h b/apps/rmgr/include/flux/c/ctype.h new file mode 100644 index 0000000..4897044 --- /dev/null +++ b/apps/rmgr/include/flux/c/ctype.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_CTYPE_H_ +#define _FLUX_MC_CTYPE_H_ + +#include + +__FLUX_INLINE int iscntrl(int c) +{ + return ((c) < ' ') || ((c) > 126); +} + +__FLUX_INLINE int isdigit(int c) +{ + return ((c) >= '0') && ((c) <= '9'); +} + +__FLUX_INLINE int isgraph(int c) +{ + return ((c) > ' ') && ((c) <= 126); +} + +__FLUX_INLINE int islower(int c) +{ + return (c >= 'a') && (c <= 'z'); +} + +__FLUX_INLINE int isprint(int c) +{ + return ((c) >= ' ') && ((c) <= 126); +} + +__FLUX_INLINE int isspace(int c) +{ + return ((c) == ' ') || ((c) == '\f') + || ((c) == '\n') || ((c) == '\r') + || ((c) == '\t') || ((c) == '\v'); +} + +__FLUX_INLINE int isupper(int c) +{ + return (c >= 'A') && (c <= 'Z'); +} + +__FLUX_INLINE int isxdigit(int c) +{ + return isdigit(c) || + ((c >= 'A') && (c <= 'F')) || + ((c >= 'a') && (c <= 'f')); +} + +__FLUX_INLINE int isalpha(int c) +{ + return islower(c) || isupper(c); +} + +__FLUX_INLINE int isalnum(int c) +{ + return isalpha(c) || isdigit(c); +} + +__FLUX_INLINE int ispunct(int c) +{ + return isgraph(c) && !isalnum(c); +} + +__FLUX_INLINE int toupper(int c) +{ + return ((c >= 'a') && (c <= 'z')) ? (c - 'a' + 'A') : c; +} + +__FLUX_INLINE int tolower(int c) +{ + return ((c >= 'A') && (c <= 'Z')) ? (c - 'A' + 'a') : c; +} + + +#endif _FLUX_MC_CTYPE_H_ diff --git a/apps/rmgr/include/flux/c/endian.h b/apps/rmgr/include/flux/c/endian.h new file mode 100644 index 0000000..bc105de --- /dev/null +++ b/apps/rmgr/include/flux/c/endian.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Byte swapping stuff. + */ + +#ifndef _FLUX_C_ENDIAN_H_ +#define _FLUX_C_ENDIAN_H_ + +#include + +__FLUX_BEGIN_DECLS +extern unsigned long ntohl(unsigned long); +extern unsigned long htonl(unsigned long); +extern unsigned short ntohs(unsigned short); +extern unsigned short htons(unsigned short); +__FLUX_END_DECLS + +#endif /* _FLUX_C_ENDIAN_H_ */ diff --git a/apps/rmgr/include/flux/c/errno.h b/apps/rmgr/include/flux/c/errno.h new file mode 100644 index 0000000..c858efb --- /dev/null +++ b/apps/rmgr/include/flux/c/errno.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This header file defines a set of POSIX errno values + * that fits consistently into the Mach error code "space" - + * i.e. these error code values can be mixed with kern_return_t's + * and mach_msg_return_t's and such without conflict. + * Higher-level services are not required to use these values + * (or, for that matter, any of the mach/sa header files), + * but if they use other values of their own choosing, + * those values may conflict with values in the Mach error code space, + * making it necessary to keep the different types of error codes separate. + * + * (For example, Lites uses BSD's errno values, + * which conflict with Mach's kern_return_t values, + * and therefore must carefully distinguish between BSD and Mach error codes + * and never return one type when the other is expected, etc. - + * we've found this to be a frequent source of bugs.) + * + * One (probably the main) disadvantage of using these error codes + * is that, since they don't start from around 0 like typical Unix errno values, + * it's impossible to provide a conventional Unix-style sys_errlist table for them. + * However, they are compatible with the POSIX-blessed strerror and perror routines. + */ +#ifndef _FLUX_MC_ERRNO_H_ +#define _FLUX_MC_ERRNO_H_ + +#ifndef errno +extern int errno; /* global error number */ +#endif + +/* ISO/ANSI C-1990 errors */ +#define EDOM 0xc001 /* Numerical argument out of domain */ +#define ERANGE 0xc002 /* Result too large */ + +/* POSIX-1990 errors */ +#define E2BIG 0xc003 /* Argument list too long */ +#define EACCES 0xc004 /* Permission denied */ +#define EAGAIN 0xc005 /* Resource temporarily unavailable */ +#define EBADF 0xc006 /* Bad file descriptor */ +#define EBUSY 0xc007 /* Device busy */ +#define ECHILD 0xc008 /* No child processes */ +#define EDEADLK 0xc009 /* Resource deadlock avoided */ +#define EEXIST 0xc00a /* File exists */ +#define EFAULT 0xc00b /* Bad address */ +#define EFBIG 0xc00c /* File too large */ +#define EINTR 0xc00d /* Interrupted system call */ +#define EINVAL 0xc00e /* Invalid argument */ +#define EIO 0xc00f /* Input/output error */ +#define EISDIR 0xc010 /* Is a directory */ +#define EMFILE 0xc011 /* Too many open files */ +#define EMLINK 0xc012 /* Too many links */ +#define ENAMETOOLONG 0xc013 /* File name too long */ +#define ENFILE 0xc014 /* Too many open files in system */ +#define ENODEV 0xc015 /* Operation not supported by device */ +#define ENOENT 0xc016 /* No such file or directory */ +#define ENOEXEC 0xc017 /* Exec format error */ +#define ENOLCK 0xc018 /* No locks available */ +#define ENOMEM 0xc019 /* Cannot allocate memory */ +#define ENOSPC 0xc01a /* No space left on device */ +#define ENOSYS 0xc01b /* Function not implemented */ +#define ENOTDIR 0xc01c /* Not a directory */ +#define ENOTEMPTY 0xc01d /* Directory not empty */ +#define ENOTTY 0xc01e /* Inappropriate ioctl for device */ +#define ENXIO 0xc01f /* Device not configured */ +#define EPERM 0xc020 /* Operation not permitted */ +#define EPIPE 0xc021 /* Broken pipe */ +#define EROFS 0xc022 /* Read-only file system */ +#define ESPIPE 0xc023 /* Illegal seek */ +#define ESRCH 0xc024 /* No such process */ +#define EXDEV 0xc025 /* Cross-device link */ + +/* POSIX-1993 errors */ +#define EBADMSG 0xc026 +#define ECANCELED 0xc027 +#define EINPROGRESS 0xc028 +#define EMSGSIZE 0xc029 +#define ENOTSUP 0xc02a + +#endif /* _FLUX_MC_ERRNO_H_ */ diff --git a/apps/rmgr/include/flux/c/fcntl.h b/apps/rmgr/include/flux/c/fcntl.h new file mode 100644 index 0000000..98b529e --- /dev/null +++ b/apps/rmgr/include/flux/c/fcntl.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_FCNTL_H_ +#define _FLUX_MC_FCNTL_H_ + +#include + +/* + * These values are the same as those used in BSD. + * (Linux and other Unixoids use different values.) + */ +#define O_ACCMODE 0x0003 +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 + +#define O_NONBLOCK 0x0004 +#define O_APPEND 0x0008 +#define O_CREAT 0x0200 +#define O_TRUNC 0x0400 +#define O_EXCL 0x0800 + +/* + * Constants used for fcntl(2) + */ + +/* command values */ +#define F_DUPFD 0 /* duplicate file descriptor */ +#define F_GETFD 1 /* get file descriptor flags */ +#define F_SETFD 2 /* set file descriptor flags */ +#define F_GETFL 3 /* get file status flags */ +#define F_SETFL 4 /* set file status flags */ +#ifndef _POSIX_SOURCE +#define F_GETOWN 5 /* get SIGIO/SIGURG proc/pgrp */ +#define F_SETOWN 6 /* set SIGIO/SIGURG proc/pgrp */ +#endif +#define F_GETLK 7 /* get record locking information */ +#define F_SETLK 8 /* set record locking information */ +#define F_SETLKW 9 /* F_SETLK; wait if blocked */ + +/* file descriptor flags (F_GETFD, F_SETFD) */ +#define FD_CLOEXEC 1 /* close-on-exec flag */ + + +__FLUX_BEGIN_DECLS + +int creat(const char *__name, __flux_mode_t __mode); +int open(const char *__name, int __mode, ...); + +__FLUX_END_DECLS + +#endif /* _FLUX_MC_FCNTL_H_ */ diff --git a/apps/rmgr/include/flux/c/limits.h b/apps/rmgr/include/flux/c/limits.h new file mode 100644 index 0000000..8784903 --- /dev/null +++ b/apps/rmgr/include/flux/c/limits.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_LIMITS_H_ +#define _FLUX_MC_LIMITS_H_ + +/* This file is valid for typical 32-bit machines; + it should be overridden on 64-bit machines. */ + +#define INT_MIN ((signed int)0x80000000) +#define INT_MAX ((signed int)0x7fffffff) + +#define UINT_MIN ((unsigned int)0x00000000) +#define UINT_MAX ((unsigned int)0xffffffff) + +#endif _FLUX_MC_LIMITS_H_ diff --git a/apps/rmgr/include/flux/c/malloc.h b/apps/rmgr/include/flux/c/malloc.h new file mode 100644 index 0000000..c0cdc2c --- /dev/null +++ b/apps/rmgr/include/flux/c/malloc.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_MALLOC_H_ +#define _FLUX_MC_MALLOC_H_ + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +/* The malloc package in the base C library + is implemented on top of the List Memory Manager, + and the underlying memory pool can be manipulated + directly with the LMM primitives using this lmm structure. */ +extern struct lmm malloc_lmm; + +__FLUX_BEGIN_DECLS + +/* + * Don't macro expand protos please. + */ +#ifndef MALLOC_IS_MACRO + +void *malloc(size_t size); +void *mustmalloc(size_t size); +void *memalign(size_t alignment, size_t size); +void *calloc(size_t nelt, size_t eltsize); +void *mustcalloc(size_t nelt, size_t eltsize); +void *realloc(void *buf, size_t new_size); +void free(void *buf); + +/* Alternate version of the standard malloc functions that expect the + caller to keep track of the size of allocated chunks. These + versions are _much_ more memory-efficient when allocating many + chunks naturally aligned to their (natural) size (e.g. allocating + naturally-aligned pages or superpages), because normal memalign + requires a prefix between each chunk which will create horrendous + fragmentation and memory loss. Chunks allocated with these + functions must be freed with sfree() rather than the ordinary + free(). */ +void *smalloc(size_t size); +void *smemalign(size_t alignment, size_t size); +void *scalloc(size_t size); +void *srealloc(void *buf, size_t old_size, size_t new_size); +void sfree(void *buf, size_t size); + +#endif /* MALLOC_IS_MACRO */ + +/* malloc() and realloc() call this routine when they're about to fail; + it should try to scare up more memory and add it to the malloc_lmm. + Returns nonzero if it succeeds in finding more memory. */ +int morecore(size_t size); + +/* in a multithreaded client os, these functions should be overridden + to protect accesses to the malloc_lmm. */ +void mem_lock(void); +void mem_unlock(void); + +__FLUX_END_DECLS + +#endif _FLUX_MC_MALLOC_H_ diff --git a/apps/rmgr/include/flux/c/memory.h b/apps/rmgr/include/flux/c/memory.h new file mode 100644 index 0000000..dc6b6c7 --- /dev/null +++ b/apps/rmgr/include/flux/c/memory.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _MACH_MEMORY_H_ +#define _MACH_MEMORY_H_ + +#include + +#endif _MACH_MEMORY_H_ diff --git a/apps/rmgr/include/flux/c/setjmp.h b/apps/rmgr/include/flux/c/setjmp.h new file mode 100644 index 0000000..ed769de --- /dev/null +++ b/apps/rmgr/include/flux/c/setjmp.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _SETJMP_H_ +#define _SETJMP_H_ + +#include +#include + +__FLUX_BEGIN_DECLS +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val); +__FLUX_END_DECLS + +#endif /* _SETJMP_H_ */ diff --git a/apps/rmgr/include/flux/c/signal.h b/apps/rmgr/include/flux/c/signal.h new file mode 100644 index 0000000..2cf090b --- /dev/null +++ b/apps/rmgr/include/flux/c/signal.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1982, 1986, 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)signal.h 8.2 (Berkeley) 1/21/94 + * signal.h,v 1.2 1994/08/02 07:53:32 davidg Exp + */ + +#ifndef _FLUX_MC_SIGNAL_H_ +#define _FLUX_MC_SIGNAL_H_ + +#include + +#define NSIG 32 /* counting 0; could be 33 (mask is 1-32) */ + +/* + * These signal numbers are the same as the corresponding ones in BSD, + * except (mostly) only the POSIX signals are included here. + */ +#define SIGHUP 1 /* hangup */ +#define SIGINT 2 /* interrupt */ +#define SIGQUIT 3 /* quit */ +#define SIGILL 4 /* illegal instruction (not reset when caught) */ +#define SIGTRAP 5 /* trace trap (not reset when caught) */ +#define SIGABRT 6 /* abort() */ +#define SIGFPE 8 /* floating point exception */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ +#define SIGBUS 10 /* bus error */ +#define SIGSEGV 11 /* segmentation violation */ +#define SIGPIPE 13 /* write on a pipe with no one to read it */ +#define SIGALRM 14 /* alarm clock */ +#define SIGTERM 15 /* software termination signal from kill */ +#define SIGSTOP 17 /* sendable stop signal not from tty */ +#define SIGTSTP 18 /* stop signal from tty */ +#define SIGCONT 19 /* continue a stopped process */ +#define SIGCHLD 20 /* to parent on child stop or exit */ +#define SIGTTIN 21 /* to readers pgrp upon background tty read */ +#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ +#define SIGUSR1 30 /* user defined signal 1 */ +#define SIGUSR2 31 /* user defined signal 2 */ + +#if defined(_ANSI_SOURCE) || defined(__cplusplus) +/* + * Language spec sez we must list exactly one parameter, even though we + * actually supply three. Ugh! + */ +#define SIG_DFL (void (*)(int))0 +#define SIG_IGN (void (*)(int))1 +#define SIG_ERR (void (*)(int))-1 +#else +#define SIG_DFL (void (*)())0 +#define SIG_IGN (void (*)())1 +#define SIG_ERR (void (*)())-1 +#endif + +#ifndef _ANSI_SOURCE + +typedef unsigned int sigset_t; + +/* + * POSIX 1003.1b: Generic value to pass back to an application. + */ +union sigval +{ + int sival_int; + void *sival_ptr; +}; + +/* + * This structure is passed to signal handlers + * that use the new SA_SIGINFO calling convention (see below). + */ +typedef struct +{ + int si_signo; + int si_code; + union sigval si_value; +} siginfo_t; + +/* Values for si_code, indicating the source of the signal */ +#define SI_USER 0 /* sent by kill(), raise(), or abort() */ +#define SI_QUEUE 1 /* sent by sigqueue() */ +#define SI_TIMER 2 /* generated by an expired timer */ +#define SI_ASYNCIO 3 /* generated by completion of an async i/o */ +#define SI_MESGQ 4 /* generated by the arrival of a message */ +#define SI_IRQ 5 /* hardware int dispatched to application */ +#define SI_EXCEP 6 /* processor or kernel-generated exception */ + +/* + * Signal vector "template" used in sigaction call. + */ +struct sigaction { + union { /* signal handler */ + void (*sa_u_handler)(); + void (*sa_u_sigaction)(int, siginfo_t *, void *); + } sa_u; + sigset_t sa_mask; /* signal mask to apply */ + int sa_flags; /* see signal options below */ +}; +#define sa_handler sa_u.sa_u_handler +#define sa_sigaction sa_u.sa_u_sigaction + +#ifndef _POSIX_SOURCE +#define SA_ONSTACK 0x0001 /* take signal on signal stack */ +#define SA_RESTART 0x0002 /* restart system on signal return */ +#define SA_DISABLE 0x0004 /* disable taking signals on alternate stack */ +#ifdef COMPAT_SUNOS +#define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ +#endif +#endif +#define SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ +#define SA_SIGINFO 0x0010 /* use sa_sigaction calling convention */ + +/* + * Flags for sigprocmask: + */ +#define SIG_BLOCK 1 /* block specified signal set */ +#define SIG_UNBLOCK 2 /* unblock specified signal set */ +#define SIG_SETMASK 3 /* set specified signal set */ + +/* + * POSIX 1003.1b: + * Used when requesting queued notification of an event, + * such as a timer expiration or a message arrival. + */ +struct sigevent +{ + int sigev_notify; + union + { + struct + { + int __signo; + union sigval __value; + } __sig; + struct + { + void (*__handler)(void); + void *__stack; + } __fastint; + } __u; +}; + +#define sigev_signo __u.__sig.__signo +#define sigev_value __u.__sig.__value + +#define sigev_handler __u.__fastint.__handler +#define sigev_stack __u.__fastint.__stack + +/* Values for sigev_notify */ +#define SIGEV_NONE 0 +#define SIGEV_SIGNAL 1 +#define SIGEV_FASTINT 2 + + +__FLUX_BEGIN_DECLS +int kill(__flux_pid_t __pid, int __sig); +int sigaction(int __sig, const struct sigaction *__act, + struct sigaction *__oact); +int sigprocmask(int __how, const sigset_t *__set, sigset_t *__oset); +int sigsuspend(const sigset_t *__sigmask); +int sigwaitinfo(const sigset_t *__set, siginfo_t *__info); +int sigqueue(__flux_pid_t __pid, int __signo, const union sigval __value); +__FLUX_END_DECLS + + +#define sigaddset(set, signo) (*(set) |= 1 << ((signo) - 1), 0) +#define sigdelset(set, signo) (*(set) &= ~(1 << ((signo) - 1)), 0) +#define sigemptyset(set) (*(set) = 0, 0) +#define sigfillset(set) (*(set) = ~(sigset_t)0, 0) +#define sigismember(set, signo) ((*(set) & (1 << ((signo) - 1))) != 0) + +#endif /* !_ANSI_SOURCE */ + +#endif /* !_FLUX_MC_SIGNAL_H_ */ diff --git a/apps/rmgr/include/flux/c/stdarg.h b/apps/rmgr/include/flux/c/stdarg.h new file mode 100644 index 0000000..fa0aa11 --- /dev/null +++ b/apps/rmgr/include/flux/c/stdarg.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#include + +#endif /* _STDARG_H_ */ diff --git a/apps/rmgr/include/flux/c/stddef.h b/apps/rmgr/include/flux/c/stddef.h new file mode 100644 index 0000000..fb420da --- /dev/null +++ b/apps/rmgr/include/flux/c/stddef.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_C_STDDEF_H_ +#define _FLUX_C_STDDEF_H_ + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif /* _FLUX_C_STDDEF_H_ */ diff --git a/apps/rmgr/include/flux/c/stdio.h b/apps/rmgr/include/flux/c/stdio.h new file mode 100644 index 0000000..0dc0aaa --- /dev/null +++ b/apps/rmgr/include/flux/c/stdio.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_STDIO_H +#define _FLUX_MC_STDIO_H + +#include + +/* This is a very naive standard I/O implementation + which simply chains to the low-level I/O routines + without doing any buffering or anything. */ + +#ifndef NULL +#define NULL 0 +#endif + +typedef struct +{ + int fd; +} FILE; + +#define fileno(__stream) (__stream)->fd + +extern FILE __stdin, __stdout, __stderr; +#define stdin (&__stdin) +#define stdout (&__stdout) +#define stderr (&__stderr) + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef EOF +#define EOF -1 +#endif + +__FLUX_BEGIN_DECLS + +int putchar(int __c); +int puts(const char *__str); +int printf(const char *__format, ...); +int vprintf(const char *__format, __flux_va_list __vl); +int sprintf(char *__dest, const char *__format, ...); +int snprintf(char *__dest, int __size, const char *__format, ...); +int vsprintf(char *__dest, const char *__format, __flux_va_list __vl); +int vsnprintf(char *__dest, int __size, const char *__format, __flux_va_list __vl); +int getchar(void); +FILE *fopen(const char *__path, const char *__mode); +int fclose(FILE *__stream); +int fread(void *__buf, int __size, int __count, FILE *__stream); +int fwrite(void *buf, int __size, int __count, FILE *__stream); +int fputc(int c, FILE *__stream); +int fgetc(FILE *__stream); +int fprintf(FILE *__stream, const char *__format, ...); +int vfprintf(FILE *__stream, const char *__format, __flux_va_list __vl); +int fscanf(FILE *__stream, const char *__format, ...); +int fseek(FILE *__stream, long __offset, int __whence); +int feof(FILE *__stream); +long ftell(FILE *__stream); +void rewind(FILE *__stream); +int rename(const char *__from, const char *__to); +void hexdump(void *buf, int len); + +#define putc(c, stream) fputc(c, stream) + +__FLUX_END_DECLS + +#endif _FLUX_MC_STDIO_H diff --git a/apps/rmgr/include/flux/c/stdlib.h b/apps/rmgr/include/flux/c/stdlib.h new file mode 100644 index 0000000..af87743 --- /dev/null +++ b/apps/rmgr/include/flux/c/stdlib.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _MACH_SA_STDLIB_H_ +#define _MACH_SA_STDLIB_H_ + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +__FLUX_BEGIN_DECLS + +/* + * These function prototypes are roughly in the same order + * as their descriptions in the ISO/ANSI C standard, section 7.10. + */ + +#define atoi(str) ((int)atol(str)) +long atol(const char *__str); +long strtol(const char *__p, char **__out_p, int __base); +unsigned long strtoul(const char *__p, char **__out_p, int __base); + +int rand(void); +void srand(unsigned __seed); + +/* Don't macro expand protos please. */ +#ifndef MALLOC_IS_MACRO +void *malloc(size_t __size); +void *mustmalloc(size_t __size); +void *calloc(size_t __nelt, size_t __eltsize); +void *mustcalloc(size_t __nelt, size_t __eltsize); +void *realloc(void *__buf, size_t __new_size); +void free(void *__buf); +#endif /* MALLOC_IS_MACRO */ + +void abort(void) __FLUX_NORETURN; +void exit(int __status) __FLUX_NORETURN; +void panic(const char *__format, ...) __FLUX_NORETURN; + +int atexit(void (*__function)(void)); + +char *getenv(const char *__name); + +void qsort(void *__array, size_t __nelt, size_t __eltsize, + int (*__cmp)(void *, void *)); + +#define abs(n) __builtin_abs(n) + +__FLUX_END_DECLS + +#endif _MACH_SA_STDLIB_H_ diff --git a/apps/rmgr/include/flux/c/string.h b/apps/rmgr/include/flux/c/string.h new file mode 100644 index 0000000..87b817a --- /dev/null +++ b/apps/rmgr/include/flux/c/string.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_STRING_H_ +#define _FLUX_MC_STRING_H_ + +#include + +#ifndef NULL +#define NULL 0 +#endif + +__FLUX_BEGIN_DECLS + +__flux_size_t strlen(const char *__s); +char *strcpy(char *__dest, const char *__src); +char *strncpy(char *__dest, const char *__src, int __n); +char *strdup(const char *__s); +char *strcat(char *__dest, const char *__src); +char *strncat(char *__dest, const char *__src, __flux_size_t __n); +int strcmp(const char *__a, const char *__b); +int strncmp(const char *__a, const char *__b, int __n); + +char *strchr(const char *__s, int __c); +char *strrchr(const char *__s, int __c); +char *strstr(const char *__haystack, const char *__needle); +char *strtok(char *__s, const char *__delim); +char *strpbrk(const char *__s1, const char *__s2); +__flux_size_t strspn(const char *__s1, const char *__s2); +__flux_size_t strcspn(const char *__s1, const char *__s2); + +#ifndef __GNUC__ +void *memcpy(void *__to, const void *__from, unsigned int __n); +#endif +void *memset(void *__to, int __ch, unsigned int __n); +#ifndef __GNUC__ +int memcmp(const void *s1v, const void *s2v, int size); +#else +#define memcmp __builtin_memcmp +#endif + + +/*** BSD compatibility functions; do not use in new code ***/ + +char *index(const char *__s, int __c); +char *rindex(const char *__s, int __c); + +void bcopy(const void *__from, void *__to, unsigned int __n); +void bzero(void *__to, unsigned int __n); + +__FLUX_END_DECLS + +#endif _FLUX_MC_STRING_H_ diff --git a/apps/rmgr/include/flux/c/strings.h b/apps/rmgr/include/flux/c/strings.h new file mode 100644 index 0000000..f5d6c73 --- /dev/null +++ b/apps/rmgr/include/flux/c/strings.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _MACH_STRINGS_H_ +#define _MACH_STRINGS_H_ + +#include + +#endif _MACH_STRINGS_H_ diff --git a/apps/rmgr/include/flux/c/sys/gmon.h b/apps/rmgr/include/flux/c/sys/gmon.h new file mode 100644 index 0000000..50a26e6 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/gmon.h @@ -0,0 +1,165 @@ +/*- + * Copyright (c) 1982, 1986, 1992, 1993 + * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)gmon.h 8.2 (Berkeley) 1/4/94 + */ + +#ifndef _SYS_GMON_H_ +#define _SYS_GMON_H_ + +#if 0 +#include +#endif + +/* + * Structure prepended to gmon.out profiling data file. + */ +struct gmonhdr { + u_long lpc; /* base pc address of sample buffer */ + u_long hpc; /* max pc address of sampled buffer */ + int ncnt; /* size of sample buffer (plus this header) */ + int version; /* version number */ + int profrate; /* profiling clock rate */ + int spare[3]; /* reserved */ +}; +#define GMONVERSION 0x00051879 + +/* + * histogram counters are unsigned shorts (according to the kernel). + */ +#if 0 +#define HISTCOUNTER unsigned short +#else +#define HISTCOUNTER unsigned int +#endif + +/* + * fraction of text space to allocate for histogram counters here, 1/2 + */ +#define HISTFRACTION 2 + +/* + * Fraction of text space to allocate for from hash buckets. + * The value of HASHFRACTION is based on the minimum number of bytes + * of separation between two subroutine call points in the object code. + * Given MIN_SUBR_SEPARATION bytes of separation the value of + * HASHFRACTION is calculated as: + * + * HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1); + * + * For example, on the VAX, the shortest two call sequence is: + * + * calls $0,(r0) + * calls $0,(r0) + * + * which is separated by only three bytes, thus HASHFRACTION is + * calculated as: + * + * HASHFRACTION = 3 / (2 * 2 - 1) = 1 + * + * Note that the division above rounds down, thus if MIN_SUBR_FRACTION + * is less than three, this algorithm will not work! + * + * In practice, however, call instructions are rarely at a minimal + * distance. Hence, we will define HASHFRACTION to be 2 across all + * architectures. This saves a reasonable amount of space for + * profiling data structures without (in practice) sacrificing + * any granularity. + */ +#define HASHFRACTION 2 + +/* + * percent of text space to allocate for tostructs with a minimum. + */ +#define ARCDENSITY 2 +#define MINARCS 50 +#define MAXARCS (((u_long)1 << (8 * sizeof(HISTCOUNTER))) - 2) + +struct tostruct { + u_long selfpc; + long count; + u_short link; + u_short pad; +}; + +/* + * a raw arc, with pointers to the calling site and + * the called site and a count. + */ +struct rawarc { + u_long raw_frompc; + u_long raw_selfpc; + long raw_count; +}; + +/* + * general rounding functions. + */ +#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) + +/* + * The profiling data structures are housed in this structure. + */ +struct gmonparam { + int state; + HISTCOUNTER *kcount; + u_long kcountsize; + u_short *froms; + u_long fromssize; + struct tostruct *tos; + u_long tossize; + long tolimit; + u_long lowpc; + u_long highpc; + u_long textsize; + u_long hashfraction; +}; +extern struct gmonparam _gmonparam; + +/* + * Possible states of profiling. + */ +#define GMON_PROF_ON 0 +#define GMON_PROF_BUSY 1 +#define GMON_PROF_ERROR 2 +#define GMON_PROF_OFF 3 + +/* + * Sysctl definitions for extracting profiling information from the kernel. + */ +#define GPROF_STATE 0 /* int: profiling enabling variable */ +#define GPROF_COUNT 1 /* struct: profile tick count buffer */ +#define GPROF_FROMS 2 /* struct: from location hash bucket */ +#define GPROF_TOS 3 /* struct: destination/count structure */ +#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */ +#endif /* !_SYS_GMON_H_ */ diff --git a/apps/rmgr/include/flux/c/sys/ioctl.h b/apps/rmgr/include/flux/c/sys/ioctl.h new file mode 100644 index 0000000..732494d --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/ioctl.h @@ -0,0 +1,52 @@ +/* + * Mach Operating System + * Copyright (c) 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon rights + * to redistribute these changes. + */ +/* + * Format definitions for 'ioctl' commands in device definitions. + * + * From BSD4.4. + */ + +#ifndef _MACH_SYS_IOCTL_H_ +#define _MACH_SYS_IOCTL_H_ +/* + * 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 3 bits of the + * upper word are used to encode the in/out status of the parameter. + */ +#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ +#define IOC_VOID 0x20000000 /* no parameters */ +#define IOC_OUT 0x40000000 /* copy out parameters */ +#define IOC_IN 0x80000000U /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + +#define _IOC(inout,group,num,len) \ + (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) +#define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) +#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) +#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) +#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) + +#endif _MACH_SYS_IOCTL_H_ diff --git a/apps/rmgr/include/flux/c/sys/mman.h b/apps/rmgr/include/flux/c/sys/mman.h new file mode 100644 index 0000000..3585558 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/mman.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_SYS_MMAN_H_ +#define _FLUX_MC_SYS_MMAN_H_ + +/* + * Protections are chosen from these bits, or-ed together. + * NB: These are the same values as the VM_PROT_xxx definitions, + * and they can be used interchangeably. + * They are also the same values used in traditional Unix, BSD, and Linux + * though READ/EXEC are reversed from the traditional Unix filesystem values. + */ +#define PROT_READ 0x01 /* pages can be read */ +#define PROT_WRITE 0x02 /* pages can be written */ +#define PROT_EXEC 0x04 /* pages can be executed */ +#define PROT_NONE 0x00 /* no access permitted */ + +/* + * Flags for mmap(). + * These are the same values as in BSD. + */ +#define MAP_SHARED 0x0001 /* writes change the underlying file */ +#define MAP_PRIVATE 0x0002 /* writes only change our mapping */ +#define MAP_FIXED 0x0010 /* must use specified address exactly */ + +/* + * Failure return value for mmmap + */ +#define MAP_FAILED ((void *)-1) + +/* + * Flags for the msync() call. + */ +#define MS_INVALIDATE 0x0004 /* invalidate cached data */ + +/* + * Flags for the mlockall() call. + */ +#define MCL_CURRENT 0x0001 /* lock all currently mapped memory */ +#define MCL_FUTURE 0x0002 /* lock all memory mapped in the future */ + +#endif _FLUX_MC_SYS_MMAN_H_ diff --git a/apps/rmgr/include/flux/c/sys/reboot.h b/apps/rmgr/include/flux/c/sys/reboot.h new file mode 100644 index 0000000..36d19d9 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/reboot.h @@ -0,0 +1,142 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)reboot.h 7.5 (Berkeley) 6/27/88 + */ +/* + * Warning: The contents of this file are deprecated; + * it should only ever be used for BSD and Mach 3 compatibility. + * As the above copyright notice suggests, this file originated in BSD; + * it is mostly the same, except the flags after RB_DFLTROOT + * have diverged from BSD. + */ +#ifndef _MACH_SYS_REBOOT_H_ +#define _MACH_SYS_REBOOT_H_ + +/* + * Arguments to reboot system call. + * These are converted to switches, and passed to startup program, + * and on to init. + */ + +/* + * Defs that work on BSD and Mach. + */ +#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#define RB_ASKNAME 0x01 /* -a: ask for file name to reboot from */ +#define RB_SINGLE 0x02 /* -s: reboot to single user only */ +#define RB_HALT 0x08 /* -h: enter KDB at bootup */ + /* for host_reboot(): don't reboot, + just halt */ +#define RB_INITNAME 0x10 /* -i: name given for /etc/init (unused) */ +#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */ + +/* + * Mach specific defs. + */ +#define MACH_RB_KDB 0x04 /* -d: kernel debugger symbols loaded */ +#define MACH_RB_NOBOOTRC 0x20 /* -b: don't run /etc/rc.boot */ +#define MACH_RB_ALTBOOT 0x40 /* use /boot.old vs /boot */ +#define MACH_RB_UNIPROC 0x80 /* -u: start only one processor */ + +#define MACH_RB_PANIC 0 /* reboot due to panic */ +#define MACH_RB_BOOT 1 /* reboot due to boot() */ +#define MACH_RB_SHIFT 8 /* second byte is for ux */ + +#define MACH_RB_DEBUGGER 0x1000 /* for host_reboot(): enter kernel + debugger from user level */ + +/* + * BSD specific defs. + * NetBSD or FreeBSD. + */ +#define BSD_RB_NOSYNC 0x04 /* dont sync before reboot */ +#define BSD_RB_KDB 0x40 /* give control to kernel debugger */ +#define BSD_RB_RDONLY 0x80 /* mount root fs read-only */ +#define BSD_RB_DUMP 0x100 /* dump kernel memory before reboot */ +#define BSD_RB_MINIROOT 0x200 /* mini-root present in memory at boot time */ +#define BSD_RB_CONFIG 0x400 /* invoke user configuration routing */ +#define BSD_RB_VERBOSE 0x800 /* print all potentially useful info */ +#define BSD_RB_SERIAL 0x1000 /* user serial port as console */ +#define BSD_RB_CDROM 0x2000 /* use cdrom as root */ + +#define BSD_RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */ + +/* + * This part is identical for Mach and Free/NetBSD. + * + * Constants for converting boot-style device number to type, + * adaptor (uba, mba, etc), unit number and partition number. + * Type (== major device number) is in the low byte + * for backward compatibility. Except for that of the "magic + * number", each mask applies to the shifted value. + * Format: + * (4) (4) (4) (4) (8) (8) + * -------------------------------- + * |MA | AD| CT| UN| PART | TYPE | + * -------------------------------- + */ +#define B_ADAPTORSHIFT 24 +#define B_ADAPTORMASK 0x0f +#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK) +#define B_CONTROLLERSHIFT 20 +#define B_CONTROLLERMASK 0xf +#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK) +#define B_UNITSHIFT 16 +#define B_UNITMASK 0xf +#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK) +#define B_PARTITIONSHIFT 8 +#define B_PARTITIONMASK 0xff +#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK) +#define B_TYPESHIFT 0 +#define B_TYPEMASK 0xff +#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK) + +#define B_MAGICMASK ((u_int)0xf0000000U) +#define B_DEVMAGIC ((u_int)0xa0000000U) + +#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \ + (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \ + ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \ + ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC) + +#endif /* _MACH_SYS_REBOOT_H_ */ diff --git a/apps/rmgr/include/flux/c/sys/signal.h b/apps/rmgr/include/flux/c/sys/signal.h new file mode 100644 index 0000000..4e29e70 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/signal.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Compatibility for BSD code that includes + * instead of the POSIX-defined + */ +#ifndef _FLUX_MC_SYS_SIGNAL_H +#define _FLUX_MC_SYS_SIGNAL_H + +#include + +#endif /* _FLUX_MC_SYS_SIGNAL_H */ diff --git a/apps/rmgr/include/flux/c/sys/stat.h b/apps/rmgr/include/flux/c/sys/stat.h new file mode 100644 index 0000000..f0a21da --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/stat.h @@ -0,0 +1,119 @@ +/*- + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)stat.h 8.6 (Berkeley) 3/8/94 + * stat.h,v 1.5 1994/10/02 17:24:57 phk Exp + */ + +#ifndef _MACH_SA_SYS_STAT_H_ +#define _MACH_SA_SYS_STAT_H_ + +#include + +struct stat { + dev_t st_dev; /* inode's device */ + ino_t st_ino; /* inode's number */ + mode_t st_mode; /* inode protection mode */ + nlink_t st_nlink; /* number of hard links */ + uid_t st_uid; /* user ID of the file's owner */ + gid_t st_gid; /* group ID of the file's group */ + dev_t st_rdev; /* device type */ + time_t st_atime; /* time of last access */ + time_t st_mtime; /* time of last data modification */ + time_t st_ctime; /* time of last file status change */ + off_t st_size; /* file size, in bytes */ + unsigned long st_blocks; /* blocks allocated for file */ + unsigned long st_blksize; /* optimal blocksize for I/O */ +}; + +#define S_ISUID 0004000 /* set user id on execution */ +#define S_ISGID 0002000 /* set group id on execution */ +#ifndef _POSIX_SOURCE +#define S_ISTXT 0001000 /* sticky bit */ +#endif + +#define S_IRWXU 0000700 /* RWX mask for owner */ +#define S_IRUSR 0000400 /* R for owner */ +#define S_IWUSR 0000200 /* W for owner */ +#define S_IXUSR 0000100 /* X for owner */ + +#define S_IRWXG 0000070 /* RWX mask for group */ +#define S_IRGRP 0000040 /* R for group */ +#define S_IWGRP 0000020 /* W for group */ +#define S_IXGRP 0000010 /* X for group */ + +#define S_IRWXO 0000007 /* RWX mask for other */ +#define S_IROTH 0000004 /* R for other */ +#define S_IWOTH 0000002 /* W for other */ +#define S_IXOTH 0000001 /* X for other */ + +#ifndef _POSIX_SOURCE +#define S_IFMT 0170000 /* type of file mask */ +#define S_IFIFO 0010000 /* named pipe (fifo) */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFREG 0100000 /* regular */ +#define S_IFLNK 0120000 /* symbolic link */ +#define S_IFSOCK 0140000 /* socket */ +#define S_ISVTX 0001000 /* save swapped text even after use */ +#endif + +#define S_ISDIR(m) (((m) & 0170000) == 0040000) /* directory */ +#define S_ISCHR(m) (((m) & 0170000) == 0020000) /* char special */ +#define S_ISBLK(m) (((m) & 0170000) == 0060000) /* block special */ +#define S_ISREG(m) (((m) & 0170000) == 0100000) /* regular file */ +#define S_ISFIFO(m) (((m) & 0170000) == 0010000 || \ + ((m) & 0170000) == 0140000) /* fifo or socket */ +#ifndef _POSIX_SOURCE +#define S_ISLNK(m) (((m) & 0170000) == 0120000) /* symbolic link */ +#define S_ISSOCK(m) (((m) & 0170000) == 0010000 || \ + ((m) & 0170000) == 0140000) /* fifo or socket */ +#endif + +#include + +__FLUX_BEGIN_DECLS +int chmod(const char *, __flux_mode_t); +int fstat(int, struct stat *); +int mkdir(const char *, __flux_mode_t); +int mkfifo(const char *, __flux_mode_t); +int stat(const char *, struct stat *); +__flux_mode_t umask(__flux_mode_t); +__FLUX_END_DECLS + +#endif /* !_MACH_SA_SYS_STAT_H_ */ diff --git a/apps/rmgr/include/flux/c/sys/termios.h b/apps/rmgr/include/flux/c/sys/termios.h new file mode 100644 index 0000000..444c3d7 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/termios.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Compatibility for BSD code that includes + * instead of the POSIX-defined + */ +#ifndef _FLUX_MC_SYS_TERMIOS_H +#define _FLUX_MC_SYS_TERMIOS_H + +#include + +#endif /* _FLUX_MC_SYS_TERMIOS_H */ diff --git a/apps/rmgr/include/flux/c/sys/time.h b/apps/rmgr/include/flux/c/sys/time.h new file mode 100644 index 0000000..bc761f1 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/time.h @@ -0,0 +1,58 @@ +/* + * Mach Operating System + * Copyright (c) 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon rights + * to redistribute these changes. + */ +/* + * Time-keeper for kernel IO devices. + * + * May or may not have any relation to wall-clock time. + */ + +#ifndef _FLUX_MC_SYS_TIME_H_ +#define _FLUX_MC_SYS_TIME_H_ + +#include + +typedef struct time_value { long seconds, microseconds; } time_value_t; + +/* + * Definitions to keep old code happy. + */ +#define timeval_t time_value_t +#define timeval time_value +#define tv_sec seconds +#define tv_usec microseconds + +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + ((tvp)->tv_sec cmp (uvp)->tv_sec || \ + (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 + +struct timezone; + +__FLUX_BEGIN_DECLS +int gettimeofday(struct timeval *tp, struct timezone *tzp); +__FLUX_END_DECLS +#endif _FLUX_MC_SYS_TIME_H_ diff --git a/apps/rmgr/include/flux/c/sys/types.h b/apps/rmgr/include/flux/c/sys/types.h new file mode 100644 index 0000000..7804c56 --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/types.h @@ -0,0 +1,92 @@ +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _MACH_SA_SYS_TYPES_H_ +#define _MACH_SA_SYS_TYPES_H_ + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __flux_ssize_t ssize_t; +#endif + +typedef __flux_dev_t dev_t; /* device id */ +typedef __flux_gid_t gid_t; /* group id */ +typedef __flux_ino_t ino_t; /* inode number */ +typedef __flux_mode_t mode_t; /* permissions */ +typedef __flux_nlink_t nlink_t; /* link count */ +typedef __flux_off_t off_t; /* file offset */ +typedef __flux_uid_t uid_t; /* user id */ +typedef __flux_pid_t pid_t; /* process id */ + + +/* Symbols allowed but not required by POSIX */ + +typedef char * caddr_t; /* address of a (signed) char */ + +#ifndef _TIME_T +#define _TIME_T +typedef unsigned int time_t; +#endif + +#define RAND_MAX 0x7fffffff + +/* Symbols not allowed by POSIX */ +#ifndef _POSIX_SOURCE + +/* + * Common type definitions that lots of old files seem to want. + */ + +typedef unsigned char u_char; /* unsigned char */ +typedef unsigned short u_short; /* unsigned short */ +typedef unsigned int u_int; /* unsigned int */ +typedef unsigned long u_long; /* unsigned long */ + +typedef struct _quad_ { + unsigned int val[2]; /* 2 32-bit values make... */ +} quad; /* an 8-byte item */ + +typedef unsigned int daddr_t; /* disk address */ + +#define major(i) (((i) >> 8) & 0xFF) +#define minor(i) ((i) & 0xFF) +#define makedev(i,j) ((((i) & 0xFF) << 8) | ((j) & 0xFF)) + +#define NBBY 8 + +#ifndef NULL +#define NULL ((void *) 0) /* the null pointer */ +#endif + +#endif /* _POSIX_SOURCE */ + +#endif /* _MACH_SA_SYS_TYPES_H_ */ diff --git a/apps/rmgr/include/flux/c/sys/uio.h b/apps/rmgr/include/flux/c/sys/uio.h new file mode 100644 index 0000000..9f717cb --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/uio.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1982, 1986, 1993, 1994 + * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)uio.h 8.5 (Berkeley) 2/22/94 + * uio.h,v 1.3 1994/09/15 20:24:28 bde Exp + */ + +#ifndef _FLUX_C_SYS_UIO_H_ +#define _FLUX_C_SYS_UIO_H_ + +#include + +/* + * XXX + * iov_base should be a void *. + */ +struct iovec { + char *iov_base; /* Base address. */ + size_t iov_len; /* Length. */ +}; + +enum uio_rw { UIO_READ, UIO_WRITE }; + +/* Segment flag values. */ +enum uio_seg { + UIO_USERSPACE, /* from user data space */ + UIO_SYSSPACE, /* from system space */ + UIO_USERISPACE /* from user I space */ +}; + +__FLUX_BEGIN_DECLS +ssize_t readv (int, const struct iovec *, int); +ssize_t writev (int, const struct iovec *, int); +__FLUX_END_DECLS + +#endif /* !_FLUX_C_SYS_UIO_H_ */ diff --git a/apps/rmgr/include/flux/c/sys/wait.h b/apps/rmgr/include/flux/c/sys/wait.h new file mode 100644 index 0000000..6689def --- /dev/null +++ b/apps/rmgr/include/flux/c/sys/wait.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * POSIX-defined + */ +#ifndef _FLUX_C_SYS_WAIT_H +#define _FLUX_C_SYS_WAIT_H + +#include +#include + +/* Upper 8 bits are return code, lowest 7 are status bits */ +#define _WSTATMASK 0177 +#define _WEXITSTAT(stat_val) ((stat_val) & _WSTATMASK) + +/* Evaluates to nonzero if child terminated normally. */ +#define WIFEXITED(stat_val) (_WEXITSTAT(stat_val) == 0) + +/* Evaulates to nonzero if child terminated due to unhandled signal */ +#define WIFSIGNALED(stat_val) ((_WEXITSTAT(stat_val) != _WSTATMASK) && (_WEXITSTAT(stat_val) != 0)) + +/* Evaluates to nonzero if child process is currently stopped. */ +#define WIFSTOPPED(stat_val) (_WEXITSTAT(stat_val) == _WSTATMASK) + +/* + * If WIFEXITED(stat_val) is nonzero, this evaulates to the return code of the + * child process. + */ +#define WEXITSTATUS(stat_val) ((stat_val) >> 8) + +/* + * If WIFSIGNALED(stat_val) is nonzero, this evaluates to the signal number + * that caused the termination. + */ +#define WTERMSIG(stat_val) (_WEXITSTAT(stat_val)) + +/* + * If WIFSTOPPED(stat_val) is nonzero, this evaluates to the signal number + * that caused the child to stop. + */ +#define WSTOPSIG(stat_val) ((stat_val) >> 8) + +/* + * bitwise OR-able option flags to waitpid(). waitpid() will not suspend the + * caller if WNOHANG is given and there is no process status immediately + * available. WUNTRACED causes waitpid() to report stopped processes whose + * status has not yet been reported since they stopped. + */ +#define WNOHANG 1 +#define WUNTRACED 2 + + +__FLUX_BEGIN_DECLS + +pid_t wait(int *__stat_loc); +pid_t waitpid(pid_t __pid, int *__stat_loc, int __options); + +__FLUX_END_DECLS + +#endif diff --git a/apps/rmgr/include/flux/c/termios.h b/apps/rmgr/include/flux/c/termios.h new file mode 100644 index 0000000..b1c4721 --- /dev/null +++ b/apps/rmgr/include/flux/c/termios.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 1988, 1989, 1993, 1994 + * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)termios.h 8.3 (Berkeley) 3/28/94 + * termios.h,v 1.3 1994/08/02 07:53:46 davidg Exp + */ + +#ifndef _FLUX_MC_SYS_TERMIOS_H_ +#define _FLUX_MC_SYS_TERMIOS_H_ + +/* + * Special Control Characters + * + * Index into c_cc[] character array. + * + * Name Subscript Enabled by + */ +#define VEOF 0 /* ICANON */ +#define VEOL 1 /* ICANON */ +#define VERASE 3 /* ICANON */ +#define VKILL 5 /* ICANON */ +#define VINTR 8 /* ISIG */ +#define VQUIT 9 /* ISIG */ +#define VSUSP 10 /* ISIG */ +#define VSTART 12 /* IXON, IXOFF */ +#define VSTOP 13 /* IXON, IXOFF */ +#define VMIN 16 /* !ICANON */ +#define VTIME 17 /* !ICANON */ +#define NCCS 20 + +#define _POSIX_VDISABLE ((unsigned char)'\377') + +/* + * Input flags - software input processing + */ +#define IGNBRK 0x00000001 /* ignore BREAK condition */ +#define BRKINT 0x00000002 /* map BREAK to SIGINTR */ +#define IGNPAR 0x00000004 /* ignore (discard) parity errors */ +#define PARMRK 0x00000008 /* mark parity and framing errors */ +#define INPCK 0x00000010 /* enable checking of parity errors */ +#define ISTRIP 0x00000020 /* strip 8th bit off chars */ +#define INLCR 0x00000040 /* map NL into CR */ +#define IGNCR 0x00000080 /* ignore CR */ +#define ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */ +#define IXON 0x00000200 /* enable output flow control */ +#define IXOFF 0x00000400 /* enable input flow control */ +#ifndef _POSIX_SOURCE +#define IXANY 0x00000800 /* any char will restart after stop */ +#define IMAXBEL 0x00002000 /* ring bell on input queue full */ +#endif /*_POSIX_SOURCE */ + +/* + * Output flags - software output processing + */ +#define OPOST 0x00000001 /* enable following output processing */ + +/* + * Control flags - hardware control of terminal + */ +#define CSIZE 0x00000300 /* character size mask */ +#define CS5 0x00000000 /* 5 bits (pseudo) */ +#define CS6 0x00000100 /* 6 bits */ +#define CS7 0x00000200 /* 7 bits */ +#define CS8 0x00000300 /* 8 bits */ +#define CSTOPB 0x00000400 /* send 2 stop bits */ +#define CREAD 0x00000800 /* enable receiver */ +#define PARENB 0x00001000 /* parity enable */ +#define PARODD 0x00002000 /* odd parity, else even */ +#define HUPCL 0x00004000 /* hang up on last close */ +#define CLOCAL 0x00008000 /* ignore modem status lines */ + + +/* + * "Local" flags - dumping ground for other state + * + * Warning: some flags in this structure begin with + * the letter "I" and look like they belong in the + * input flag. + */ + +#define ECHOE 0x00000002 /* visually erase chars */ +#define ECHOK 0x00000004 /* echo NL after line kill */ +#define ECHO 0x00000008 /* enable echoing */ +#define ECHONL 0x00000010 /* echo NL even if ECHO is off */ +#define ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */ +#define ICANON 0x00000100 /* canonicalize input lines */ +#define IEXTEN 0x00000400 /* enable DISCARD and LNEXT */ +#define EXTPROC 0x00000800 /* external processing */ +#define TOSTOP 0x00400000 /* stop background jobs from output */ +#define NOFLSH 0x80000000 /* don't flush after interrupt */ + +typedef unsigned long tcflag_t; +typedef unsigned char cc_t; +typedef long speed_t; + +struct termios { + tcflag_t c_iflag; /* input flags */ + tcflag_t c_oflag; /* output flags */ + tcflag_t c_cflag; /* control flags */ + tcflag_t c_lflag; /* local flags */ + cc_t c_cc[NCCS]; /* control chars */ + long c_ispeed; /* input speed */ + long c_ospeed; /* output speed */ +}; + +/* + * Commands passed to tcsetattr() for setting the termios structure. + */ +#define TCSANOW 0 /* make change immediate */ +#define TCSADRAIN 1 /* drain output, then change */ +#define TCSAFLUSH 2 /* drain output, flush input */ +#ifndef _POSIX_SOURCE +#define TCSASOFT 0x10 /* flag - don't alter h.w. state */ +#endif + +/* + * Standard speeds + */ +#define B0 0 +#define B50 50 +#define B75 75 +#define B110 110 +#define B134 134 +#define B150 150 +#define B200 200 +#define B300 300 +#define B600 600 +#define B1200 1200 +#define B1800 1800 +#define B2400 2400 +#define B4800 4800 +#define B9600 9600 +#define B19200 19200 +#define B38400 38400 +#ifndef _POSIX_SOURCE +#define B7200 7200 +#define B14400 14400 +#define B28800 28800 +#define B57600 57600 +#define B76800 76800 +#define B115200 115200 +#define B230400 230400 +#endif /* !_POSIX_SOURCE */ + +#define TCIFLUSH 1 +#define TCOFLUSH 2 +#define TCIOFLUSH 3 +#define TCOOFF 1 +#define TCOON 2 +#define TCIOFF 3 +#define TCION 4 + +#include + +__FLUX_BEGIN_DECLS +speed_t cfgetispeed(const struct termios *); +speed_t cfgetospeed(const struct termios *); +int cfsetispeed(struct termios *, speed_t); +int cfsetospeed(struct termios *, speed_t); +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, const struct termios *); +int tcdrain(int); +int tcflow(int, int); +int tcflush(int, int); +int tcsendbreak(int, int); +__FLUX_END_DECLS + +#endif /* _FLUX_MC_SYS_TERMIOS_H_ */ diff --git a/apps/rmgr/include/flux/c/time.h b/apps/rmgr/include/flux/c/time.h new file mode 100644 index 0000000..4ddf6b6 --- /dev/null +++ b/apps/rmgr/include/flux/c/time.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _MACH_SA_TIME_H +#define _MACH_SA_TIME_H + +#endif /* _MACH_SA_TIME_H */ diff --git a/apps/rmgr/include/flux/c/unistd.h b/apps/rmgr/include/flux/c/unistd.h new file mode 100644 index 0000000..f3ba4b0 --- /dev/null +++ b/apps/rmgr/include/flux/c/unistd.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MC_UNISTD_H_ +#define _FLUX_MC_UNISTD_H_ + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __flux_ssize_t ssize_t; +#endif + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +/* access function */ +#define F_OK 0 /* test for existence of file */ +#define X_OK 0x01 /* test for execute or search permission */ +#define W_OK 0x02 /* test for write permission */ +#define R_OK 0x04 /* test for read permission */ + +__FLUX_BEGIN_DECLS + +void _exit(int __fd) __FLUX_NORETURN; +int close(int __fd); +ssize_t read(int __fd, void *__buf, size_t __n); +ssize_t write(int __fd, const void *__buf, size_t __n); +__flux_off_t lseek(int __fd, __flux_off_t __offset, int __whence); +int rename(const char *__oldpath, const char *__newpath); +void *sbrk(int __size); +int unlink(const char *__path); + +__FLUX_END_DECLS + +#endif /* _FLUX_MC_UNISTD_H_ */ diff --git a/apps/rmgr/include/flux/config.h b/apps/rmgr/include/flux/config.h new file mode 100644 index 0000000..3adaa9d --- /dev/null +++ b/apps/rmgr/include/flux/config.h @@ -0,0 +1,38 @@ +/* flux/config.h. Generated automatically by configure. */ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_CONFIG_H_ +#define _FLUX_CONFIG_H_ + +/* Define if your assembler supports the %cr4 register. */ +#define HAVE_CR4 1 + +/* Define if your assembler supports the .p2align pseudo-op. */ +#define HAVE_P2ALIGN 1 + +/* Define if your assembler supports the .code16 pseudo-op. */ +#define HAVE_CODE16 1 + +/* Define if your assembler allows .space within .bss segments. */ +#define HAVE_WORKING_BSS 1 + +#endif /* _FLUX_CONFIG_H_ */ diff --git a/apps/rmgr/include/flux/config.h.in b/apps/rmgr/include/flux/config.h.in new file mode 100644 index 0000000..52186a5 --- /dev/null +++ b/apps/rmgr/include/flux/config.h.in @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_CONFIG_H_ +#define _FLUX_CONFIG_H_ + +/* Define if your assembler supports the %cr4 register. */ +#undef HAVE_CR4 + +/* Define if your assembler supports the .p2align pseudo-op. */ +#undef HAVE_P2ALIGN + +/* Define if your assembler supports the .code16 pseudo-op. */ +#undef HAVE_CODE16 + +/* Define if your assembler allows .space within .bss segments. */ +#undef HAVE_WORKING_BSS + +#endif /* _FLUX_CONFIG_H_ */ diff --git a/apps/rmgr/include/flux/debug.h b/apps/rmgr/include/flux/debug.h new file mode 100644 index 0000000..e9de47d --- /dev/null +++ b/apps/rmgr/include/flux/debug.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1995-1993 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This file contains definitions for kernel debugging, + * which are compiled in on the DEBUG symbol. + */ +#ifndef _FLUX_DEBUG_H_ +#define _FLUX_DEBUG_H_ + +#include + +#ifdef DEBUG + + +/*** Permanent code annotation macros ***/ + +/* Get the assert() macro from the minimal C library's assert.h. + Sanity check: make sure NDEBUG isn't also defined... */ +#ifdef NDEBUG +#error Inconsistency: DEBUG and NDEBUG both defined! +#endif +#include + +#define otsan() panic("%s:%d: off the straight and narrow!", __FILE__, __LINE__) + +#define do_debug(stmt) stmt + +/* XXX not sure how useful this is; just delete? */ +#define struct_id_decl unsigned struct_id; +#define struct_id_init(p,id) ((p)->struct_id = (id)) +#define struct_id_denit(p) ((p)->struct_id = 0) +#define struct_id_verify(p,id) \ + ({ if ((p)->struct_id != (id)) \ + panic("%s:%d: "#p" (%08x) struct_id should be "#id" (%08x), is %08x\n", \ + __FILE__, __LINE__, (p), (id), (p->struct_id)); \ + }) + + +/*** Macros to provide temporary debugging scaffolding ***/ + +extern void dump_stack_trace(void); /* defined in libc//stack_trace.c */ + +#include +#define here() printf("@ %s:%d\n", __FILE__, __LINE__) + +#define debugmsg(args) \ + ( printf("%s:%d: ", __FILE__, __LINE__), printf args, printf("\n") ) + +#else /* !DEBUG */ + +/* Make sure the assert macro compiles to nothing. + XXX What about if assert.h has already been included? */ +#ifndef NDEBUG +#define NDEBUG +#endif +#include + +#define otsan() +#define do_debug(stmt) + +#define struct_id_decl +#define struct_id_init(p,id) +#define struct_id_denit(p) +#define struct_id_verify(p,id) + +#endif /* !DEBUG */ + +#include +__FLUX_BEGIN_DECLS +extern void panic(const char *format, ...) __FLUX_NORETURN; +__FLUX_END_DECLS + +#endif /* _FLUX_DEBUG_H_ */ diff --git a/apps/rmgr/include/flux/depend b/apps/rmgr/include/flux/depend new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/apps/rmgr/include/flux/depend @@ -0,0 +1 @@ +# diff --git a/apps/rmgr/include/flux/diskpart/dec.h b/apps/rmgr/include/flux/diskpart/dec.h new file mode 100644 index 0000000..ab8f869 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/dec.h @@ -0,0 +1,84 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_DISKPART_DEC_H_ +#define _FLUX_DISKPART_DEC_H_ + +/* + * Definition of the DEC disk label, + * which is located (you guessed it) + * at the end of the 4.3 superblock. + */ + +struct dec_partition_info { + unsigned int n_sectors; /* how big the partition is */ + unsigned int offset; /* sector no. of start of part. */ +}; + +typedef struct { + int magic; +# define DEC_LABEL_MAGIC 0x032957 + int in_use; + struct dec_partition_info partitions[8]; +} dec_label_t; + +/* + * Physical location on disk. + * This is independent of the filesystem we use, + * although of course we'll be in trouble if we + * screwup the 4.3 SBLOCK.. + */ + +#define DEC_LABEL_BYTE_OFFSET ((2*8192)-sizeof(dec_label_t)) + + +/* + * Definitions for the primary boot information + * This is common, cuz the prom knows it. + */ + +typedef struct { + int pad[2]; + unsigned int magic; +# define DEC_BOOT0_MAGIC 0x2757a + int mode; + unsigned int phys_base; + unsigned int virt_base; + unsigned int n_sectors; + unsigned int start_sector; +} dec_boot0_t; + +typedef struct { + dec_boot0_t vax_boot; + /* BSD label still fits in pad */ + char pad[0x1e0-sizeof(dec_boot0_t)]; + unsigned long block_count; + unsigned long starting_lbn; + unsigned long flags; + unsigned long checksum; /* add cmpl-2 all but here */ +} alpha_boot0_t; + +#endif /* _FLUX_DISKPART_DEC_H_ */ diff --git a/apps/rmgr/include/flux/diskpart/disklabel.h b/apps/rmgr/include/flux/diskpart/disklabel.h new file mode 100644 index 0000000..dfb2e29 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/disklabel.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1987, 1988, 1993 + * The Regents of the University of California. + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)disklabel.h 8.1 (Berkeley) 6/2/93 + */ + +/* + * This file was modified from the FreeBSD 2.1 version for use in the + * University of Utah's OS-Toolkit by Kevin T. Van Maren + */ + +/* + * Each disk has a label which includes information about the hardware + * disk geometry, filesystem partitions, and drive specific information. + * The label is in block 0 or 1, possibly offset from the beginning + * to leave room for a bootstrap, etc. + */ + +/* XXX these should be defined per controller (or drive) elsewhere, not here! */ +#if defined(i386) || defined(HPOSF) +#define LABELSECTOR 1 /* sector containing label */ +#define LABELOFFSET 0 /* offset of label in sector */ +#endif + +#ifndef LABELSECTOR +#define LABELSECTOR 0 /* sector containing label */ +#endif + +#ifndef LABELOFFSET +#define LABELOFFSET 64 /* offset of label in sector */ +#endif + +#define DISKMAGIC ((u_long) 0x82564557) /* The disk magic number */ +#ifndef MAXPARTITIONS +#define MAXPARTITIONS 8 +#endif + + +#ifndef LOCORE +struct disklabel { + u_long d_magic; /* the magic number */ + short d_type; /* drive type */ + short d_subtype; /* controller/d_type specific */ + char d_typename[16]; /* type name, e.g. "eagle" */ + /* + * d_packname contains the pack identifier and is returned when + * the disklabel is read off the disk or in-core copy. + * d_boot0 and d_boot1 are the (optional) names of the + * primary (block 0) and secondary (block 1-15) bootstraps + * as found in /usr/mdec. These are returned when using + * getdiskbyname(3) to retrieve the values from /etc/disktab. + */ +#if defined(KERNEL) || defined(STANDALONE) + char d_packname[16]; /* pack identifier */ +#else + union { + char un_d_packname[16]; /* pack identifier */ + struct { + char *un_d_boot0; /* primary bootstrap name */ + char *un_d_boot1; /* secondary bootstrap name */ + } un_b; + } d_un; +#define d_packname d_un.un_d_packname +#define d_boot0 d_un.un_b.un_d_boot0 +#define d_boot1 d_un.un_b.un_d_boot1 +#endif /* ! KERNEL or STANDALONE */ + /* disk geometry: */ + u_long d_secsize; /* # of bytes per sector */ + u_long d_nsectors; /* # of data sectors per track */ + u_long d_ntracks; /* # of tracks per cylinder */ + u_long d_ncylinders; /* # of data cylinders per unit */ + u_long d_secpercyl; /* # of data sectors per cylinder */ + u_long d_secperunit; /* # of data sectors per unit */ + /* + * Spares (bad sector replacements) below + * are not counted in d_nsectors or d_secpercyl. + * Spare sectors are assumed to be physical sectors + * which occupy space at the end of each track and/or cylinder. + */ + u_short d_sparespertrack; /* # of spare sectors per track */ + u_short d_sparespercyl; /* # of spare sectors per cylinder */ + /* + * Alternate cylinders include maintenance, replacement, + * configuration description areas, etc. + */ + u_long d_acylinders; /* # of alt. cylinders per unit */ + + /* hardware characteristics: */ + /* + * d_interleave, d_trackskew and d_cylskew describe perturbations + * in the media format used to compensate for a slow controller. + * Interleave is physical sector interleave, set up by the formatter + * or controller when formatting. When interleaving is in use, + * logically adjacent sectors are not physically contiguous, + * but instead are separated by some number of sectors. + * It is specified as the ratio of physical sectors traversed + * per logical sector. Thus an interleave of 1:1 implies contiguous + * layout, while 2:1 implies that logical sector 0 is separated + * by one sector from logical sector 1. + * d_trackskew is the offset of sector 0 on track N + * relative to sector 0 on track N-1 on the same cylinder. + * Finally, d_cylskew is the offset of sector 0 on cylinder N + * relative to sector 0 on cylinder N-1. + */ + u_short d_rpm; /* rotational speed */ + u_short d_interleave; /* hardware sector interleave */ + u_short d_trackskew; /* sector 0 skew, per track */ + u_short d_cylskew; /* sector 0 skew, per cylinder */ + u_long d_headswitch; /* head switch time, usec */ + u_long d_trkseek; /* track-to-track seek, usec */ + u_long d_flags; /* generic flags */ +#define NDDATA 5 + u_long d_drivedata[NDDATA]; /* drive-type specific information */ +#define NSPARE 5 + u_long d_spare[NSPARE]; /* reserved for future use */ + u_long d_magic2; /* the magic number (again) */ + u_short d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + u_short d_npartitions; /* number of partitions in following */ + u_long d_bbsize; /* size of boot area at sn0, bytes */ + u_long d_sbsize; /* max size of fs superblock, bytes */ + struct partition { /* the partition table */ + u_long p_size; /* number of sectors in partition */ + u_long p_offset; /* starting sector */ + u_long p_fsize; /* filesystem basic fragment size */ + u_char p_fstype; /* filesystem type, see below */ + u_char p_frag; /* filesystem fragments per block */ + union { + u_short cpg; /* UFS: FS cylinders per group */ + u_short sgs; /* LFS: FS segment shift */ + } __partition_u1; +#define p_cpg __partition_u1.cpg +#define p_sgs __partition_u1.sgs + } d_partitions[MAXPARTITIONS]; /* actually may be more */ +}; +#else /* LOCORE */ + /* + * offsets for asm boot files. + */ + .set d_secsize,40 + .set d_nsectors,44 + .set d_ntracks,48 + .set d_ncylinders,52 + .set d_secpercyl,56 + .set d_secperunit,60 + .set d_end_,276 /* size of disk label */ +#endif /* LOCORE */ + +/* d_type values: */ +#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */ +#define DTYPE_MSCP 2 /* MSCP */ +#define DTYPE_DEC 3 /* other DEC (rk, rl) */ +#define DTYPE_SCSI 4 /* SCSI */ +#define DTYPE_ESDI 5 /* ESDI interface */ +#define DTYPE_ST506 6 /* ST506 etc. */ +#define DTYPE_HPIB 7 /* CS/80 on HP-IB */ +#define DTYPE_HPFL 8 /* HP Fiber-link */ +#define DTYPE_FLOPPY 10 /* floppy */ + +#ifdef DKTYPENAMES +static char *dktypenames[] = { + "unknown", + "SMD", + "MSCP", + "old DEC", + "SCSI", + "ESDI", + "ST506", + "HP-IB", + "HP-FL", + "type 9", + "floppy", + 0 +}; +#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1) +#endif + +/* + * Filesystem type and version. + * Used to interpret other filesystem-specific + * per-partition information. + */ +#define FS_UNUSED 0 /* unused */ +#define FS_SWAP 1 /* swap */ +#define FS_V6 2 /* Sixth Edition */ +#define FS_V7 3 /* Seventh Edition */ +#define FS_SYSV 4 /* System V */ +#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ +#define FS_V8 6 /* Eighth Edition, 4K blocks */ +#define FS_BSDFFS 7 /* 4.2BSD fast file system */ +#define FS_MSDOS 8 /* MSDOS file system */ +#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */ +#define FS_OTHER 10 /* in use, but unknown/unsupported */ +#define FS_HPFS 11 /* OS/2 high-performance file system */ +#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ +#define FS_BOOT 13 /* partition contains bootstrap */ + +#ifdef DKTYPENAMES +static char *fstypenames[] = { + "unused", + "swap", + "Version 6", + "Version 7", + "System V", + "4.1BSD", + "Eighth Edition", + "4.2BSD", + "MSDOS", + "4.4LFS", + "unknown", + "HPFS", + "ISO9660", + "boot", + 0 +}; +#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1) +#endif diff --git a/apps/rmgr/include/flux/diskpart/diskpart.h b/apps/rmgr/include/flux/diskpart/diskpart.h new file mode 100644 index 0000000..14d5015 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/diskpart.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_DISKLABEL_H_ +#define _FLUX_DISKLABEL_H_ + +#include + +#define SECTOR_SIZE 512 + +#define LBLLOC 1 /* label block for xxxbsd */ + + +/* These are the partition types that can contain sub-partitions */ +/* enum types... */ +#define DISKPART_NONE 0 /* smallest piece flag !?! */ +#define DISKPART_DOS 1 +#define DISKPART_BSD 2 +#define DISKPART_VTOC 3 +#define DISKPART_OMRON 4 +#define DISKPART_DEC 5 /* VAX disks? */ +#define DISKPART_UNKNOWN 99 + + + +/* + * This is the basic partition structure. an array of these is + * filled, with element 0 being the whole drive, element 1-n being the + * n top-level partitions, followed by 0+ groups of 1+ sub-partitions. + */ +typedef struct diskpart { + short type; /* DISKPART_xxx (see above) */ + short fsys; /* file system (if known) */ + int nsubs; /* number of sub-slices */ + struct diskpart *subs; /* pointer to the sub-partitions */ + int start; /* relative to the start of the DRIVE */ + int size; /* # sectors in this piece */ +} diskpart_t; + + +/* MOVE THIS TO A PRIVATE HEADER FILE */ +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + +__FLUX_BEGIN_DECLS +/* + * diskpart_check_read is used to provide an immediate return if + * bottom_read_fun encounters an unrecoverable error. If an immediate + * return is not desired, the data returned should be bzero'ed by + * bottom_read_fun, and 0 returned. This may be the case, for + * example, if the sector number is past the end of the disk. + * bottom_read_fun can return errors through gobal variables as well. + */ +#define diskpart_check_read(w) { if (w) return(w); } + +/* + * + */ +void diskpart_fill_entry(struct diskpart *array, int start, int size, + struct diskpart *subs, int nsubs, short type, short fsys); + +/* + * This prints an entry pointed to by array, shifted right by level, + * with the part name. Any sub-partitions it contains are + * automatically printed at level+1. If part is a letter, the + * sub-parts are numbered, else the subparts are lettered. + */ +void diskpart_dump(struct diskpart *array, int level, char part); + +/* + * This is the main function for getting partition information for a + * drive. driver_info is passed to the bottom_read_fun, so the + * structure is defined by the user. bottom_read_fun takes three + * parameters (driver_info, int sector_number, char *buffer). It + * should read the sector number and place the data into the buffer. + * The other parameters to diskpart_get_partition are a pointer to the + * storage for the partition information, an integer specifying the + * number of entries that may be used (array size), and an integer + * specifying the size of the disk, which is used for the whole-disk + * partition. + */ +int diskpart_get_partition(void *driver_info, int (*bottom_read_fun)(), + struct diskpart *array, int array_size, + int disk_size); + +/* + * These functions are normally called by diskpart_get_partition. + * However, they can be called by the user if it is important to check + * is a particular type of partitioning scheme is being used. + */ +int diskpart_get_disklabel(struct diskpart *array, char *buff, int start, + void *driver_info, int (*bottom_read_fun)(), + int max_part); + +int diskpart_get_dos(struct diskpart *array, char *buff, int start, + void *driver_info, int (*bottom_read_fun)(), + int max_part); + +int diskpart_get_vtoc(struct diskpart *array, char *buff, int start, + void *driver_info, int (*bottom_read_fun)(), + int max_part); + +/* + * These functions are not provided. These are merely placeholders in + * case support is added. + */ +int diskpart_get_dec(struct diskpart *array, char *buff, int start, + void *driver_info, int (*bottom_read_fun)(), + int max_part); + +int diskpart_get_omron(struct diskpart *array, char *buff, int start, + void *driver_info, int (*bottom_read_fun)(), + int max_part); + +/* + * These are the sample lookup routines. + * They get called with a pointer to the first struct diskpart entry + * and information indicating which partition should be returned. + * They return a pointer to the partition specified, NULL if invallid. + */ +struct diskpart *diskpart_lookup_bsd_compat(struct diskpart *array, + short slice, short part); + +struct diskpart *diskpart_lookup_bsd_string(struct diskpart *array, + char *name); +__FLUX_END_DECLS + +#endif /* _FLUX_DISKLABEL_H_ */ + + + diff --git a/apps/rmgr/include/flux/diskpart/omron.h b/apps/rmgr/include/flux/diskpart/omron.h new file mode 100644 index 0000000..7aed0e1 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/omron.h @@ -0,0 +1,71 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Definition of the Omron disk label, + * which is located at sector 0. It + * _is_ sector 0, actually. + */ + +#ifndef _FLUX_DISKLABEL_OMRON_H_ +#define _FLUX_DISKLABEL_OMRON_H_ + +struct omron_partition_info { + unsigned long offset; + unsigned long n_sectors; +}; + +typedef struct { + char packname[128]; /* in ascii */ + + char pad[512-(128+8*8+11*2+4)]; + + unsigned short badchk; /* checksum of bad track */ + unsigned long maxblk; /* # of total logical blocks */ + unsigned short dtype; /* disk drive type */ + unsigned short ndisk; /* # of disk drives */ + unsigned short ncyl; /* # of data cylinders */ + unsigned short acyl; /* # of alternate cylinders */ + unsigned short nhead; /* # of heads in this partition */ + unsigned short nsect; /* # of 512 byte sectors per track */ + unsigned short bhead; /* identifies proper label locations */ + unsigned short ppart; /* physical partition # */ + struct omron_partition_info + partitions[8]; + + unsigned short magic; /* identifies this label format */ +# define OMRON_LABEL_MAGIC 0xdabe + + unsigned short cksum; /* xor checksum of sector */ + +} omron_label_t; + +/* + * Physical location on disk. + */ + +#define OMRON_LABEL_BYTE_OFFSET 0 + +#endif /* _FLUX_DISKLABEL_OMRON_H_ */ diff --git a/apps/rmgr/include/flux/diskpart/pcbios.h b/apps/rmgr/include/flux/diskpart/pcbios.h new file mode 100644 index 0000000..e0346b8 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/pcbios.h @@ -0,0 +1,105 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Definition of the i386AT disk label, which lives inside sector 0. + * This is the info the BIOS knows about, which we use for bootstrapping. + * It is common across all disks known to BIOS. + */ + +#ifndef _FLUX_DISKLABEL_PCBIOS_H_ +#define _FLUX_DISKLABEL_PCBIOS_H_ + +struct bios_partition_info { + + unsigned char bootid; /* bootable or not */ +# define BIOS_BOOTABLE 128 + + unsigned char beghead;/* beginning head, sector, cylinder */ + unsigned char begsect;/* begcyl is a 10-bit number. High 2 bits */ + unsigned char begcyl; /* are in begsect. */ + + unsigned char systid; /* filesystem type */ +# define UNIXOS 99 /* GNU HURD? */ +# define BSDOS 165 /* 386BSD */ +# define LINUXSWAP 130 +# define LINUXOS 131 +# define DOS_EXTENDED 05 /* container for logical partitions */ + +# define HPFS 07 /* OS/2 Native */ +# define OS_2_BOOT 10 /* OS/2 Boot Manager */ +# define DOS_12 01 /* 12 bit FAT */ +# define DOS_16_SMALL 04 /* < 32MB */ +# define DOS_16 06 /* >= 32MB */ + +/* + *These numbers can't be trusted because of newer, larger drives +*/ + unsigned char endhead;/* ending head, sector, cylinder */ + unsigned char endsect;/* endcyl is a 10-bit number. High 2 bits */ + unsigned char endcyl; /* are in endsect. */ + +/* + * The offset and n_sectors fields should be correct, regardless of the + * drive size, and should be the numbers used. + */ + unsigned long offset; + unsigned long n_sectors; +}; + +typedef struct { +/* struct bios_partition_info bogus compiler alignes wrong + partitions[4]; +*/ + char partitions[4*sizeof(struct bios_partition_info)]; + unsigned short magic; +# define BIOS_LABEL_MAGIC 0xaa55 +} bios_label_t; + +/* + * Physical location on disk. + */ + +#define BIOS_LABEL_BYTE_OFFSET 446 + +/* + * Definitions for the primary boot information + * This _is_ block 0 + */ + +#define BIOS_BOOT0_SIZE BIOS_LABEL_BYTE_OFFSET + +typedef struct { + char boot0[BIOS_BOOT0_SIZE]; /* boot code */ +/* bios_label_t label; bogus compiler alignes wrong */ + char label[sizeof(bios_label_t)]; +} bios_boot0_t; + + +#endif /* _FLUX_DISKLABEL_PCBIOS_H_ */ diff --git a/apps/rmgr/include/flux/diskpart/vtoc.h b/apps/rmgr/include/flux/diskpart/vtoc.h new file mode 100644 index 0000000..5400555 --- /dev/null +++ b/apps/rmgr/include/flux/diskpart/vtoc.h @@ -0,0 +1,74 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * This file contains the definitions for the VTOC label. + */ + +#ifndef _FLUX_DISKLABEL_VTOC_H_ +#define _FLUX_DISKLABEL_VTOC_H_ + +#define PDLOCATION 29 /* VTOC sector */ + +#define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */ + +#define HDPDLOC 29 /* location of pdinfo/vtoc */ + + +/* Here are the VTOC definitions */ +#define V_NUMPAR 16 /* maximum number of partitions */ + +struct localpartition { + u_int p_flag; /*permision flags*/ + long p_start; /*physical start sector no of partition*/ + long p_size; /*# of physical sectors in partition*/ +}; +typedef struct localpartition localpartition_t; + + +struct evtoc { + u_int fill0[6]; + u_int cyls; /*number of cylinders per drive*/ + u_int tracks; /*number tracks per cylinder*/ + u_int sectors; /*number sectors per track*/ + u_int fill1[13]; + u_int version; /*layout version*/ + u_int alt_ptr; /*byte offset of alternates table*/ + u_short alt_len; /*byte length of alternates table*/ + u_int sanity; /*to verify vtoc sanity*/ + u_int xcyls; /*number of cylinders per drive*/ + u_int xtracks; /*number tracks per cylinder*/ + u_int xsectors; /*number sectors per track*/ + u_short nparts; /*number of partitions*/ + u_short fill2; /*pad for 286 compiler*/ + char label[40]; + struct localpartition part[V_NUMPAR];/*partition headers*/ + char fill[512-352]; +}; + + + +#endif /* _FLUX_DISKLABEL_VTOC_H_ */ diff --git a/apps/rmgr/include/flux/exec/a.out.h b/apps/rmgr/include/flux/exec/a.out.h new file mode 100644 index 0000000..1357166 --- /dev/null +++ b/apps/rmgr/include/flux/exec/a.out.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _MACH_A_OUT_ +#define _MACH_A_OUT_ + +#include + +struct exec +{ + unsigned long a_magic; /* magic number */ + unsigned long a_text; /* size of text segment */ + unsigned long a_data; /* size of initialized data */ + unsigned long a_bss; /* size of uninitialized data */ + unsigned long a_syms; /* size of symbol table */ + unsigned long a_entry; /* entry point */ + unsigned long a_trsize; /* size of text relocation */ + unsigned long a_drsize; /* size of data relocation */ +}; + +struct nlist { + long n_strx; + unsigned char n_type; + char n_other; + short n_desc; + unsigned long n_value; +}; + +#define OMAGIC 0407 +#define NMAGIC 0410 +#define ZMAGIC 0413 +#define QMAGIC 0314 + +#define N_GETMAGIC(ex) \ + ( (ex).a_magic & 0xffff ) +#define N_GETMAGIC_NET(ex) \ + (ntohl((ex).a_magic) & 0xffff) + +/* Valid magic number check. */ +#define N_BADMAG(ex) \ + (N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \ + N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC && \ + N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \ + N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC) + +/* We don't provide any N_???OFF macros here + because they vary too much between the different a.out variants; + it's practically impossible to create one set of macros + that works for UX, FreeBSD, NetBSD, Linux, etc. */ + +#endif /* _MACH_A_OUT_ */ diff --git a/apps/rmgr/include/flux/exec/elf.h b/apps/rmgr/include/flux/exec/elf.h new file mode 100644 index 0000000..61209bf --- /dev/null +++ b/apps/rmgr/include/flux/exec/elf.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990 + * Open Software Foundation, Inc. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation, and that the name of ("OSF") or Open Software + * Foundation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY + * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + * + */ +/* + * OSF Research Institute MK6.1 (unencumbered) 1/31/1995 + */ +#ifndef _FLUX_EXEC_ELF_H_ +#define _FLUX_EXEC_ELF_H_ + +#include + +/* ELF Header - figure 4-3, page 4-4 */ + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + + +/* e_ident[] identification indexes - figure 4-4, page 4-7 */ + +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_PAD 7 + +/* magic number - pg 4-8 */ + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +/* file class or capacity - page 4-8 */ + +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +/* date encoding - page 4-9 */ + +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +/* object file types - page 4-5 */ + +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 + +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* architecture - page 4-5 */ + +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_860 7 +#define EM_MIPS 8 +#define EM_MIPS_RS4_BE 10 +#define EM_SPARC64 11 +#define EM_PARISC 15 +#define EM_PPC 20 + +/* version - page 4-6 */ + +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* special section indexes - page 4-11, figure 4-7 */ + +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +/* section header - page 4-13, figure 4-8 */ + +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +/* section types - page 4-15, figure 4-9 */ + +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 + +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* section attribute flags - page 4-18, figure 4-11 */ + +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +/* symbol table - page 4-25, figure 4-15 */ +typedef struct +{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +/* symbol type and binding attributes - page 4-26 */ + +#define ELF32_ST_BIND(i) ((i) >> 4) +#define ELF32_ST_TYPE(i) ((i) & 0xf) +#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +/* symbol binding - page 4-26, figure 4-16 */ + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +/* symbol types - page 4-28, figure 4-17 */ + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + + +/* relocation entries - page 4-31, figure 4-19 */ + +typedef struct +{ + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct +{ + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Macros to split/combine relocation type and symbol page 4-32 */ + +#define ELF32_R_SYM(__i) ((__i)>>8) +#define ELF32_R_TYPE(__i) ((unsigned char) (__i)) +#define ELF32_R_INFO(__s, __t) (((__s)<<8) + (unsigned char) (__t)) + + +/* program header - page 5-2, figure 5-1 */ + +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +/* segment types - page 5-3, figure 5-2 */ + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 + +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* segment permissions - page 5-6 */ + +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 +#define PF_MASKPROC 0xf0000000 + + +/* dynamic structure - page 5-15, figure 5-9 */ + +typedef struct { + Elf32_Sword d_tag; + union { + Elf32_Word d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +/* Dynamic array tags - page 5-16, figure 5-10. */ + +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 + +/* + * Bootstrap doesn't need machine dependent extensions. + */ + +#endif /* _FLUX_EXEC_ELF_H_ */ diff --git a/apps/rmgr/include/flux/exec/exec.h b/apps/rmgr/include/flux/exec/exec.h new file mode 100644 index 0000000..ccd7a51 --- /dev/null +++ b/apps/rmgr/include/flux/exec/exec.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Public definitions for the generic executable interpreter library + * provided as part of the Flux OS toolkit. + */ +#ifndef _FLUX_EXEC_EXEC_H_ +#define _FLUX_EXEC_EXEC_H_ + +#include +#include + +/* XXX */ +typedef enum +{ + EXEC_ELF = 1, + EXEC_AOUT = 2, +} exec_format_t; + +typedef struct exec_info +{ + /* Format of executable loaded - see above. */ + exec_format_t format; + + /* Program entrypoint. */ + vm_offset_t entry; + + /* Initial data pointer - only some architectures use this. */ + vm_offset_t init_dp; + + /* (ELF) Address of interpreter string for loading shared libraries, + null if none. */ + vm_offset_t interp; + +} exec_info_t; + +typedef int exec_sectype_t; + +/* + * Flag definitions for section types (exec_sectype_t). + * Note that the EXEC_SECTYPE_PROT_MASK part of the section type + * uses the same values as the PROT_* values defined in flux/c/sys/mman.h, + * and it may be assumed that this will always be the case. + * These are also the same values used in Mach 3, and BSD, and Linux, and ... + */ +#define EXEC_SECTYPE_READ ((exec_sectype_t)0x000001) +#define EXEC_SECTYPE_WRITE ((exec_sectype_t)0x000002) +#define EXEC_SECTYPE_EXECUTE ((exec_sectype_t)0x000004) +#define EXEC_SECTYPE_PROT_MASK ((exec_sectype_t)0x000007) +#define EXEC_SECTYPE_ALLOC ((exec_sectype_t)0x000100) +#define EXEC_SECTYPE_LOAD ((exec_sectype_t)0x000200) +#define EXEC_SECTYPE_DEBUG ((exec_sectype_t)0x010000) +#define EXEC_SECTYPE_AOUT_SYMTAB ((exec_sectype_t)0x020000) +#define EXEC_SECTYPE_AOUT_STRTAB ((exec_sectype_t)0x040000) + +/* For use with printf's %b format. */ +#define EXEC_SECTYPE_FORMAT \ +"\20\1READ\2WRITE\3EXEC\11ALLOC\12LOAD\21DEBUG\22AOUT_SYMTAB\23AOUT_STRTAB" + +typedef int exec_read_func_t(void *handle, vm_offset_t file_ofs, + void *buf, vm_size_t size, + vm_size_t *out_actual); + +typedef int exec_read_exec_func_t(void *handle, + vm_offset_t file_ofs, vm_size_t file_size, + vm_offset_t mem_addr, vm_size_t mem_size, + exec_sectype_t section_type); + +/* + * Routines exported from libmach_exec.a + */ + +__FLUX_BEGIN_DECLS + +/* Generic function to interpret an executable "file" + and "load" it into "memory". + Doesn't really know about files, loading, or memory; + all file I/O and destination memory accesses + go through provided functions. + Thus, this is a very generic loading mechanism. + + The read() function is used to read metadata from the file + into the local address space. + + The read_exec() function is used to load the actual sections. + It is used for all kinds of sections - code, data, bss, debugging data. + The 'section_type' parameter specifies what type of section is being loaded. + + For code, data, and bss, the EXEC_SECTYPE_ALLOC flag will be set. + For code and data (i.e. stuff that's actually loaded from the file), + EXEC_SECTYPE_LOAD will also be set. + The EXEC_SECTYPE_PROT_MASK contains the intended access permissions + for the section. + 'file_size' may be less than 'mem_size'; + the remaining data must be zero-filled. + 'mem_size' is always greater than zero, but 'file_size' may be zero + (e.g. in the case of a bss section). + No two read_exec() calls for one executable + will load data into the same virtual memory page, + although they may load from arbitrary (possibly overlapping) file positions. + + For sections that aren't normally loaded into the process image + (e.g. debug sections), EXEC_SECTYPE_ALLOC isn't set, + but some other appropriate flag is set to indicate the type of section. + + The 'handle' is an opaque pointer which is simply passed on + to the read() and read_exec() functions. + + On return, the specified info structure is filled in + with information about the loaded executable. +*/ +int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, + void *handle, exec_info_t *out_info); + +__FLUX_END_DECLS + +/* + * Error codes + * XXX these values are a holdover from Mach 3, and probably should be changed. + */ + +#define EX_NOT_EXECUTABLE 6000 /* not a recognized executable format */ +#define EX_WRONG_ARCH 6001 /* valid executable, but wrong arch. */ +#define EX_CORRUPT 6002 /* recognized executable, but mangled */ +#define EX_BAD_LAYOUT 6003 /* something wrong with the memory or file image layout */ + + +#endif /* _FLUX_EXEC_EXEC_H_ */ diff --git a/apps/rmgr/include/flux/fdev.h b/apps/rmgr/include/flux/fdev.h new file mode 100644 index 0000000..dbc7c66 --- /dev/null +++ b/apps/rmgr/include/flux/fdev.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Device interface definitions. + */ + +#ifndef _FLUX_FDEV_H_ +#define _FLUX_FDEV_H_ + +#include +#include +#include + +/* + * Description of a device. + */ +struct fdev { + struct fdev_drv_ops *drv_ops; /* driver operations vector */ + void *data; /* opaque driver data */ +}; + +typedef struct fdev fdev_t; + +/* + * Buffer operations vector table. + * + * XXX: Unused at present. + */ +struct fdev_buf_vec { + int (*copyin)(void *src, vm_offset_t offset, void *dest, + unsigned count); + int (*copyout)(void *src, void *dest, vm_offset_t offset, + unsigned count); + int (*wire)(void *buf, unsigned size, vm_offset_t *page_list, + unsigned *amt_wired); + void (*unwire)(void *buf, vm_offset_t offset, unsigned size); +}; + +typedef struct bufvec fdev_buf_vec_t; + +/* + * Driver operations vector table. + */ +struct fdev_drv_ops { + void (*close)(fdev_t *dev); + int (*read)(fdev_t *dev, void *buf, fdev_buf_vec_t *bufvec, + vm_offset_t off, unsigned count, unsigned *amount_read); + int (*write)(fdev_t *dev, void *buf, + fdev_buf_vec_t *bufvec, vm_offset_t off, + unsigned count, unsigned *amount_written); +}; + +/* + * Flags to fdev_drv_open. + */ +#define FDEV_OPEN_READ 0x01 /* open device for reading */ +#define FDEV_OPEN_WRITE 0x02 /* open device for writing */ +#define FDEV_OPEN_ALL (FDEV_OPEN_WRITE|FDEV_OPEN_READ) + +/* + * Error codes. + */ +#define FDEV_NO_SUCH_DEVICE 1 +#define FDEV_BAD_OPERATION 2 +#define FDEV_INVALID_PARAMETER 3 +#define FDEV_IO_ERROR 4 +#define FDEV_MEMORY_SHORTAGE 5 + +/* + * Memory allocation flags. + */ +#define FDEV_AUTO_SIZE 0x01 +#define FDEV_PHYS_WIRED 0x02 +#define FDEV_VIRT_EQ_PHYS 0x04 +#define FDEV_PHYS_CONTIG 0x08 +#define FDEV_NONBLOCKING 0x10 +#define FDEV_ISA_DMA_MEMORY 0x20 + +/* + * Prototypes. + */ + +__FLUX_BEGIN_DECLS + +/* + * Initialization. + */ +void fdev_init(void); + +/* + * Device interface. + */ +int fdev_drv_open(const char *name, unsigned flags, fdev_t **dev); + +#define fdev_drv_close(dev) \ + ((dev)->drv_ops->close)(dev) +#define fdev_drv_read(dev, buf, bufvec, off, count, amount_read) \ + ((dev)->drv_ops->read)(dev, buf, bufvec, off, count, amount_read) +#define fdev_drv_write(dev, buf, bufvec, off, count, amount_written) \ + ((dev)->drv_ops->write)(dev, buf, bufvec, off, count, amount_written) + +/* + * Buffer manipulation. + */ + +#define fdev_buf_copyin(src, bufvec, offset, dest, count) \ + ((bufvec)->copyin)(src, offset, dest, count) +#define fdev_buf_copyout(src, dest, bufvec, offset, count) \ + ((bufvec)->copyout)(src, dest, offset, count) +#define fdev_buf_wire(buf, bufvec, size, page_list, amt_wired) \ + ((bufvec)->wire)(buf, size, page_list, amt_wired) +#define fdev_buf_unwire(buf, bufvec, offset, size) \ + ((bufvec)->unwire)(buf, offset, size) + +int fdev_default_buf_copyin(void *buf, vm_offset_t off, void *dest, + unsigned amt); +int fdev_default_buf_copyout(void *src, void *buf, vm_offset_t off, + unsigned amt); +int fdev_default_buf_wire(void *buf, unsigned size, vm_offset_t *page_list, + unsigned *amt_wired); +void fdev_default_buf_unwire(void *buf, vm_offset_t offset, unsigned size); + + +/* + * Interrupts. + */ +int fdev_intr_alloc(unsigned irq, void (*handler)(void *), + void *data, int flags); +void fdev_intr_free(unsigned irq); +void fdev_intr_disable(void); /* XXX: not used at present */ +void fdev_intr_enable(void); /* XXX: not used at present */ + +/* + * Memory allocation/deallocation. + */ +void *fdev_mem_alloc(unsigned size, int flags, unsigned align); +void fdev_mem_free(void *p, int flags, unsigned size); + +/* + * Memory mapping. + */ +int fdev_map_phys_mem(vm_offset_t pa, vm_size_t size, void **addr, int flags); + +/* + * Scheduler support. + */ +void fdev_event_block(void *event); +void fdev_event_unblock(void *event); + +/* + * Software interrupt support. + */ +void fdev_register_soft_handler(void (*func)(void)); + +/* + * Timer interrupt support. + */ +void fdev_register_timer_handler(void (*func)(void), int freq); +__FLUX_END_DECLS + +#endif /* _FLUX_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/fdev/blk.h b/apps/rmgr/include/flux/fdev/blk.h new file mode 100644 index 0000000..977a008 --- /dev/null +++ b/apps/rmgr/include/flux/fdev/blk.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions specific to block devices. + */ +#ifndef _FLUX_FDEV_BLK_H_ +#define _FLUX_FDEV_BLK_H_ + +struct fdev_blk +{ + fdev_t fdev; + + unsigned char type; + unsigned char flags; + unsigned blksize; + + fdev_error_t (*read)(fdev_t *dev, void *buf, fdev_buf_vect_t *bufvec, + fdev_off_t offset, unsigned count, + unsigned *out_actual); + fdev_error_t (*write)(fdev_t *dev, void *buf, fdev_buf_vect_t *bufvec, + fdev_off_t offset, unsigned count, + unsigned *out_actual); +}; +typedef struct fdev_blk fdev_blk_t; + +#define fdev_blk_read(dev, cmd, buf, bufvec) \ + ((dev)->read((dev), (cmd), (buf), (bufvec))) + +#define fdev_blk_write(dev, cmd, buf, bufvec) \ + ((dev)->write((dev), (cmd), (buf), (bufvec))) + +/* Specific block device types */ +#define FDEV_BLK_DISK 0x01 +#define FDEV_BLK_FLOPPY 0x02 +#define FDEV_BLK_CDROM 0x03 + +/* Flags specific to block devices */ +#define FDEV_BLKF_REMOVABLE 0x01 /* Removable media */ +#define FDEV_BLKF_REMOVE_NOTIFY 0x02 /* Removal detection supported */ + +#endif /* _FLUX_FDEV_BLK_H_ */ diff --git a/apps/rmgr/include/flux/fdev/bus.h b/apps/rmgr/include/flux/fdev/bus.h new file mode 100644 index 0000000..e963270 --- /dev/null +++ b/apps/rmgr/include/flux/fdev/bus.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Flux device driver interface definitions. + */ +#ifndef _FLUX_FDEV_BUS_H_ +#define _FLUX_FDEV_BUS_H_ + +struct fdev_bus +{ + fdev_t fdev; + + unsigned char type; +}; +typedef struct fdev_bus fdev_bus_t; + +/* Specific well-known bus device types */ +#define FDEV_BUS_ISA 0x01 +#define FDEV_BUS_EISA 0x02 +#define FDEV_BUS_PCI 0x03 +#define FDEV_BUS_SCSI 0x04 + +#endif /* _FLUX_FDEV_BUS_H_ */ diff --git a/apps/rmgr/include/flux/fdev/char.h b/apps/rmgr/include/flux/fdev/char.h new file mode 100644 index 0000000..26ec478 --- /dev/null +++ b/apps/rmgr/include/flux/fdev/char.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions specific to character devices. + */ +#ifndef _FLUX_FDEV_CHAR_H_ +#define _FLUX_FDEV_CHAR_H_ + +#include +#include + +struct fdev_char +{ + fdev_t fdev; + + unsigned char type; + + fdev_error_t (*write)(fdev_t *dev, void *buf, fdev_buf_vect_t *bufvec); +}; +typedef struct fdev_char fdev_char_t; + +__FLUX_BEGIN_DECLS +/* + * Character drivers call this OS-supplied function + * when one or more characters have been received. + */ +void fdev_char_recv(fdev_char_t *fdev, char *data, unsigned size); +__FLUX_END_DECLS + +/* Specific character device types */ +#define FDEV_CHAR_SERIAL 0x01 /* RS-232 serial port */ +#define FDEV_CHAR_PARALLEL 0x02 /* Centronics parallel port */ +#define FDEV_CHAR_KEYBOARD 0x03 +#define FDEV_CHAR_MOUSE 0x04 +#define FDEV_CHAR_DISPLAY 0x05 + +#endif /* _FLUX_FDEV_CHAR_H_ */ diff --git a/apps/rmgr/include/flux/fdev/error.h b/apps/rmgr/include/flux/fdev/error.h new file mode 100644 index 0000000..0ea2abf --- /dev/null +++ b/apps/rmgr/include/flux/fdev/error.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Standard error codes returned by device drivers + * in the Flux device driver framework. + */ +#ifndef _FLUX_FDEV_ERROR_H_ +#define _FLUX_FDEV_ERROR_H_ + +typedef int fdev_error_t; + +/* + * Error codes. + */ +#define FDEV_NO_SUCH_DEVICE 1 +#define FDEV_BAD_OPERATION 2 +#define FDEV_INVALID_PARAMETER 3 +#define FDEV_IO_ERROR 4 +#define FDEV_MEMORY_SHORTAGE 5 + +#endif /* _FLUX_FDEV_ERROR_H_ */ diff --git a/apps/rmgr/include/flux/fdev/fdev.h b/apps/rmgr/include/flux/fdev/fdev.h new file mode 100644 index 0000000..7a51592 --- /dev/null +++ b/apps/rmgr/include/flux/fdev/fdev.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Flux device driver interface definitions. + */ +#ifndef _FLUX_FDEV_FDEV_H_ +#define _FLUX_FDEV_FDEV_H_ + +#include + +struct fdev +{ + fdev_set_t *fdev_set; + + unsigned char devclass; /* General device class; see below */ + const char *name; /* Short device type identifier */ + const char *description; /* Longer description of device */ + const char *vendor; /* Vendor name, if available */ + const char *model; /* Specific hardware model */ + const char *version; /* Origin and version of driver */ + + fdev_error_t (*ioctl)(fdev_t *dev, int cmd, + void *buf, fdev_buf_vect_t *bufvec); +}; +typedef struct fdev fdev_t; + +#define fdev_ioctl(dev, cmd, buf, bufvec) \ + ((dev)->ioctl((dev), (cmd), (buf), (bufvec))) + +/* Basic device classes */ +#define FDEV_CLASS_BUS 0x01 /* Interfaces to other devices */ +#define FDEV_CLASS_BLOCK 0x02 /* Random-access storage devices */ +#define FDEV_CLASS_SEQ 0x03 /* Sequential storage devices (tape) */ +#define FDEV_CLASS_CHAR 0x04 /* Character devices (ser, par) */ +#define FDEV_CLASS_NET 0x05 /* Network interface devices */ + + +/* + * Memory allocation/deallocation. + */ +typedef unsigned fdev_memflags_t; + +__FLUX_BEGIN_DECLS +void *fdev_mem_alloc(vm_size_t size, fdev_memflags_t flags, unsigned align); +void fdev_mem_free(void *block, fdev_memflags_t flags, vm_size_t size); +vm_offset_t fdev_mem_get_phys(void *block, fdev_memflags_t flags, + vm_size_t size); +__FLUX_END_DECLS + +#define FDEV_AUTO_SIZE 0x01 +#define FDEV_PHYS_WIRED 0x02 +#define FDEV_VIRT_EQ_PHYS 0x04 +#define FDEV_PHYS_CONTIG 0x08 +#define FDEV_NONBLOCKING 0x10 +#define FDEV_ISA_DMA_MEMORY 0x20 + +/* + * Buffer management. + */ +struct fdev_buf_vec { + int (*copyin)(void *src, vm_offset_t offset, void *dest, + vm_size_t size); + int (*copyout)(void *src, void *dest, vm_offset_t offset, + vm_size_t size); + int (*wire)(void *buf, unsigned size, vm_offset_t *page_list, + unsigned *amt_wired); + void (*unwire)(void *buf, vm_offset_t offset, vm_size_t size); + int (*map)(void *buf, void **kaddr, vm_size_t size); +}; + +#define fdev_buf_copyin(src, bufvec, offset, dest, count) \ + ((bufvec)->copyin)(src, offset, dest, count) +#define fdev_buf_copyout(src, dest, bufvec, offset, count) \ + ((bufvec)->copyout)(src, dest, offset, count) +#define fdev_buf_wire(buf, bufvec, size, page_list, amt_wired) \ + ((bufvec)->wire)(buf, size, page_list, amt_wired) +#define fdev_buf_unwire(buf, bufvec, offset, size) \ + ((bufvec)->unwire)(buf, offset, size) +#define fdev_buf_map(buf, bufvec, kaddr, size) \ + ((bufvec)->map)(buf, kaddr, size) + +__FLUX_BEGIN_DECLS +/* XXX encapsulate these in a 'fdev_bufvec_lmm' or somesuch. */ +int fdev_default_buf_copyin(void *buf, vm_offset_t off, void *dest, + unsigned amt); +int fdev_default_buf_copyout(void *src, void *buf, vm_offset_t off, + unsigned amt); +int fdev_default_buf_wire(void *buf, unsigned size, vm_offset_t *page_list, + unsigned *amt_wired); +void fdev_default_buf_unwire(void *buf, vm_offset_t offset, unsigned size); + +/* + * Interrupts. + */ +int fdev_intr_alloc(unsigned irq, void (*handler)(void *), + void *data, int flags); +void fdev_intr_free(unsigned irq); +void fdev_intr_disable(void); /* XXX: not used at present */ +void fdev_intr_enable(void); /* XXX: not used at present */ + +/* + * Memory mapping. + */ +int fdev_map_phys_mem(vm_offset_t pa, vm_size_t size, void **addr, int flags); + +/* + * Sleep/wakeup support. + */ +void fdev_sleep(void); +void fdev_wakeup(void); + +/* + * Software interrupt support. + * XXX get rid of this. + */ +void fdev_register_soft_handler(void (*func)(void)); + +/* + * Timer interrupt support. + */ +void fdev_register_timer_handler(void (*func)(void), int freq); +__FLUX_END_DECLS + +#endif /* _FLUX_FDEV_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/fdev/net.h b/apps/rmgr/include/flux/fdev/net.h new file mode 100644 index 0000000..415726b --- /dev/null +++ b/apps/rmgr/include/flux/fdev/net.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions specific to network devices. + */ +#ifndef _FLUX_FDEV_NET_H_ +#define _FLUX_FDEV_NET_H_ + +#include + +struct fdev_net +{ + fdev_t fdev; + + /* Network type; see below. */ + unsigned char type; + + fdev_error_t (*send)(fdev_t *dev, void *buf, fdev_buf_vect_t *bufvec, + vm_size_t pkt_size); +}; +typedef struct fdev_net fdev_net_t; + +#define fdev_net_send(dev, buf, bufvec, size) \ + ((dev)->send((dev), (buf), (bufvec), (size))) + +/* Specific network types */ +#define FDEV_NET_ETHERNET 0x01 + +__FLUX_BEGIN_DECLS +/* + * Network drivers call this OS-supplied function + * to allocate a packet buffer to receive a packet into. + */ +void fdev_net_alloc(fdev_net_t *fdev, + vm_size_t buf_size, fdev_memflags_t flags, + void **out_buf, fdev_buf_vect_t **out_bufvec); + +/* + * Network drivers call this OS-supplied function + * when a packet has been received from the network. + * Calling this function consumes the packet buffer. + */ +void fdev_net_recv(fdev_net_t *fdev, void *buf, fdev_buf_vec_t *bufvec, + vm_offset_t pkt_size); + +/* + * Free a packet buffer without having received a packet into it. + * Typically only used during shutdown. + */ +void fdev_net_free(fdev_net_t *fdev, void *buf, fdev_buf_vec_t *bufvec); +__FLUX_END_DECLS + +#endif /* _FLUX_FDEV_NET_H_ */ diff --git a/apps/rmgr/include/flux/fdev/serial.h b/apps/rmgr/include/flux/fdev/serial.h new file mode 100644 index 0000000..77dac23 --- /dev/null +++ b/apps/rmgr/include/flux/fdev/serial.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions specific to RS-232 serial character devices. + */ +#ifndef _FLUX_FDEV_SERIAL_H_ +#define _FLUX_FDEV_SERIAL_H_ + +#include + +struct fdev_serial +{ + fdev_char_t fdev_char; + + fdev_error_t (*set)(fdev_serial_t *dev, unsigned baud, int mode); + fdev_error_t (*get)(fdev_serial_t *dev, unsigned *out_baud, + int *out_mode, int *out_state); +}; +typedef struct fdev_serial fdev_serial_t; + +/* Serial-specific device driver interface functions */ +#define fdev_serial_set(fdev, baud, mode) \ + ((fdev)->set((fdev), (baud), (mode))) +#define fdev_serial_get(fdev, baud, out_mode, out_state) \ + ((fdev)->get((fdev), (baud), (out_mode), (out_state))) + +/* Serial mode flags */ +#define FDEV_SERIAL_DTR 0x0010 /* Assert data terminal ready signal */ +#define FDEV_SERIAL_RTS 0x0020 /* Assert request-to-send signal */ +#define FDEV_SERIAL_CSIZE 0x0300 /* Number of bits per byte: */ +#define FDEV_SERIAL_CS5 0x0000 /* 5 bits */ +#define FDEV_SERIAL_CS5 0x0100 /* 6 bits */ +#define FDEV_SERIAL_CS5 0x0200 /* 7 bits */ +#define FDEV_SERIAL_CS5 0x0300 /* 8 bits */ +#define FDEV_SERIAL_CSTOPB 0x0400 /* Use two stop bits if set */ +#define FDEV_SERIAL_PARENB 0x1000 /* Enable parity */ +#define FDEV_SERIAL_PARODD 0x2000 /* Odd parity if set, even if not */ + +/* Serial line state flags */ +#define FDEV_SERIAL_DSR 0x0001 /* Data set ready */ +#define FDEV_SERIAL_CTS 0x0002 /* Clear to send */ +#define FDEV_SERIAL_CD 0x0004 /* Carrier detect */ +#define FDEV_SERIAL_RI 0x0008 /* Ring indicator */ + +/* + * Serial drivers call this OS-supplied function + * when a break signal or parity error is received. + */ +void fdev_serial_recv_special(fdev_char_t *fdev, int event); +#define FDEV_SERIAL_BREAK 0x01 /* Break signal received */ +#define FDEV_SERIAL_PARITY_ERR 0x02 /* Parity error detected */ +#define FDEV_SERIAL_STATE_CHG 0x03 /* State of RS-232 signals changed */ + +#endif /* _FLUX_FDEV_SERIAL_H_ */ diff --git a/apps/rmgr/include/flux/gdb.h b/apps/rmgr/include/flux/gdb.h new file mode 100644 index 0000000..50f9395 --- /dev/null +++ b/apps/rmgr/include/flux/gdb.h @@ -0,0 +1,82 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ +/* + * Generic definitions for remote GDB debugging. + */ +#ifndef _FLUX_GDB_H_ +#define _FLUX_GDB_H_ + +#include +#include + +/* + * This structure must be defined in + * to represent the processor register state frame as GDB wants it. + */ +struct gdb_state; + +/* + * This structure must be defined in + * to represent the processor register state + * as saved by the default trap entrypoint code. + */ +struct trap_state; + +__FLUX_BEGIN_DECLS + +/* + * This function provides the necessary glue + * between the base trap handling mechanism provided by the toolkit + * and a machine-independent GDB stub such as gdb_serial. + * This function is intended to be plugged into 'trap_handler_func' + * (see flux/machine/base_trap.h). + */ +int gdb_trap(struct trap_state *inout_trap_state); + +/* + * Before the above function is called for the first time, + * this variable must be set to point to the GDB stub it should call. + */ +extern void (*gdb_signal)(int *inout_signo, struct gdb_state *inout_gdb_state); + +/* + * These functions are provided to copy data + * into and out of the address space of the program being debugged. + * Machine-dependent code typically provides default implementations + * that simply copy data into and out of the kernel's own address space. + * These functions return zero if the copy succeeds, + * or nonzero if the memory region couldn't be accessed for some reason. + */ +int gdb_copyin(vm_offset_t src_va, void *dest_buf, vm_size_t size); +int gdb_copyout(const void *src_buf, vm_offset_t dest_va, vm_size_t size); + +/* + * The GDB stub calls this architecture-specific function + * to modify the trace flag in the processor state. + */ +void gdb_set_trace_flag(int trace_enable, struct gdb_state *inout_state); + +__FLUX_END_DECLS + +/* Bring in machine-dependent definitions. */ +#include + +#endif /* _FLUX_GDB_H_ */ diff --git a/apps/rmgr/include/flux/gdb_serial.h b/apps/rmgr/include/flux/gdb_serial.h new file mode 100644 index 0000000..7921dc9 --- /dev/null +++ b/apps/rmgr/include/flux/gdb_serial.h @@ -0,0 +1,75 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + * Loosely based on i386-stub.c from GDB 4.14 + */ +#ifndef _FLUX_GDB_SERIAL_H_ +#define _FLUX_GDB_SERIAL_H_ + +#include +#include + +/* + * This is actually defined in , + * but we don't actually need the full definition in this header file. + */ +struct gdb_state; + +__FLUX_BEGIN_DECLS + +/* + * These function pointers define how we send and receive characters + * over the serial line. They must be initialized before gdb_serial_stub() + * is called for the first time. + */ +extern int (*gdb_serial_recv)(void); +extern void (*gdb_serial_send)(int ch); + +/* + * This is the main part of the GDB stub for serial-line remote debugging. + * Call it with a signal number indicating the signal + * that caused the program to stop, + * and a snapshot of the program's register state. + * After this routine returns, if *inout_signo has been set to 0, + * the program's execution should be resumed as if nothing had happened. + * If *inout_signo is nonzero, + * then that signal should be delivered to the program + * as if the program had caused the signal itself. + * The register state in *inout_state may have been changed; + * the new register state should be used when resuming execution. + */ +void gdb_serial_signal(int *inout_signo, struct gdb_state *inout_state); + +/* + * Call this routine to indicate that the program is exiting normally. + * The 'exit_code' specifies the exit code sent back to GDB. + * This function will cause the GDB session to be broken; + * the caller can then reboot or exit or whatever locally. + */ +void gdb_serial_exit(int exit_code); + +/* + * Call these routines to output characters or strings + * to the remote debugger's standard output. + */ +void gdb_serial_putchar(int ch); +void gdb_serial_puts(const char *s); +__FLUX_END_DECLS + +#endif /* _FLUX_GDB_SERIAL_H_ */ diff --git a/apps/rmgr/include/flux/inline.h b/apps/rmgr/include/flux/inline.h new file mode 100644 index 0000000..c2d6adb --- /dev/null +++ b/apps/rmgr/include/flux/inline.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_INLINE_H_ +#define _FLUX_INLINE_H_ + +#ifndef FLUX_INLINE +#define FLUX_INLINE extern __inline +#endif + +#endif /* _FLUX_INLINE_H_ */ diff --git a/apps/rmgr/include/flux/lmm.h b/apps/rmgr/include/flux/lmm.h new file mode 100644 index 0000000..5b0ff31 --- /dev/null +++ b/apps/rmgr/include/flux/lmm.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Public header file for the List Memory Manager. + */ +#ifndef _FLUX_LMM_H_ +#define _FLUX_LMM_H_ + +#include +#include + +typedef natural_t lmm_flags_t; +typedef integer_t lmm_pri_t; + +/* The contents of these structures are opaque to users. */ +typedef struct lmm_region +{ + struct lmm_region *next; + + /* List of free memory blocks in this region. */ + struct lmm_node *nodes; + + /* Virtual addresses of the start and end of the memory region. */ + vm_offset_t min; + vm_offset_t max; + + /* Attributes of this memory. */ + lmm_flags_t flags; + + /* Allocation priority of this region with respect to other regions. */ + lmm_pri_t pri; + + /* Current amount of free space in this region in bytes. */ + vm_size_t free; +} lmm_region_t; + +typedef struct lmm +{ + struct lmm_region *regions; +} lmm_t; + +#define LMM_INITIALIZER { 0 } + +__FLUX_BEGIN_DECLS + +void lmm_init(lmm_t *lmm); +void lmm_add_region(lmm_t *lmm, lmm_region_t *lmm_region, + void *addr, vm_size_t size, + lmm_flags_t flags, lmm_pri_t pri); +void lmm_add_free(lmm_t *lmm, void *block, vm_size_t size); +void lmm_remove_free(lmm_t *lmm, void *block, vm_size_t size); +void *lmm_alloc(lmm_t *lmm, vm_size_t size, lmm_flags_t flags); +void *lmm_alloc_aligned(lmm_t *lmm, vm_size_t size, lmm_flags_t flags, + int align_bits, vm_offset_t align_ofs); +void *lmm_alloc_page(lmm_t *lmm, lmm_flags_t flags); +void *lmm_alloc_gen(lmm_t *lmm, vm_size_t size, lmm_flags_t flags, + int align_bits, vm_offset_t align_ofs, + vm_offset_t bounds_min, vm_offset_t bounds_max); +vm_size_t lmm_avail(lmm_t *lmm, lmm_flags_t flags); +void lmm_find_free(lmm_t *lmm, vm_offset_t *inout_addr, + vm_size_t *out_size, lmm_flags_t *out_flags); +void lmm_free(lmm_t *lmm, void *block, vm_size_t size); +void lmm_free_page(lmm_t *lmm, void *block); + +/* Only available if debugging turned on. */ +void lmm_dump(lmm_t *lmm); +__FLUX_END_DECLS + +#endif /* _FLUX_LMM_H_ */ diff --git a/apps/rmgr/include/flux/machine/anno.h b/apps/rmgr/include/flux/machine/anno.h new file mode 100644 index 0000000..bd0d01b --- /dev/null +++ b/apps/rmgr/include/flux/machine/anno.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_ANNO_H_ +#define _FLUX_X86_ANNO_H_ + +#ifndef ASSEMBLER + + + +#else /* ASSEMBLER */ + + +/* Create an arbitrary annotation entry. + Must switch back to an appropriate segment afterward. */ +#define ANNO_ENTRY(table, val1, val2, val3) \ + .section .anno,"aw",@progbits ;\ + .long val1,val2,val3,table + +/* Create an annotation entry for code in a text segment. */ +#define ANNO_TEXT(table, val2, val3) \ +9: ANNO_ENTRY(table, 9b, val2, val3) ;\ + .text + + + +/* The following are for common annotation tables. + These don't have to be used in any given kernel, + and others can be defined as convenient. */ + + +/* The anno_intr table is generally accessed + on hardware interrupts that occur while running in kernel mode. + The value is a routine for the trap handler in interrupt.S + to jump to before processing the hardware interrupt. + This routine applies to all code from this address + up to but not including the address of the next ANNO_INTR. + To disable interrupt redirection for a piece of code, + place an ANNO_INTR(0) before it. */ + +#define ANNO_INTR(routine) \ + ANNO_TEXT(anno_intr, routine, 0) + + +/* The anno_trap table is accessed + on processor traps that occur in kernel mode. + If a match is found in this table, + the specified alternate handler is run instead of the generic handler. + A match is found only if the EIP exactly matches an ANNO_TRAP entry + (i.e. these entries apply to individual instructions, not groups), + and if the trap type that occurred matches the type specified. */ + +#define ANNO_TRAP(routine) \ + ANNO_TEXT(anno_trap, routine, 0) + + +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_ANNO_H_ */ diff --git a/apps/rmgr/include/flux/machine/asm.h b/apps/rmgr/include/flux/machine/asm.h new file mode 100644 index 0000000..45a467e --- /dev/null +++ b/apps/rmgr/include/flux/machine/asm.h @@ -0,0 +1,119 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_ASM_H_ +#define _FLUX_X86_ASM_H_ + +#include + +/* This is a more reliable delay than a few short jmps. */ +#define IODELAY pushl %eax; inb $0x80,%al; inb $0x80,%al; popl %eax + +#define S_ARG0 4(%esp) +#define S_ARG1 8(%esp) +#define S_ARG2 12(%esp) +#define S_ARG3 16(%esp) + +#define FRAME pushl %ebp; movl %esp, %ebp +#define EMARF leave + +#define B_ARG0 8(%ebp) +#define B_ARG1 12(%ebp) +#define B_ARG2 16(%ebp) +#define B_ARG3 20(%ebp) + +#ifdef i486 +#define TEXT_ALIGN 4 +#else +#define TEXT_ALIGN 2 +#endif +#define DATA_ALIGN 2 +#define ALIGN TEXT_ALIGN + +/* + * The .align directive has different meaning on the x86 when using ELF + * than when using a.out. + * Newer GNU as remedies this problem by providing .p2align and .balign. + */ +#if defined(HAVE_P2ALIGN) +# define P2ALIGN(p2) .p2align p2 +#elif defined(__ELF__) +# define P2ALIGN(p2) .align (1<<(p2)) +#else +# define P2ALIGN(p2) .align p2 +#endif + +#define LCL(x) x + +#define LB(x,n) n +#ifndef __ELF__ +#define EXT(x) _ ## x +#define LEXT(x) _ ## x ## : +#define SEXT(x) "_"#x +#else +#define EXT(x) x +#define LEXT(x) x ## : +#define SEXT(x) #x +#endif +#define GLEXT(x) .globl EXT(x); LEXT(x) +#define LCLL(x) x ## : +#define gLB(n) n ## : +#define LBb(x,n) n ## b +#define LBf(x,n) n ## f + + +/* Symbol types */ +#ifdef __ELF__ +#define FUNCSYM(x) .type x,@function +#else +#define FUNCSYM(x) /* nothing */ +#endif + + +#ifdef GPROF + +#define MCOUNT .data; gLB(9) .long 0; .text; lea LBb(x, 9),%edx; call mcount +#define ENTRY(x) .globl EXT(x); P2ALIGN(TEXT_ALIGN); LEXT(x) ; \ + pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + P2ALIGN(TEXT_ALIGN); LEXT(x) LEXT(y) +#define ASENTRY(x) .globl x; P2ALIGN(TEXT_ALIGN); gLB(x) ; \ + pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; + +#else /* ndef GPROF */ + +#define MCOUNT +#define ENTRY(x) FUNCSYM(x); .globl EXT(x); P2ALIGN(TEXT_ALIGN); LEXT(x) +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + P2ALIGN(TEXT_ALIGN); LEXT(x) LEXT(y) +#define ASENTRY(x) .globl x; P2ALIGN(TEXT_ALIGN); gLB(x) + +#endif /* ndef GPROF */ + + +#define Entry(x) P2ALIGN(TEXT_ALIGN); GLEXT(x) +#define DATA(x) P2ALIGN(DATA_ALIGN); GLEXT(x) + +#endif /* _FLUX_X86_ASM_H_ */ diff --git a/apps/rmgr/include/flux/machine/base_asm.sym b/apps/rmgr/include/flux/machine/base_asm.sym new file mode 100644 index 0000000..9de12c3 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_asm.sym @@ -0,0 +1,36 @@ +/* + * MOSS - DOS extender built from the Mach 4 source tree + * Copyright (C) 1995-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ + +#include + +#include "gdt.h" + +offset i386_tss tss esp0 +offset i386_tss tss ss +size i386_tss tss + +expr KERNEL_CS +expr KERNEL_DS +expr KERNEL_16_CS +expr KERNEL_16_DS +expr LINEAR_CS +expr LINEAR_DS + diff --git a/apps/rmgr/include/flux/machine/base_cpu.h b/apps/rmgr/include/flux/machine/base_cpu.h new file mode 100644 index 0000000..0eb6ea5 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_cpu.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Functions for setting up and activating + * a basic x86 protected-mode kernel execution environment. + */ +#ifndef _FLUX_X86_BASE_CPU_H_ +#define _FLUX_X86_BASE_CPU_H_ + +#include +#include + +__FLUX_BEGIN_DECLS +/* + * CPU information for the processor base_cpu_init() was called on. + */ +extern struct cpu_info base_cpuid; + +/* + * Initialize all the processor data structures defining the base environment: + * the base_cpuid, the base_idt, the base_gdt, and the base_tss. + */ +extern void base_cpu_init(void); + +/* + * Load all of the above into the processor, + * properly setting up the protected-mode environment. + */ +extern void base_cpu_load(void); +__FLUX_END_DECLS + +/* + * Do both at once. + */ +#define base_cpu_setup() (base_cpu_init(), base_cpu_load()) + +#endif /* _FLUX_X86_BASE_CPU_H_ */ diff --git a/apps/rmgr/include/flux/machine/base_gdt.h b/apps/rmgr/include/flux/machine/base_gdt.h new file mode 100644 index 0000000..ac9e838 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_gdt.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This file defines a basic global descriptor table that can be used + * for simple protected-mode execution in both kernel and user mode. + */ +#ifndef _FLUX_X86_BASE_GDT_H_ +#define _FLUX_X86_BASE_GDT_H_ + +#include + + +#define BASE_TSS 0x08 +#define KERNEL_CS 0x10 /* Kernel's PL0 code segment */ +#define KERNEL_DS 0x18 /* Kernel's PL0 data segment */ +#define KERNEL_16_CS 0x20 /* 16-bit version of KERNEL_CS */ +#define KERNEL_16_DS 0x28 /* 16-bit version of KERNEL_DS */ +#define LINEAR_CS 0x30 /* PL0 code segment mapping to linear space */ +#define LINEAR_DS 0x38 /* PL0 data segment mapping to linear space */ +#define USER_CS 0x43 /* User-defined descriptor, RPL=3 */ +#define USER_DS 0x4b /* User-defined descriptor, RPL=3 */ + +#define GDTSZ (0x50/8) + + +#ifndef ASSEMBLER + +#include + +extern struct x86_desc base_gdt[GDTSZ]; + +__FLUX_BEGIN_DECLS +/* Initialize the base GDT descriptors with sensible defaults. */ +extern void base_gdt_init(void); + +/* Load the base GDT into the CPU. */ +extern void base_gdt_load(void); + +/* 16-bit versions of the above functions, + which can be executed in real mode. */ +extern void i16_base_gdt_init(void); +extern void i16_base_gdt_load(void); +__FLUX_END_DECLS + +#endif /* not ASSEMBLER */ + +#endif _FLUX_X86_BASE_GDT_H_ diff --git a/apps/rmgr/include/flux/machine/base_idt.h b/apps/rmgr/include/flux/machine/base_idt.h new file mode 100644 index 0000000..d9ec20b --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_idt.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_BASE_IDT_H_ +#define _FLUX_X86_BASE_IDT_H_ + +#include +#include + + +/* The base environment provides a full-size 256-entry IDT. + This is needed, for example, under VCPI or Intel MP Standard PCs. */ +#define IDTSZ 256 + +extern struct x86_gate base_idt[IDTSZ]; + + +/* Note that there is no base_idt_init() function, + because the IDT is used for both trap and interrupt vectors. + To initialize the processor trap vectors, call base_trap_init(). + Inititalizing hardware interrupt vectors is platform-specific. */ + + +__FLUX_BEGIN_DECLS +/* Load the base IDT into the CPU. */ +extern void base_idt_load(void); +__FLUX_END_DECLS + + +#endif /* _FLUX_X86_BASE_IDT_H_ */ diff --git a/apps/rmgr/include/flux/machine/base_paging.h b/apps/rmgr/include/flux/machine/base_paging.h new file mode 100644 index 0000000..6272ac0 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_paging.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Basic page directory and page table management routines for the x86. + */ +#ifndef _FLUX_X86_BASE_PAGING_H_ +#define _FLUX_X86_BASE_PAGING_H_ + +#include +#include +#include +#include +#include + +/* + * Find the entry in a page directory or page table + * for a particular linear address. + */ +#define pdir_find_pde(pdir_pa, la) \ + (&((pd_entry_t*)phystokv(pdir_pa))[lin2pdenum(la)]) +#define ptab_find_pte(ptab_pa, la) \ + (&((pt_entry_t*)phystokv(ptab_pa))[lin2ptenum(la)]) + +/* + * Find a page table entry given a page directory and a linear address. + * Returns NULL if there is no page table covering that address. + * Assumes that if there is a valid PDE, it's a page table, _not_ a 4MB page. + */ +FLUX_INLINE pt_entry_t *pdir_find_pte(vm_offset_t pdir_pa, vm_offset_t la) +{ + pd_entry_t *pde = pdir_find_pde(pdir_pa, la); + if (!(*pde & INTEL_PDE_VALID)) + return 0; + return ptab_find_pte(pde_to_pa(*pde), la); +} + +/* + * Get the value of a page table entry, + * or return zero if no such entry exists. + * As above, doesn't check for 4MB pages. + */ +FLUX_INLINE pt_entry_t pdir_get_pte(vm_offset_t pdir_pa, vm_offset_t la) +{ + pt_entry_t *pte = pdir_find_pte(pdir_pa, la); + return pte ? *pte : 0; +} + +__FLUX_BEGIN_DECLS +/* + * Functions called by the following routines to allocate a page table. + * Supplies a single page of CLEARED memory, by its physical address. + * Returns zero if successful, nonzero on failure. + * The default implementation simply allocates a page from the malloc_lmm, + * returning -1 if the LMM runs out of memory. + * This implementation can be overridden, of course. + */ +int ptab_alloc(vm_offset_t *out_ptab_pa); + +/* + * Free a page table allocated using ptab_alloc(). + * The caller must ensure that it is not still in use in any page directories. + */ +void ptab_free(vm_offset_t ptab_pa); + +/* + * Map a 4KB page into a page directory. + * Calls page_alloc_func if a new page table needs to be allocated. + * If page_alloc_func returns nonzero, pdir_map_page aborts with that value. + * Otherwise, inserts the mapping and returns zero. + * Doesn't check for 4MB pages. + */ +int pdir_map_page(vm_offset_t pdir_pa, vm_offset_t la, pt_entry_t mapping); + + +/* + * Map a continuous range of virtual addresses + * to a continuous range of physical addresses. + * If the processor supports 4MB pages, uses them if possible. + * Assumes that there are no valid mappings already in the specified range. + * The 'mapping_bits' parameter must include INTEL_PTE_VALID, + * and may include other permissions as desired. + */ +int pdir_map_range(vm_offset_t pdir_pa, vm_offset_t la, vm_offset_t pa, + vm_size_t size, pt_entry_t mapping_bits); + +/* + * Change the permissions on an existing mapping range. + * The 'new_mapping_bits' parameter must include INTEL_PTE_VALID, + * and may include other permissions as desired. + * Assumes that the mappings being changed were produced + * by a previous call to pdir_map_range() + * with identical linear address and size parameters. + */ +void pdir_prot_range(vm_offset_t pdir_pa, vm_offset_t la, vm_size_t size, + pt_entry_t new_mapping_bits); + +/* + * Unmap a continuous range of virtual addresses. + * Assumes that the mappings being unmapped were produced + * by a previous call to pdir_map_range() + * with identical linear address and size parameters. + */ +void pdir_unmap_range(vm_offset_t pdir_pa, vm_offset_t la, vm_size_t size); + +/* + * These functions are primarily for debugging VM-related code: + * they pretty-print a dump of a page directory or page table + * and all their mappings. + */ +void pdir_dump(vm_offset_t pdir_pa); +void ptab_dump(vm_offset_t ptab_pa, vm_offset_t base_la); + +/* + * Initialize a basic paged environment. + * Sets up the base_pdir (see below) which direct maps + * all physical memory from 0 to (at least) phys_mem_max, + * and enables paging on the current processor using that page directory. + * The client can then modify this page directory or create others as needed. + * The base physical memory mappings are accessible from user mode by default. + */ +void base_paging_init(void); +__FLUX_END_DECLS + +/* + * Physical address of the base page directory, + * set up by base_paging_init(). + */ +extern vm_offset_t base_pdir_pa; + +#endif _FLUX_X86_BASE_PAGING_H_ diff --git a/apps/rmgr/include/flux/machine/base_stack.h b/apps/rmgr/include/flux/machine/base_stack.h new file mode 100644 index 0000000..61cf75e --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_stack.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This header file defines the initial stack provided by the base environment. + * The stack is BASE_STACK_SIZE bytes by default. + */ +#ifndef _FLUX_X86_BASE_STACK_H_ +#define _FLUX_X86_BASE_STACK_H_ + +#define BASE_STACK_SIZE 4096 + +#ifndef ASSEMBLER + +extern char base_stack_start[], base_stack_end[]; + +#endif + +#endif /* _FLUX_X86_BASE_STACK_H_ */ diff --git a/apps/rmgr/include/flux/machine/base_trap.h b/apps/rmgr/include/flux/machine/base_trap.h new file mode 100644 index 0000000..0ab39b2 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_trap.h @@ -0,0 +1,162 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University. + * Copyright (c) 1994 The University of Utah and + * the Center for Software Science (CSS). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_BASE_TRAP_H_ +#define _FLUX_X86_BASE_TRAP_H_ + +#ifndef ASSEMBLER + +#include + +/* + * This structure corresponds to the state of user registers + * as saved upon kernel trap/interrupt entry. + * As always, it is only a default implementation; + * a well-optimized kernel will probably want to override it + * with something that allows better optimization. + */ +struct trap_state +{ + /* Saved segment registers */ + unsigned int gs; + unsigned int fs; + unsigned int es; + unsigned int ds; + + /* PUSHA register state frame */ + unsigned int edi; + unsigned int esi; + unsigned int ebp; + unsigned int cr2; /* we save cr2 over esp for page faults */ + unsigned int ebx; + unsigned int edx; + unsigned int ecx; + unsigned int eax; + + /* Processor trap number, 0-31. */ + unsigned int trapno; + + /* Error code pushed by the processor, 0 if none. */ + unsigned int err; + + /* Processor state frame */ + unsigned int eip; + unsigned int cs; + unsigned int eflags; + unsigned int esp; + unsigned int ss; + + /* Virtual 8086 segment registers */ + unsigned int v86_es; + unsigned int v86_ds; + unsigned int v86_fs; + unsigned int v86_gs; +}; + +/* + * The actual trap_state frame pushed by the processor + * varies in size depending on where the trap came from. + */ +#define TR_KSIZE ((int)&((struct trap_state*)0)->esp) +#define TR_USIZE ((int)&((struct trap_state*)0)->v86_es) +#define TR_V86SIZE sizeof(struct trap_state) + + +__FLUX_BEGIN_DECLS +/* + * This library routine initializes the trap vectors in the base IDT + * to point to default trap handler entrypoints + * which merely push the standard trap saved-state frame above + * and call the default trap handler routine, 'trap_handler'. + */ +extern void base_trap_init(void); + +/* + * This gate initialization table is used by base_trap_init + * to initialize the base IDT to the default trap entrypoint code, + * which pushes the state frame described above + * and calls the trap handler, below. + */ +extern struct gate_init_entry base_trap_inittab[]; + +/* + * The default trap entrypoint code checks this function pointer + * (after saving the trap_state frame described by the structure above), + * and if non-null, calls the C function it points to. + * The function can examine and modify the provided trap_state as appropriate. + * If the trap handler function returns zero, + * execution will be resumed or resterted with the final trap_state; + * if the trap handler function returns nonzero, + * the trap handler dumps the trap state to the console and panics. + */ +extern int (*base_trap_handler)(struct trap_state *state); + + +/* + * This routine dumps the contents of the specified trap_state structure + * to the console using printf. + * It is normally called automatically from trap_dump_panic + * when an unexpected trap occurs; + * however, can be called at other times as well + * (e.g., for debugging custom trap handlers). + */ +void trap_dump(const struct trap_state *st); + +/* + * This routine simply calls trap_dump to dump the trap state, + * and then calls panic. + * It is used by the default trap entrypoint code + * when a trap occurs and there is no trap handler, + * and by the UNEXPECTED_TRAP assembly language macro below. + */ +void trap_dump_panic(const struct trap_state *st); +__FLUX_END_DECLS + + +#else ASSEMBLER + +#include + + +/* + * Simple assembly language macro that can be called from most anywhere + * to dump a trap state frame at the top of the kernel stack and panic. + */ +#define UNEXPECTED_TRAP \ + movw %ss,%ax ;\ + movw %ax,%ds ;\ + movw %ax,%es ;\ + movl %esp,%eax ;\ + pushl %eax ;\ + call EXT(trap_dump_panic) ;\ + + +#endif ASSEMBLER + + +#endif /* _FLUX_X86_BASE_TRAP_H_ */ diff --git a/apps/rmgr/include/flux/machine/base_tss.h b/apps/rmgr/include/flux/machine/base_tss.h new file mode 100644 index 0000000..ba87455 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_tss.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions for a basic x86 32-bit Task State Segment (TSS) + * which is set up and and used by the base environment as a "default" TSS. + */ +#ifndef _FLUX_X86_BASE_TSS_H_ +#define _FLUX_X86_BASE_TSS_H_ + +#include +#include + +extern struct x86_tss base_tss; + +__FLUX_BEGIN_DECLS +/* Initialize the base TSS with sensible default values. + The current stack pointer is used as the TSS's ring 0 stack pointer. */ +extern void base_tss_init(void); + +/* Load the base TSS into the current CPU. + Assumes that the base GDT is already loaded, + and that the BASE_TSS descriptor in the GDT refers to the base TSS. */ +extern void base_tss_load(void); +__FLUX_END_DECLS + +#endif _FLUX_X86_BASE_TSS_H_ diff --git a/apps/rmgr/include/flux/machine/base_vm.h b/apps/rmgr/include/flux/machine/base_vm.h new file mode 100644 index 0000000..317b427 --- /dev/null +++ b/apps/rmgr/include/flux/machine/base_vm.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions for the base VM environment provided by the OS toolkit: + * how to change pointers between physical, virtual, and linear addresses, etc. + */ +#ifndef _FLUX_X86_BASE_VM_H_ +#define _FLUX_X86_BASE_VM_H_ + +#include + + +/* This variable is expected always to contain + the kernel virtual address at which physical memory is mapped. + It may change as paging is turned on or off. */ +extern vm_offset_t phys_mem_va; + + +/* Calculate a kernel virtual address from a physical address. */ +#define phystokv(pa) ((vm_offset_t)(pa) + phys_mem_va) + +/* Same, but in reverse. + This only works for the region of kernel virtual addresses + that directly map physical addresses. */ +#define kvtophys(va) ((vm_offset_t)(va) - phys_mem_va) + + +/* This variable contains the kernel virtual address + corresponding to linear address 0. + In the absence of paging, + linear addresses are always the same as physical addresses. */ +extern vm_offset_t linear_base_va; + +/* Convert between linear and kernel virtual addresses. */ +#define lintokv(la) ((vm_offset_t)(la) + linear_base_va) +#define kvtolin(va) ((vm_offset_t)(va) - linear_base_va) + + +/* If the kernel was started from real mode, + this variable contains our original real-mode code segment. */ +extern unsigned short real_cs; + + +#endif /* _FLUX_X86_BASE_VM_H_ */ diff --git a/apps/rmgr/include/flux/machine/c/common.h b/apps/rmgr/include/flux/machine/c/common.h new file mode 100644 index 0000000..2963de6 --- /dev/null +++ b/apps/rmgr/include/flux/machine/c/common.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Common machine-dependent definitions + * used by the Flux minimal C library headers. + */ +#ifndef _FLUX_X86_MC_COMMON_H_ +#define _FLUX_X86_MC_COMMON_H_ + +typedef unsigned int __flux_size_t; +typedef int __flux_ssize_t; +typedef unsigned int __flux_off_t; +typedef char * __flux_va_list; + +#endif /* _FLUX_X86_MC_COMMON_H_ */ diff --git a/apps/rmgr/include/flux/machine/c/setjmp.h b/apps/rmgr/include/flux/machine/c/setjmp.h new file mode 100644 index 0000000..7717100 --- /dev/null +++ b/apps/rmgr/include/flux/machine/c/setjmp.h @@ -0,0 +1,34 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * setjmp/longjmp buffer for x86. + */ +#ifndef _FLUX_X86_C_SETJMP_H_ +#define _FLUX_X86_C_SETJMP_H_ + +typedef int jmp_buf[6]; /* ebx, esi, edi, ebp, esp, eip */ + +#endif /* _FLUX_X86_C_SETJMP_H_ */ diff --git a/apps/rmgr/include/flux/machine/c/stdarg.h b/apps/rmgr/include/flux/machine/c/stdarg.h new file mode 100644 index 0000000..7bfd87d --- /dev/null +++ b/apps/rmgr/include/flux/machine/c/stdarg.h @@ -0,0 +1,48 @@ +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University. + * Copyright (c) 1994 The University of Utah and + * the Center for Software Science (CSS). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_C_STDARG_H_ +#define _FLUX_X86_C_STDARG_H_ + +#include + +#define __va_size(type) ((sizeof(type)+3) & ~0x3) + +#ifndef _VA_LIST_ +#define _VA_LIST_ +typedef __flux_va_list va_list; +#endif + +#define va_start(pvar, lastarg) \ + ((pvar) = (char*)(void*)&(lastarg) + __va_size(lastarg)) +#define va_end(pvar) +#define va_arg(pvar,type) \ + ((pvar) += __va_size(type), \ + *((type *)((pvar) - __va_size(type)))) + +#endif _FLUX_X86_C_STDARG_H_ diff --git a/apps/rmgr/include/flux/machine/cpuid.h b/apps/rmgr/include/flux/machine/cpuid.h new file mode 100644 index 0000000..34a0890 --- /dev/null +++ b/apps/rmgr/include/flux/machine/cpuid.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * CPU identification for x86 processors. + */ +#ifndef _FLUX_X86_CPUID_H_ +#define _FLUX_X86_CPUID_H_ + +#include + +struct cpu_info +{ + unsigned stepping : 4; + unsigned model : 4; + unsigned family : 4; + unsigned type : 2; + unsigned reserved : 18; + unsigned feature_flags; + char vendor_id[12]; + unsigned char cache_config[16]; +}; + +/* + * Values of the cpu_info.family field + */ +#define CPU_FAMILY_386 3 +#define CPU_FAMILY_486 4 +#define CPU_FAMILY_PENTIUM 5 +#define CPU_FAMILY_PENTIUM_PRO 6 + +/* + * Values of the cpu_info.type field + */ +#define CPU_TYPE_ORIGINAL 0 +#define CPU_TYPE_OVERDRIVE 1 +#define CPU_TYPE_DUAL 2 + +/* + * CPU feature_flags bit definitions. + */ +#define CPUF_ON_CHIP_FPU 0x00000001 /* On-chip floating point */ +#define CPUF_VM86_EXT 0x00000002 /* Virtual mode extensions */ +#define CPUF_IO_BKPTS 0x00000004 /* I/O breakpoint support */ +#define CPUF_4MB_PAGES 0x00000008 /* 4MB page support */ +#define CPUF_TS_COUNTER 0x00000010 /* Timestamp counter */ +#define CPUF_PENTIUM_MSR 0x00000020 /* Pentium model-spec regs */ +#define CPUF_PAGE_ADDR_EXT 0x00000040 /* Page address extensions */ +#define CPUF_MACHINE_CHECK_EXCP 0x00000080 /* Machine check exception */ +#define CPUF_CMPXCHG8B 0x00000100 /* CMPXCHG8B instruction */ +#define CPUF_LOCAL_APIC 0x00000200 /* CPU contains a local APIC */ +#define CPUF_MEM_RANGE_REGS 0x00001000 /* memory type range regs */ +#define CPUF_PAGE_GLOBAL_EXT 0x00002000 /* page global extensions */ +#define CPUF_MACHINE_CHECK_ARCH 0x00004000 /* Machine check architecture */ +#define CPUF_CMOVCC 0x00008000 /* CMOVcc instructions */ + +/* + * Cache configuration descriptor entry values. + */ +#define CPUC_NULL 0x00 +#define CPUC_CODE_TLB_4K_4W_64E 0x01 +#define CPUC_CODE_TLB_4M_4W_4E 0x02 +#define CPUC_DATA_TLB_4K_4W_64E 0x03 +#define CPUC_DATA_TLB_4M_4W_8E 0x04 +#define CPUC_CODE_L1_32B_4W_8KB 0x06 +#define CPUC_DATA_L1_32B_2W_8KB 0x0a +#define CPUC_COMB_L2_32B_4W_128KB 0x41 +#define CPUC_COMB_L2_32B_4W_256KB 0x42 +#define CPUC_COMB_L2_32B_4W_512KB 0x43 + + +__FLUX_BEGIN_DECLS +/* + * Generic routine to detect the current processor + * and fill in the supplied cpu_info structure with all information available. + * If the vendor ID cannot be determined, it is left a zero-length string. + * This routine assumes the processor is at least a 386 - + * since it's a 32-bit function, it wouldn't run on anything less anyway. + */ +void cpuid(struct cpu_info *out_id); + +/* + * Format the information in a cpu_info structure + * into a human-readable ASCII representation, + * using the specified printf-like formatting function for output. + */ +void cpu_info_format( + struct cpu_info *info, + void (*formatter)(void *data, const char *fmt, ...), + void *data); + +/* + * Pretty-print a cpu_info structure to the console using printf(). + */ +void cpu_info_dump(struct cpu_info *info); + +/* + * Given two cpu_info structures, reduce 'id' to be the minimum + * (least-common-denominator) of the two structurens. + * Typically used on SMP systems to determine the basic feature set + * common across all processors in the system regardless of type. + */ +void cpu_info_min(struct cpu_info *id, const struct cpu_info *id2); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_CPUID_H_ */ diff --git a/apps/rmgr/include/flux/machine/debug.h b/apps/rmgr/include/flux/machine/debug.h new file mode 100644 index 0000000..90a497b --- /dev/null +++ b/apps/rmgr/include/flux/machine/debug.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DEBUG_H_ +#define _FLUX_X86_DEBUG_H_ + +#define PRINT_STACK_TRACE(num_frames) { \ + int i = (num_frames); \ + unsigned *fp; \ + printf("stack trace:\n"); \ + asm volatile ("movl %%ebp,%0" : "=r" (fp)); \ + while (fp && --i >= 0) { \ + printf("\t0x%08x\n", *(fp + 1)); \ + fp = (unsigned *)(*fp); \ + } \ +} + +#ifdef ASSEMBLER +#ifdef DEBUG + + +#define A(cond,a,b) \ + a,b ;\ + j##cond 8f ;\ + int $0xda ;\ +8: + + +#else /* !DEBUG */ + + +#define A(cond,a,b) + + +#endif /* !DEBUG */ +#else /* !ASSEMBLER */ + + +#endif /* !ASSEMBLER */ + +#endif /* _FLUX_X86_DEBUG_H_ */ diff --git a/apps/rmgr/include/flux/machine/debug_reg.h b/apps/rmgr/include/flux/machine/debug_reg.h new file mode 100644 index 0000000..6e1b8ee --- /dev/null +++ b/apps/rmgr/include/flux/machine/debug_reg.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DEBUG_REG_H_ +#define _FLUX_X86_DEBUG_REG_H_ + +/* Bits in DR7 - debug control register */ +#define DR7_LEN3 0xc0000000 +#define DR7_RW3 0x30000000 +#define DR7_LEN2 0x0c000000 +#define DR7_RW2 0x03000000 +#define DR7_LEN1 0x00c00000 +#define DR7_RW1 0x00300000 +#define DR7_LEN0 0x000c0000 +#define DR7_RW0 0x00030000 +#define DR7_GD 0x00002000 +#define DR7_GE 0x00000200 +#define DR7_LE 0x00000100 +#define DR7_G3 0x00000080 +#define DR7_L3 0x00000040 +#define DR7_G2 0x00000020 +#define DR7_L2 0x00000010 +#define DR7_G1 0x00000008 +#define DR7_L1 0x00000004 +#define DR7_G0 0x00000002 +#define DR7_L0 0x00000001 + +/* Shift values for multibit fields in DR7 */ +#define DR7_LEN3_SHIFT 30 +#define DR7_RW3_SHIFT 28 +#define DR7_LEN2_SHIFT 26 +#define DR7_RW2_SHIFT 24 +#define DR7_LEN1_SHIFT 22 +#define DR7_RW1_SHIFT 20 +#define DR7_LEN0_SHIFT 18 +#define DR7_RW0_SHIFT 16 + +/* Values for LEN fields in DR7 */ +#define DR7_LEN_1 0 +#define DR7_LEN_2 1 +#define DR7_LEN_4 3 + +/* Values for RW fields in DR7 */ +#define DR7_RW_INST 0 /* Break on instruction execution */ +#define DR7_RW_WRITE 1 /* Break on data writes */ +#define DR7_RW_IO 2 /* Break on I/O reads and writes (Pentium only) */ +#define DR7_RW_DATA 3 /* Break on data reads and writes */ + + +/* Bits in DR6 - debug status register */ +#define DR6_BT 0x00008000 +#define DR6_BS 0x00004000 +#define DR6_BD 0x00002000 +#define DR6_B3 0x00000008 +#define DR6_B2 0x00000004 +#define DR6_B1 0x00000002 +#define DR6_B0 0x00000001 + + +#include + +/* Functions to set debug registers. */ + +FLUX_INLINE unsigned get_dr0() +{ + unsigned val; + asm volatile("movl %%dr0,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr1() +{ + unsigned val; + asm volatile("movl %%dr1,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr2() +{ + unsigned val; + asm volatile("movl %%dr2,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr3() +{ + unsigned val; + asm volatile("movl %%dr3,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr6() +{ + unsigned val; + asm volatile("movl %%dr6,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr7() +{ + unsigned val; + asm volatile("movl %%dr7,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE void set_dr0(unsigned val) +{ + asm volatile("movl %0,%%dr0" : : "r" (val)); +} + + +/* Functions to read debug registers. */ + +FLUX_INLINE void set_dr1(unsigned val) +{ + asm volatile("movl %0,%%dr1" : : "r" (val)); +} + +FLUX_INLINE void set_dr2(unsigned val) +{ + asm volatile("movl %0,%%dr2" : : "r" (val)); +} + +FLUX_INLINE void set_dr3(unsigned val) +{ + asm volatile("movl %0,%%dr3" : : "r" (val)); +} + +FLUX_INLINE void set_dr6(unsigned val) +{ + asm volatile("movl %0,%%dr6" : : "r" (val)); +} + +FLUX_INLINE void set_dr7(unsigned val) +{ + asm volatile("movl %0,%%dr7" : : "r" (val)); +} + + +/* Functions to set global breakpoints. */ + +FLUX_INLINE void set_b0(unsigned addr, unsigned len, unsigned rw) +{ + set_dr0(addr); + addr = ((get_dr7() & ~(DR7_LEN0 | DR7_RW0)) + | (len << DR7_LEN0_SHIFT) | (rw << DR7_RW0_SHIFT) + | DR7_GE | DR7_G0); + set_dr7(addr); +} + +FLUX_INLINE void set_b1(unsigned addr, unsigned len, unsigned rw) +{ + set_dr1(addr); + set_dr7((get_dr7() & ~(DR7_LEN1 | DR7_RW1)) + | (len << DR7_LEN1_SHIFT) | (rw << DR7_RW1_SHIFT) + | DR7_GE | DR7_G1); +} + +FLUX_INLINE void set_b2(unsigned addr, unsigned len, unsigned rw) +{ + set_dr2(addr); + set_dr7((get_dr7() & ~(DR7_LEN2 | DR7_RW2)) + | (len << DR7_LEN2_SHIFT) | (rw << DR7_RW2_SHIFT) + | DR7_GE | DR7_G2); +} + +FLUX_INLINE void set_b3(unsigned addr, unsigned len, unsigned rw) +{ + set_dr3(addr); + set_dr7((get_dr7() & ~(DR7_LEN3 | DR7_RW3)) + | (len << DR7_LEN3_SHIFT) | (rw << DR7_RW3_SHIFT) + | DR7_GE | DR7_G3); +} + + + +#endif /* _FLUX_X86_DEBUG_REG_H_ */ diff --git a/apps/rmgr/include/flux/machine/dos/dpmi.h b/apps/rmgr/include/flux/machine/dos/dpmi.h new file mode 100644 index 0000000..db1526e --- /dev/null +++ b/apps/rmgr/include/flux/machine/dos/dpmi.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DOS_DPMI_H_ +#define _FLUX_X86_DOS_DPMI_H_ + +#include +#include + +typedef unsigned short dpmi_error_t; + +#define DPMI_UNSUPPORTED_FUNCTION 0x8001 +#define DPMI_OBJECT_WRONG_STATE 0x8002 +#define DPMI_SYSTEM_INTEGRITY 0x8003 +#define DPMI_DEADLOCK 0x8004 +#define DPMI_SERIALIZATION_CANCELLED 0x8005 +#define DPMI_OUT_OF_RESOURCES 0x8010 +#define DPMI_DESCRIPTOR_UNAVAILABLE 0x8011 +#define DPMI_LINEAR_MEMORY_UNAVAILABLE 0x8012 +#define DPMI_PHYSICAL_MEMORY_UNAVAILABLE 0x8013 +#define DPMI_BACKING_STORE_UNAVAILABLE 0x8014 +#define DPMI_CALLBACK_UNAVAILABLE 0x8015 +#define DPMI_HANDLE_UNAVAILABLE 0x8016 +#define DPMI_MAX_LOCK_COUNT_EXCEEDED 0x8017 +#define DPMI_ALREADY_SERIALIZED_EXCLUSIVELY 0x8018 +#define DPMI_ALREADY_SERIALIZED_SHARED 0x8019 +#define DPMI_INVALID_VALUE 0x8021 +#define DPMI_INVALID_SELECTOR 0x8022 +#define DPMI_INVALID_HANDLE 0x8023 +#define DPMI_INVALID_CALLBACK 0x8024 +#define DPMI_INVALID_LINEAR_ADDRESS 0x8025 +#define DPMI_NOT_SUPPORTED_BY_HARDWARE 0x8026 + +struct real_call_data; /*XXX*/ + +MACH_INLINE dpmi_error_t dpmi_switch_to_pmode( + struct far_pointer_16 *pmode_entry_vector, + unsigned short host_data_seg) +{ + dpmi_error_t err; + + asm volatile(" + movw %3,%%es + lcallw %2 + jc 1f + xorw %%ax,%%ax + 1: pushw %%ds + popw %%es + " : "=a" (err) + : "a" (1), + "m" (*pmode_entry_vector), + "rm" (host_data_seg)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_descriptors( + unsigned short count, + unsigned short *out_selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + movw %%ax,%1 + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=rm" (*out_selector) + : "a" (0x0000), + "c" (count)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_segment_base( + unsigned short selector, + unsigned long *out_base) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + shll $16,%ecx + movw %dx,%cx + 1: + " : "=a" (err), + "=c" (*out_base) + : "a" (0x0006), + "b" (selector) + : "edx"); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_segment_base( + unsigned short selector, + unsigned long base) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0007), + "b" (selector), + "c" (base >> 16), + "d" (base)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_segment_limit( + unsigned short selector, + unsigned limit) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0008), + "b" (selector), + "c" (limit >> 16), + "d" (limit)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_create_code_segment_alias( + unsigned short code_selector, + unsigned short *out_data_selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + movw %%ax,%1 + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=rm" (*out_data_selector) + : "a" (0x000a), + "b" (code_selector)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_descriptor( + unsigned short selector, + struct i386_descriptor *out_descriptor) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000b), + "b" (selector), + "D" (out_descriptor)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_descriptor( + unsigned short selector, + struct i386_descriptor *descriptor) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000c), + "b" (selector), + "D" (descriptor)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_specific_descriptor( + unsigned short selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000d), + "b" (selector)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_exception_handler( + unsigned char trapno, + struct far_pointer_32 *out_vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=c" (out_vector->seg), + "=d" (out_vector->ofs) + : "a" (0x0202), + "b" (trapno)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_exception_handler( + unsigned char trapno, + struct far_pointer_32 *vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0203), + "b" (trapno), + "c" (vector->seg), + "d" (vector->ofs)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_interrupt_handler( + unsigned char intvec, + struct far_pointer_32 *out_vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=c" (out_vector->seg), + "=d" (out_vector->ofs) + : "a" (0x0204), + "b" (intvec)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_interrupt_handler( + unsigned char intvec, + struct far_pointer_32 *vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0205), + "b" (intvec), + "c" (vector->seg), + "d" (vector->ofs)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_simulate_real_mode_interrupt( + unsigned char intnum, + struct real_call_data *call_data) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0300), + "b" ((unsigned short)intnum), + "c" (0), + "D" (call_data)); + + return err; +} + +struct dpmi_version_status +{ + unsigned char minor_version; + unsigned char major_version; + unsigned short flags; + unsigned char slave_pic_base; + unsigned char master_pic_base; + unsigned char processor_type; +}; + +MACH_INLINE void dpmi_get_version(struct dpmi_version_status *status) +{ + asm volatile(" + int $0x31 + " : "=a" (*((short*)&status->minor_version)), + "=b" (status->flags), + "=c" (status->processor_type), + "=d" (*((short*)&status->slave_pic_base)) + : "a" (0x0400)); +} + +MACH_INLINE dpmi_error_t dpmi_allocate_memory( + unsigned size, + unsigned *out_linear_addr, + unsigned *out_mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + shll $16,%%ebx + movw %%cx,%%bx + shll $16,%%esi + movw %%di,%%si + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_linear_addr), + "=S" (*out_mem_handle) + : "a" (0x0501), + "b" (size >> 16), + "c" (size) + : "ebx", "ecx", "esi", "edi"); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_free_memory( + unsigned mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0502), + "S" (mem_handle >> 16), + "D" (mem_handle)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_linear_memory( + unsigned linear_addr, + unsigned size, + unsigned flags, + unsigned *out_linear_addr, + unsigned *out_mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_linear_addr), + "=S" (*out_mem_handle) + : "a" (0x0504), + "b" (linear_addr), + "c" (size), + "d" (flags)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_resize_linear_memory( + unsigned handle, + unsigned new_size, + unsigned flags, + unsigned short *update_selector_array, + unsigned update_selector_count, + unsigned *out_new_linear_addr) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_new_linear_addr) + : "a" (0x0505), + "b" (update_selector_array), + "c" (new_size), + "d" (flags), + "S" (handle), + "D" (update_selector_count)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_map_conventional_memory( + unsigned handle, + vm_offset_t offset, + vm_offset_t low_addr, + vm_size_t page_count) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0509), + "S" (handle), + "b" (offset), + "c" (page_count), + "d" (low_addr)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_lock_linear_region( + vm_offset_t start_la, + vm_size_t size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0600), + "b" (start_la >> 16), + "c" (start_la), + "S" (size >> 16), + "D" (size)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_unlock_linear_region( + vm_offset_t start_la, + vm_size_t size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0601), + "b" (start_la >> 16), + "c" (start_la), + "S" (size >> 16), + "D" (size)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_page_size( + unsigned *out_page_size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + shll $16,%%ebx + movw %%cx,%%bx + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_page_size) + : "a" (0x0604) + : "ecx"); + + return err; +} + + +#endif /* _FLUX_X86_DOS_DPMI_H_ */ diff --git a/apps/rmgr/include/flux/machine/dos/vcpi.h b/apps/rmgr/include/flux/machine/dos/vcpi.h new file mode 100644 index 0000000..99b56b0 --- /dev/null +++ b/apps/rmgr/include/flux/machine/dos/vcpi.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DOS_VCPI_H_ +#define _FLUX_X86_DOS_VCPI_H_ + +struct vcpi_switch_data +{ + vm_offset_t phys_pdir; + vm_offset_t lin_gdt; + vm_offset_t lin_idt; + unsigned short ldt_sel; + unsigned short tss_sel; + unsigned long entry_eip; + unsigned short entry_cs; +}; + +#endif /* _FLUX_X86_DOS_VCPI_H_ */ diff --git a/apps/rmgr/include/flux/machine/eflags.h b/apps/rmgr/include/flux/machine/eflags.h new file mode 100644 index 0000000..7a0cf64 --- /dev/null +++ b/apps/rmgr/include/flux/machine/eflags.h @@ -0,0 +1,53 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_EFLAGS_H_ +#define _FLUX_X86_EFLAGS_H_ + +/* + * i386 flags register + */ +#define EFL_CF 0x00000001 /* carry */ +#define EFL_PF 0x00000004 /* parity of low 8 bits */ +#define EFL_AF 0x00000010 /* carry out of bit 3 */ +#define EFL_ZF 0x00000040 /* zero */ +#define EFL_SF 0x00000080 /* sign */ +#define EFL_TF 0x00000100 /* trace trap */ +#define EFL_IF 0x00000200 /* interrupt enable */ +#define EFL_DF 0x00000400 /* direction */ +#define EFL_OF 0x00000800 /* overflow */ +#define EFL_IOPL 0x00003000 /* IO privilege level: */ +#define EFL_IOPL_KERNEL 0x00000000 /* kernel */ +#define EFL_IOPL_USER 0x00003000 /* user */ +#define EFL_NT 0x00004000 /* nested task */ +#define EFL_RF 0x00010000 /* resume without tracing */ +#define EFL_VM 0x00020000 /* virtual 8086 mode */ +#define EFL_AC 0x00040000 /* alignment check */ +#define EFL_VIF 0x00080000 /* virtual interrupt flag */ +#define EFL_VIP 0x00100000 /* virtual interrupt pending */ +#define EFL_ID 0x00200000 /* CPUID instruction support */ + +#endif _FLUX_X86_EFLAGS_H_ diff --git a/apps/rmgr/include/flux/machine/exec/elf.h b/apps/rmgr/include/flux/machine/exec/elf.h new file mode 100644 index 0000000..0c3f9a1 --- /dev/null +++ b/apps/rmgr/include/flux/machine/exec/elf.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_EXEC_ELF_H_ +#define _FLUX_X86_EXEC_ELF_H_ + +typedef unsigned long Elf32_Addr; +typedef unsigned short Elf32_Half; +typedef unsigned long Elf32_Off; +typedef signed long Elf32_Sword; +typedef unsigned long Elf32_Word; + +/* Architecture identification parameters for x86 architecture. */ +#define MY_EI_DATA ELFDATA2LSB +#define MY_E_MACHINE EM_386 + +#endif /* _FLUX_X86_EXEC_ELF_H_ */ diff --git a/apps/rmgr/include/flux/machine/far_ptr.h b/apps/rmgr/include/flux/machine/far_ptr.h new file mode 100644 index 0000000..cd5c2b6 --- /dev/null +++ b/apps/rmgr/include/flux/machine/far_ptr.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_FAR_PTR_H_ +#define _FLUX_X86_FAR_PTR_H_ + +struct far_pointer_16 +{ + unsigned short ofs; + unsigned short seg; +}; + +struct far_pointer_32 +{ + unsigned long ofs; + unsigned short seg; +}; + +#endif /* _FLUX_X86_FAR_PTR_H_ */ diff --git a/apps/rmgr/include/flux/machine/fdev.h b/apps/rmgr/include/flux/machine/fdev.h new file mode 100644 index 0000000..5e1d99a --- /dev/null +++ b/apps/rmgr/include/flux/machine/fdev.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Machine-specific definitions for device interface. + */ + +#ifndef _FLUX_X86_FDEV_H_ +#define _FLUX_X86_FDEV_H_ + +#include + +#endif /* _FLUX_X86_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/machine/fp_reg.h b/apps/rmgr/include/flux/machine/fp_reg.h new file mode 100644 index 0000000..dbc1055 --- /dev/null +++ b/apps/rmgr/include/flux/machine/fp_reg.h @@ -0,0 +1,108 @@ +/* + * Mach Operating System + * Copyright (c) 1992-1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_FP_REG_H_ +#define _FLUX_X86_FP_REG_H_ +/* + * Floating point registers and status, as saved + * and restored by FP save/restore instructions. + */ +struct i386_fp_save { + unsigned short fp_control; /* control */ + unsigned short fp_unused_1; + unsigned short fp_status; /* status */ + unsigned short fp_unused_2; + unsigned short fp_tag; /* register tags */ + unsigned short fp_unused_3; + unsigned int fp_eip; /* eip at failed instruction */ + unsigned short fp_cs; /* cs at failed instruction */ + unsigned short fp_opcode; /* opcode of failed instruction */ + unsigned int fp_dp; /* data address */ + unsigned short fp_ds; /* data segment */ + unsigned short fp_unused_4; +}; + +struct i386_fp_regs { + unsigned short fp_reg_word[5][8]; + /* space for 8 80-bit FP registers */ +}; + +/* + * Control register + */ +#define FPC_IE 0x0001 /* enable invalid operation + exception */ +#define FPC_IM FPC_IE +#define FPC_DE 0x0002 /* enable denormalized operation + exception */ +#define FPC_DM FPC_DE +#define FPC_ZE 0x0004 /* enable zero-divide exception */ +#define FPC_ZM FPC_ZE +#define FPC_OE 0x0008 /* enable overflow exception */ +#define FPC_OM FPC_OE +#define FPC_UE 0x0010 /* enable underflow exception */ +#define FPC_PE 0x0020 /* enable precision exception */ +#define FPC_PC 0x0300 /* precision control: */ +#define FPC_PC_24 0x0000 /* 24 bits */ +#define FPC_PC_53 0x0200 /* 53 bits */ +#define FPC_PC_64 0x0300 /* 64 bits */ +#define FPC_RC 0x0c00 /* rounding control: */ +#define FPC_RC_RN 0x0000 /* round to nearest or even */ +#define FPC_RC_RD 0x0400 /* round down */ +#define FPC_RC_RU 0x0800 /* round up */ +#define FPC_RC_CHOP 0x0c00 /* chop */ +#define FPC_IC 0x1000 /* infinity control (obsolete) */ +#define FPC_IC_PROJ 0x0000 /* projective infinity */ +#define FPC_IC_AFF 0x1000 /* affine infinity (std) */ + +/* + * Status register + */ +#define FPS_IE 0x0001 /* invalid operation */ +#define FPS_DE 0x0002 /* denormalized operand */ +#define FPS_ZE 0x0004 /* divide by zero */ +#define FPS_OE 0x0008 /* overflow */ +#define FPS_UE 0x0010 /* underflow */ +#define FPS_PE 0x0020 /* precision */ +#define FPS_SF 0x0040 /* stack flag */ +#define FPS_ES 0x0080 /* error summary */ +#define FPS_C0 0x0100 /* condition code bit 0 */ +#define FPS_C1 0x0200 /* condition code bit 1 */ +#define FPS_C2 0x0400 /* condition code bit 2 */ +#define FPS_TOS 0x3800 /* top-of-stack pointer */ +#define FPS_TOS_SHIFT 11 +#define FPS_C3 0x4000 /* condition code bit 3 */ +#define FPS_BUSY 0x8000 /* FPU busy */ + +/* + * Kind of floating-point support provided by kernel. + */ +#define FP_NO 0 /* no floating point */ +#define FP_SOFT 1 /* software FP emulator */ +#define FP_287 2 /* 80287 */ +#define FP_387 3 /* 80387 or 80486 */ + +#endif /* _FLUX_X86_FP_REG_H_ */ diff --git a/apps/rmgr/include/flux/machine/gate_init.h b/apps/rmgr/include/flux/machine/gate_init.h new file mode 100644 index 0000000..0e933b3 --- /dev/null +++ b/apps/rmgr/include/flux/machine/gate_init.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This file defines a simple, clean method provided by the OS toolkit + * for initializing x86 gate descriptors: + * call gates, interrupt gates, trap gates, and task gates. + * Simply create a table of gate_init_entry structures + * (or use the corresponding assembly-language macros below), + * and then call the x86_gate_init() routine. + */ +#ifndef _FLUX_X86_KERN_GATE_INIT_H_ +#define _FLUX_X86_KERN_GATE_INIT_H_ + +#ifndef ASSEMBLER + +#include + +/* One entry in the list of gates to initialized. + Terminate with an entry with a null entrypoint. */ +struct gate_init_entry +{ + unsigned entrypoint; + unsigned short vector; + unsigned short type; +}; + +struct x86_gate; + +__FLUX_BEGIN_DECLS +/* Initialize a set of gates in a descriptor table. + All gates will use the same code segment selector, 'entry_cs'. */ +void gate_init(struct x86_gate *dest, const struct gate_init_entry *src, + unsigned entry_cs); +__FLUX_END_DECLS + +#else /* ASSEMBLER */ + +/* + * We'll be using macros to fill in a table in data hunk 2 + * while writing trap entrypoint routines at the same time. + * Here's the header that comes before everything else. + */ +#define GATE_INITTAB_BEGIN(name) \ + .data 2 ;\ +ENTRY(name) ;\ + .text + +/* + * Interrupt descriptor table and code vectors for it. + */ +#define GATE_ENTRY(n,entry,type) \ + .data 2 ;\ + .long entry ;\ + .word n ;\ + .word type ;\ + .text + +/* + * Terminator for the end of the table. + */ +#define GATE_INITTAB_END \ + .data 2 ;\ + .long 0 ;\ + .text + + +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_KERN_GATE_INIT_H_ */ diff --git a/apps/rmgr/include/flux/machine/gdb.h b/apps/rmgr/include/flux/machine/gdb.h new file mode 100644 index 0000000..101bdb4 --- /dev/null +++ b/apps/rmgr/include/flux/machine/gdb.h @@ -0,0 +1,79 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + * Loosely based on i386-stub.c from GDB 4.14 + */ +/* + * Definitions for remote GDB debugging of x86 programs. + */ +#ifndef _FLUX_X86_GDB_H_ +#define _FLUX_X86_GDB_H_ + +#include + +/* This structure represents the x86 register state frame as GDB wants it. */ +struct gdb_state +{ + unsigned eax; + unsigned ecx; + unsigned edx; + unsigned ebx; + unsigned esp; + unsigned ebp; + unsigned esi; + unsigned edi; + unsigned eip; + unsigned eflags; + unsigned cs; + unsigned ss; + unsigned ds; + unsigned es; + unsigned fs; + unsigned gs; +}; + +struct trap_state; +struct termios; + +/* + * While copying data to or from arbitrary locations, + * the gdb_copyin() and gdb_copyout() routines set this address + * so they can recover from any memory access traps that may occur. + * On receiving a trap, if this address is non-null, + * gdb_trap() simply sets the EIP to it and resumes execution, + * at which point the gdb_copyin/gdb_copyout routines return an error. + * If the default gdb_copyin/gdb_copyout routines are overridden, + * the replacement routines can use this facility as well. + */ +extern unsigned gdb_trap_recover; + +/* + * Use this macro to insert a breakpoint manually anywhere in your code. + */ +#define gdb_breakpoint() asm volatile("int $3"); + + +__FLUX_BEGIN_DECLS +/* + * Set up serial-line debugging over a COM port + */ +void gdb_pc_com_init(int com_port, struct termios *com_params); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_GDB_H_ */ diff --git a/apps/rmgr/include/flux/machine/multiboot.h b/apps/rmgr/include/flux/machine/multiboot.h new file mode 100644 index 0000000..59f88f7 --- /dev/null +++ b/apps/rmgr/include/flux/machine/multiboot.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_MULTIBOOT_H_ +#define _FLUX_X86_MULTIBOOT_H_ + +#include + +/* For a.out kernel boot images, the following header must appear + somewhere in the first 8192 bytes of the kernel image file. */ +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC */ + unsigned magic; + + /* Feature flags - see below. */ + unsigned flags; + + /* Checksum: magic + flags + checksum == 0 */ + unsigned checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + vm_offset_t header_addr; + vm_offset_t load_addr; + vm_offset_t load_end_addr; + vm_offset_t bss_end_addr; + vm_offset_t entry; +}; + +/* The entire multiboot_header must be contained + within the first MULTIBOOT_SEARCH bytes of the kernel image. */ +#define MULTIBOOT_SEARCH 8192 + +/* Magic value identifying the multiboot_header. */ +#define MULTIBOOT_MAGIC 0x1badb002 + +/* Features flags for 'flags'. + If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set + and it doesn't understand it, it must fail. */ +#define MULTIBOOT_MUSTKNOW 0x0000ffff + +/* Align all boot modules on page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must be provided memory information in multiboot_info structure */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Use the load address fields above instead of the ones in the a.out header + to figure out what to load where, and what to do afterwards. + This should only be needed for a.out kernel images + (ELF and other formats can generally provide the needed information). */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* The boot loader passes this value in register EAX to signal the kernel + that the multiboot method is being used */ +#define MULTIBOOT_VALID 0x2badb002 + +/* The boot loader passes this data structure to the kernel in + register EBX on entry. */ +struct multiboot_info +{ + /* These flags indicate which parts of the multiboot_info are valid; + see below for the actual flag bit definitions. */ + unsigned flags; + + /* Lower/Upper memory installed in the machine. + Valid only if MULTIBOOT_MEMORY is set in flags word above. */ + vm_size_t mem_lower; + vm_size_t mem_upper; + + /* BIOS disk device the kernel was loaded from. + Valid only if MULTIBOOT_BOOT_DEVICE is set in flags word above. */ + unsigned char boot_device[4]; + + /* Command-line for the OS kernel: a null-terminated ASCII string. + Valid only if MULTIBOOT_CMDLINE is set in flags word above. */ + vm_offset_t cmdline; + + /* List of boot modules loaded with the kernel. + Valid only if MULTIBOOT_MODS is set in flags word above. */ + unsigned mods_count; + vm_offset_t mods_addr; + + /* Symbol information for a.out or ELF executables. */ + union + { + struct + { + /* a.out symbol information valid only if MULTIBOOT_AOUT_SYMS + is set in flags word above. */ + vm_size_t tabsize; + vm_size_t strsize; + vm_offset_t addr; + unsigned reserved; + } a; + + struct + { + /* ELF section header information valid only if + MULTIBOOT_ELF_SHDR is set in flags word above. */ + unsigned num; + vm_size_t size; + vm_offset_t addr; + unsigned shndx; + } e; + } syms; + + /* Memory map buffer. + Valid only if MULTIBOOT_MEM_MAP is set in flags word above. */ + vm_size_t mmap_count; + vm_offset_t mmap_addr; +}; + +#define MULTIBOOT_MEMORY (1L<<0) +#define MULTIBOOT_BOOT_DEVICE (1L<<1) +#define MULTIBOOT_CMDLINE (1L<<2) +#define MULTIBOOT_MODS (1L<<3) +#define MULTIBOOT_AOUT_SYMS (1L<<4) +#define MULTIBOOT_ELF_SHDR (1L<<5) +#define MULTIBOOT_MEM_MAP (1L<<6) + +/* For use with printf's %b format. */ +#define MULTIBOOT_FLAGS_FORMAT \ + "\20\1MEMORY\2BOOT_DEVICE\3CMDLINE\4MODS\5AOUT_SYMS\6ELF_SHDR\7MEM_MAP" + +/* The mods_addr field above contains the physical address of the first + of 'mods_count' multiboot_module structures. */ +struct multiboot_module +{ + /* Physical start and end addresses of the module data itself. */ + vm_offset_t mod_start; + vm_offset_t mod_end; + + /* Arbitrary ASCII string associated with the module. */ + vm_offset_t string; + + /* Boot loader must set to 0; OS must ignore. */ + unsigned reserved; +}; + + +/* The mmap_addr field above contains the physical address of the first + of the AddrRangeDesc structure. "size" represents the size of the + rest of the structure and optional padding. The offset to the beginning + of the next structure is therefore "size + 4". */ +struct AddrRangeDesc +{ + unsigned long size; + unsigned long BaseAddrLow; + unsigned long BaseAddrHigh; + unsigned long LengthLow; + unsigned long LengthHigh; + unsigned long Type; + + /* unspecified optional padding... */ +}; + +/* usable memory "Type", all others are reserved. */ +#define MB_ARD_MEMORY 1 + + +#endif /* _FLUX_X86_MULTIBOOT_H_ */ diff --git a/apps/rmgr/include/flux/machine/page.h b/apps/rmgr/include/flux/machine/page.h new file mode 100644 index 0000000..cf165a6 --- /dev/null +++ b/apps/rmgr/include/flux/machine/page.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PAGE_H_ +#define _FLUX_X86_PAGE_H_ + +#define PAGE_SHIFT 12 + +#endif /* _FLUX_X86_PAGE_H_ */ diff --git a/apps/rmgr/include/flux/machine/paging.h b/apps/rmgr/include/flux/machine/paging.h new file mode 100644 index 0000000..0b813e7 --- /dev/null +++ b/apps/rmgr/include/flux/machine/paging.h @@ -0,0 +1,182 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Definitions relating to x86 page directories and page tables. + */ +#ifndef _FLUX_X86_PAGING_H_ +#define _FLUX_X86_PAGING_H_ + +#include + +#define INTEL_OFFMASK 0xfff /* offset within page */ +#define PDESHIFT 22 /* page descriptor shift */ +#define PDEMASK 0x3ff /* mask for page descriptor index */ +#define PTESHIFT 12 /* page table shift */ +#define PTEMASK 0x3ff /* mask for page table index */ + +/* + * Convert linear offset to page descriptor/page table index + */ +#define lin2pdenum(a) (((a) >> PDESHIFT) & PDEMASK) +#define lin2ptenum(a) (((a) >> PTESHIFT) & PTEMASK) + +/* + * Convert page descriptor/page table index to linear address + */ +#define pdenum2lin(a) ((vm_offset_t)(a) << PDESHIFT) +#define ptenum2lin(a) ((vm_offset_t)(a) << PTESHIFT) + +/* + * Number of ptes/pdes in a page table/directory. + */ +#define NPTES (ptoa(1)/sizeof(pt_entry_t)) +#define NPDES (ptoa(1)/sizeof(pt_entry_t)) + +/* + * Hardware pte bit definitions (to be used directly on the ptes + * without using the bit fields). + */ +#define INTEL_PTE_VALID 0x00000001 +#define INTEL_PTE_WRITE 0x00000002 +#define INTEL_PTE_USER 0x00000004 +#define INTEL_PTE_WTHRU 0x00000008 +#define INTEL_PTE_NCACHE 0x00000010 +#define INTEL_PTE_REF 0x00000020 +#define INTEL_PTE_MOD 0x00000040 +#define INTEL_PTE_GLOBAL 0x00000100 +#define INTEL_PTE_AVAIL 0x00000e00 +#define INTEL_PTE_PFN 0xfffff000 + +#define INTEL_PDE_VALID 0x00000001 +#define INTEL_PDE_WRITE 0x00000002 +#define INTEL_PDE_USER 0x00000004 +#define INTEL_PDE_WTHRU 0x00000008 +#define INTEL_PDE_NCACHE 0x00000010 +#define INTEL_PDE_REF 0x00000020 +#define INTEL_PDE_MOD 0x00000040 /* only for superpages */ +#define INTEL_PDE_SUPERPAGE 0x00000080 +#define INTEL_PDE_GLOBAL 0x00000100 /* only for superpages */ +#define INTEL_PDE_AVAIL 0x00000e00 +#define INTEL_PDE_PFN 0xfffff000 + +/* + * Macros to translate between page table entry values + * and physical addresses. + */ +#define pa_to_pte(a) ((a) & INTEL_PTE_PFN) +#define pte_to_pa(p) ((p) & INTEL_PTE_PFN) +#define pte_increment_pa(p) ((p) += INTEL_OFFMASK+1) + +#define pa_to_pde(a) ((a) & INTEL_PDE_PFN) +#define pde_to_pa(p) ((p) & INTEL_PDE_PFN) +#define pde_increment_pa(p) ((p) += INTEL_OFFMASK+1) + +/* + * Superpage-related macros. + */ +#define SUPERPAGE_SHIFT PDESHIFT +#define SUPERPAGE_SIZE (1 << SUPERPAGE_SHIFT) +#define SUPERPAGE_MASK (SUPERPAGE_SIZE - 1) + +#define round_superpage(x) ((vm_offset_t)((((vm_offset_t)(x)) \ + + SUPERPAGE_MASK) & ~SUPERPAGE_MASK)) +#define trunc_superpage(x) ((vm_offset_t)(((vm_offset_t)(x)) \ + & ~SUPERPAGE_MASK)) + +#define superpage_aligned(x) ((((vm_offset_t)(x)) & SUPERPAGE_MASK) == 0) + + +#ifndef ASSEMBLER + +#include +#include +#include + +/* + * i386/i486/i860 Page Table Entry + */ +typedef unsigned int pt_entry_t; +#define PT_ENTRY_NULL ((pt_entry_t *) 0) + +typedef unsigned int pd_entry_t; +#define PD_ENTRY_NULL ((pt_entry_t *) 0) + +/* + * Read and write the page directory base register (PDBR). + */ +#define set_pdbr(pdir) set_cr3(pdir) +#define get_pdbr() get_cr3() + +/* + * Invalidate the entire TLB. + */ +#define inval_tlb() set_pdbr(get_pdbr()) + +/* + * Load page directory 'pdir' and turn paging on. + * Assumes that 'pdir' equivalently maps the physical memory + * that contains the currently executing code, + * the currently loaded GDT and IDT, etc. + */ +FLUX_INLINE void paging_enable(vm_offset_t pdir) +{ + /* Load the page directory. */ + set_cr3(pdir); + + /* Turn on paging. */ + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + " : : "r" (get_cr0() | CR0_PG)); +} + +/* + * Turn paging off. + * Assumes that the currently loaded page directory + * equivalently maps the physical memory + * that contains the currently executing code, + * the currently loaded GDT and IDT, etc. + */ +FLUX_INLINE void paging_disable(void) +{ + /* Turn paging off. */ + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + " : : "r" (get_cr0() & ~CR0_PG)); + + /* Flush the TLB. */ + set_cr3(0); +} + +#endif /* !ASSEMBLER */ + +#endif _FLUX_X86_PAGING_H_ diff --git a/apps/rmgr/include/flux/machine/pc/base_irq.h b/apps/rmgr/include/flux/machine/pc/base_irq.h new file mode 100644 index 0000000..3f0a489 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/base_irq.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PC_BASE_IRQ_H_ +#define _FLUX_X86_PC_BASE_IRQ_H_ + + +/* On normal PCs, there are always 16 IRQ lines. */ +#define IRQ_COUNT 16 + + +/* Variables storing the master and slave PIC interrupt vector base. */ +extern int irq_master_base, irq_slave_base; + + +/* Fill an IRQ gate in the base IDT. + Always uses an interrupt gate; just set `access' to the privilege level. */ +#define fill_irq_gate(irq_num, entry, selector, access) \ + fill_gate(&base_idt[(irq_num) < 8 \ + ? irq_master_base+(irq_num) \ + : irq_slave_base+(irq_num)-8], \ + entry, selector, ACC_INTR_GATE | (access), 0) + +#endif /* _FLUX_X86_PC_BASE_IRQ_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/base_multiboot.h b/apps/rmgr/include/flux/machine/pc/base_multiboot.h new file mode 100644 index 0000000..65169df --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/base_multiboot.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Functions and data definitions for kernels + * that want to start up from a MultiBoot boot loader. + */ +#ifndef _FLUX_X86_PC_BASE_MULTIBOOT_H_ +#define _FLUX_X86_PC_BASE_MULTIBOOT_H_ + +#include +#include +#include + +/* + * This variable holds a copy of the multiboot_info structure + * which was passed to us by the boot loader. + */ +extern struct multiboot_info boot_info; + +__FLUX_BEGIN_DECLS +/* + * This function digs through the boot_info structure + * to find out what physical memory is available to us, + * and initalizes the malloc_lmm with those memory regions. + * It is smart enough to skip our own executable, wherever it may be, + * as well as the important stuff passed by the boot loader + * such as our command line and boot modules. + */ +void base_multiboot_init_mem(void); + +/* + * This function parses the command-line passed by the boot loader + * into a nice POSIX-like set of argument and environment strings. + * It depends on being able to call malloc(). + */ +void base_multiboot_init_cmdline(); + +/* + * This is the first C routine called by crt0/multiboot.o; + * its default implementation sets up the base kernel environment + * and then calls main() and exit(). + */ +void multiboot_main(vm_offset_t boot_info_pa); + +/* + * This routine finds the MultiBoot boot module in the boot_info structure + * whose associated `string' matches the provided `string' parameter. + * If the strings attached to boot modules are assumed to be filenames, + * this function can serve as a primitive "open" operation + * for a simple "boot module file system". + */ +struct multiboot_module *base_multiboot_find(const char *string); + +/* + * Dump out the boot_info struct nicely. + */ +void multiboot_info_dump(); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_BASE_MULTIBOOT_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/com_cons.h b/apps/rmgr/include/flux/machine/pc/com_cons.h new file mode 100644 index 0000000..8876e01 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/com_cons.h @@ -0,0 +1,56 @@ +/* + * Simple polling serial console for the Flux OS toolkit + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ +#ifndef _FLUX_X86_PC_COM_CONS_H_ +#define _FLUX_X86_PC_COM_CONS_H_ + +#include + +struct termios; + +__FLUX_BEGIN_DECLS +/* + * This routine must be called once to initialize the COM port. + * The com_port parameter specifies which COM port to use, 1 through 4. + * The supplied termios structure indicates the baud rate and other settings. + * If com_params is NULL, a default of 9600,8,N,1 is used. + */ +void com_cons_init(int com_port, struct termios *com_params); + +/* + * Primary serial character I/O routines. + */ +int com_cons_getchar(void); +void com_cons_putchar(int ch); + +/* + * Since the com_console operates by polling, + * there is no need to handle serial interrupts in order to do basic I/O. + * However, if you want to be notified up when a character is received, + * call this function immediately after com_cons_init(), + * and make sure the appropriate IDT entry is initialized properly. + * For example, the serial debugging code for the PC COM port + * uses this so that the program can be woken up + * when the user presses CTRL-C from the remote debugger. + */ +void com_cons_enable_receive_interrupt(); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_COM_CONS_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/debug.h b/apps/rmgr/include/flux/machine/pc/debug.h new file mode 100644 index 0000000..6ee78cc --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/debug.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _KUKM_I386_PC_DEBUG_H_ +#define _KUKM_I386_PC_DEBUG_H_ + +#ifdef ASSEMBLER +#ifdef DEBUG + + +/* Poke a character directly onto the VGA text display, + as a very quick, mostly-reliable status indicator. + Assumes ss is a kernel data segment register. */ +#define POKE_STATUS(char,scratch) \ + ss/*XXX gas bug */ ;\ + movl %ss:_phys_mem_va,scratch ;\ + addl $0xb8000+80*2*13+40*2,scratch ;\ + movb char,%ss:(scratch) ;\ + movb $0xf0,%ss:1(scratch) + + +#else !DEBUG + +#define POKE_STATUS(char,scratch) + +#endif !DEBUG +#else !ASSEMBLER +#ifdef DEBUG + +#include + + +#define POKE_STATUS(string) \ + ({ unsigned char *s = (string); \ + extern vm_offset_t phys_mem_va; \ + short *d = (short*)(phys_mem_va+0xb8000+80*2*13+40*2); \ + while (*s) { (*d++) = 0x3000 | (*s++); } \ + *d = ' '; \ + }) + + +#else !DEBUG + +#define POKE_STATUS(char) + +#endif !DEBUG +#endif !ASSEMBLER + + +#include_next "debug.h" + +#endif _KUKM_I386_PC_DEBUG_H_ diff --git a/apps/rmgr/include/flux/machine/pc/direct_cons.h b/apps/rmgr/include/flux/machine/pc/direct_cons.h new file mode 100644 index 0000000..8b8b7ef --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/direct_cons.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * The "direct console" is an extremely simple console "driver" for PCs, + * which writes directly to CGA/EGA/VGA display memory to output text, + * and reads directly from the keyboard using polling to read characters. + * The putchar and getchar routines are completely independent; + * either can be used without the other. + */ +#ifndef _FLUX_X86_PC_DIRECT_CONS_H_ +#define _FLUX_X86_PC_DIRECT_CONS_H_ + +#include + +__FLUX_BEGIN_DECLS +void direct_cons_putchar(unsigned char c); +int direct_cons_getchar(void); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_DIRECT_CONS_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/fdev.h b/apps/rmgr/include/flux/machine/pc/fdev.h new file mode 100644 index 0000000..8252a08 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/fdev.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * PC-specific definitions for device interface. + */ + +#ifndef _FLUX_X86_PC_FDEV_H_ +#define _FLUX_X86_PC_FDEV_H_ + +#include + +__FLUX_BEGIN_DECLS +/* + * DRQ manipulation. + */ +int fdev_dma_alloc(int channel); +void fdev_dma_free(int channel); + +/* + * I/O ports (modeled after the Linux interface). + */ +int fdev_port_avail(unsigned port, unsigned size); +void fdev_port_alloc(unsigned port, unsigned size); +void fdev_port_free(unsigned port, unsigned size); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/irq_list.h b/apps/rmgr/include/flux/machine/pc/irq_list.h new file mode 100644 index 0000000..cc3bb05 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/irq_list.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +/* + * This is just a handy file listing all the IRQ's on the PC, + * whether they're on the master or slave PIC, + * what interrupt line on that PIC they're connected to, + * and a simple keyword/string describing their "standard" assignment, if any. + * To use this, just define the 'irq()' macro however you want + * and #include this file in the appropriate place. + */ + +irq(master,0,0,timer) +irq(master,1,1,keyboard) +irq(master,2,2,slave) +irq(master,3,3,com2) +irq(master,4,4,com1) +irq(master,5,5,lpt2) +irq(master,6,6,fd) +irq(master,7,7,lpt1) + +irq(slave,0,8,rtc) +irq(slave,1,9,) +irq(slave,2,10,) +irq(slave,3,11,) +irq(slave,4,12,) +irq(slave,5,13,coprocessor) +irq(slave,6,14,hd) +irq(slave,7,15,) + diff --git a/apps/rmgr/include/flux/machine/pc/keyboard.h b/apps/rmgr/include/flux/machine/pc/keyboard.h new file mode 100644 index 0000000..427f452 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/keyboard.h @@ -0,0 +1,159 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* ********************************************************************** + File: kd.h + Description: definitions for AT keyboard/display driver + Authors: Eugene Kuerner, Adrienne Jardetzky, Mike Kupfer + + $ Header: $ + + Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989. + All rights reserved. +********************************************************************** */ +/* + Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc., +Cupertino, California. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Olivetti +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + + OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* + * Definitions describing the PC keyboard hardware. + */ +#ifndef _FLUX_X86_PC_KEYBOARD_H_ +#define _FLUX_X86_PC_KEYBOARD_H_ + +#include + +/* + * Keyboard I/O ports. + */ +#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ +#define K_STATUS 0x64 /* keybd status (read-only) */ +#define K_CMD 0x64 /* keybd ctlr command (write-only) */ + +/* + * Bit definitions for K_STATUS port. + */ +#define K_OBUF_FUL 0x01 /* output (from keybd) buffer full */ +#define K_IBUF_FUL 0x02 /* input (to keybd) buffer full */ +#define K_SYSFLAG 0x04 /* "System Flag" */ +#define K_CMD_DATA 0x08 /* 1 = input buf has cmd, 0 = data */ +#define K_KBD_INHIBIT 0x10 /* 0 if keyboard inhibited */ +#define K_AUX_OBUF_FUL 0x20 /* 1 = obuf holds aux device data */ +#define K_TIMEOUT 0x40 /* timout error flag */ +#define K_PARITY_ERROR 0x80 /* parity error flag */ + +/* + * Keyboard controller commands (sent to K_CMD port). + */ +#define KC_CMD_READ 0x20 /* read controller command byte */ +#define KC_CMD_WRITE 0x60 /* write controller command byte */ +#define KC_CMD_DIS_AUX 0xa7 /* disable auxiliary device */ +#define KC_CMD_ENB_AUX 0xa8 /* enable auxiliary device */ +#define KC_CMD_TEST_AUX 0xa9 /* test auxiliary device interface */ +#define KC_CMD_SELFTEST 0xaa /* keyboard controller self-test */ +#define KC_CMD_TEST 0xab /* test keyboard interface */ +#define KC_CMD_DUMP 0xac /* diagnostic dump */ +#define KC_CMD_DISABLE 0xad /* disable keyboard */ +#define KC_CMD_ENABLE 0xae /* enable keyboard */ +#define KC_CMD_RDKBD 0xc4 /* read keyboard ID */ +#define KC_CMD_WIN 0xd0 /* read output port */ +#define KC_CMD_WOUT 0xd1 /* write output port */ +#define KC_CMD_ECHO 0xee /* used for diagnostic testing */ +#define KC_CMD_PULSE 0xff /* pulse bits 3-0 based on low nybble */ + +/* + * Keyboard commands (send to K_RDWR). + */ +#define K_CMD_LEDS 0xed /* set status LEDs (caps lock, etc.) */ + +/* + * Bit definitions for controller command byte (sent following + * K_CMD_WRITE command). + */ +#define K_CB_ENBLIRQ 0x01 /* enable data-ready intrpt */ +#define K_CB_SETSYSF 0x04 /* Set System Flag */ +#define K_CB_INHBOVR 0x08 /* Inhibit Override */ +#define K_CB_DISBLE 0x10 /* disable keyboard */ + +/* + * Bit definitions for "Indicator Status Byte" (sent after a + * K_CMD_LEDS command). If the bit is on, the LED is on. Undefined + * bit positions must be 0. + */ +#define K_LED_SCRLLK 0x1 /* scroll lock */ +#define K_LED_NUMLK 0x2 /* num lock */ +#define K_LED_CAPSLK 0x4 /* caps lock */ + +/* + * Bit definitions for "Miscellaneous port B" (K_PORTB). + */ +/* read/write */ +#define K_ENABLETMR2 0x01 /* enable output from timer 2 */ +#define K_SPKRDATA 0x02 /* direct input to speaker */ +#define K_ENABLEPRTB 0x04 /* "enable" port B */ +#define K_EIOPRTB 0x08 /* enable NMI on parity error */ +/* read-only */ +#define K_REFRESHB 0x10 /* refresh flag from INLTCONT PAL */ +#define K_OUT2B 0x20 /* timer 2 output */ +#define K_ICKB 0x40 /* I/O channel check (parity error) */ + +/* + * Bit definitions for the keyboard controller's output port. + */ +#define KO_SYSRESET 0x01 /* processor reset */ +#define KO_GATE20 0x02 /* A20 address line enable */ +#define KO_AUX_DATA_OUT 0x04 /* output data to auxiliary device */ +#define KO_AUX_CLOCK 0x08 /* auxiliary device clock */ +#define KO_OBUF_FUL 0x10 /* keyboard output buffer full */ +#define KO_AUX_OBUF_FUL 0x20 /* aux device output buffer full */ +#define KO_CLOCK 0x40 /* keyboard clock */ +#define KO_DATA_OUT 0x80 /* output data to keyboard */ + +__FLUX_BEGIN_DECLS +extern void kb_command(unsigned char ch); +__FLUX_END_DECLS + +#endif _FLUX_X86_PC_KEYBOARD_H_ diff --git a/apps/rmgr/include/flux/machine/pc/phys_lmm.h b/apps/rmgr/include/flux/machine/pc/phys_lmm.h new file mode 100644 index 0000000..df1dc25 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/phys_lmm.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * PC-specific flag bits and priority values + * for the List Memory Manager (LMM) + * relevant for kernels managing physical memory. + */ +#ifndef _FLUX_X86_PC_PHYS_LMM_H_ +#define _FLUX_X86_PC_PHYS_LMM_H_ + +#include +#include + +/* + * <1MB memory is most precious, then <16MB memory, then high memory. + * Assign priorities to each region accordingly + * so that high memory will be used first when possible, + * then 16MB memory, then 1MB memory. + */ +#define LMM_PRI_1MB -2 +#define LMM_PRI_16MB -1 +#define LMM_PRI_HIGH 0 + +/* + * For memory <1MB, both LMMF_1MB and LMMF_16MB will be set. + * For memory from 1MB to 16MB, only LMMF_16MB will be set. + * For all memory higher than that, neither will be set. + */ +#define LMMF_1MB 0x01 +#define LMMF_16MB 0x02 + +__FLUX_BEGIN_DECLS +/* + * This routine sets up the malloc_lmm with three regions, + * one for each of the memory types above. + * You can then call phys_lmm_add() to add memory to those regions. + */ +void phys_lmm_init(void); + +/* + * Call one of these routines to add a chunk of physical memory found + * to the appropriate region(s) on the malloc_lmm. + * The provided memory block may be arbitrarily aligned + * and may cross region boundaries (e.g. the 16MB boundary); + * it will be shrunken and split apart as necessary. + * Note that these routines take _physical_ addresses, + * not virtual addresses as the underlying LMM routines do. + */ +void phys_lmm_add(vm_offset_t min_pa, vm_size_t size); +void i16_phys_lmm_add(vm_offset_t min_pa, vm_size_t size); +__FLUX_END_DECLS + +/* + * The above routines keep this variable up-to-date + * so that it always records the highest physical memory address seen so far; + * i.e. the end address of the highest free block added to the free list. + * After all physical memory is found and collected on the free list, + * this variable will contain the highest physical memory address + * that the kernel should ever have to deal with. + */ +extern vm_offset_t phys_mem_max; + +#endif /* _FLUX_X86_PC_PHYS_LMM_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/pic.h b/apps/rmgr/include/flux/machine/pc/pic.h new file mode 100644 index 0000000..bcc3049 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/pic.h @@ -0,0 +1,223 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* +Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760 +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and +without fee is hereby granted, provided that the above +copyright notice appears in all copies and that both the +copyright notice and this permission notice appear in +supporting documentation, and that the name of Prime +Computer, Inc. not be used in advertising or publicity +pertaining to distribution of the software without +specific, written prior permission. + +THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER, +INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY +SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR +OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* + * Definitions for the 8259A Programmable Interrupt Controller (PIC) + */ + +#ifndef _I386_PIC_H_ +#define _I386_PIC_H_ + +#include + +#define NINTR 0x10 +#define NPICS 0x02 + +/* +** The following are definitions used to locate the PICs in the system +** XXX "SLAVES" should be spelled "SLAVE". +*/ + +#define MASTER_PIC_BASE 0x20 +#define SLAVES_PIC_BASE 0xa0 +#define OFF_ICW 0x00 +#define OFF_OCW 0x01 + +#define MASTER_ICW (MASTER_PIC_BASE + OFF_ICW) +#define MASTER_OCW (MASTER_PIC_BASE + OFF_OCW) +#define SLAVES_ICW (SLAVES_PIC_BASE + OFF_ICW) +#define SLAVES_OCW (SLAVES_PIC_BASE + OFF_OCW) + +/* +** The following banks of definitions ICW1, ICW2, ICW3, and ICW4 are used +** to define the fields of the various ICWs for initialisation of the PICs +*/ + +/* +** ICW1 +*/ + +#define ICW_TEMPLATE 0x10 + +#define LEVL_TRIGGER 0x08 +#define EDGE_TRIGGER 0x00 +#define ADDR_INTRVL4 0x04 +#define ADDR_INTRVL8 0x00 +#define SINGLE__MODE 0x02 +#define CASCADE_MODE 0x00 +#define ICW4__NEEDED 0x01 +#define NO_ICW4_NEED 0x00 + +/* +** ICW2 +*/ + +#define PICM_VECTBASE IDT_IRQ_BASE +#define PICS_VECTBASE (PICM_VECTBASE + 0x08) + +/* +** ICW3 +*/ + +#define SLAVE_ON_IR0 0x01 +#define SLAVE_ON_IR1 0x02 +#define SLAVE_ON_IR2 0x04 +#define SLAVE_ON_IR3 0x08 +#define SLAVE_ON_IR4 0x10 +#define SLAVE_ON_IR5 0x20 +#define SLAVE_ON_IR6 0x40 +#define SLAVE_ON_IR7 0x80 + +#define I_AM_SLAVE_0 0x00 +#define I_AM_SLAVE_1 0x01 +#define I_AM_SLAVE_2 0x02 +#define I_AM_SLAVE_3 0x03 +#define I_AM_SLAVE_4 0x04 +#define I_AM_SLAVE_5 0x05 +#define I_AM_SLAVE_6 0x06 +#define I_AM_SLAVE_7 0x07 + +/* +** ICW4 +*/ + +#define SNF_MODE_ENA 0x10 +#define SNF_MODE_DIS 0x00 +#define BUFFERD_MODE 0x08 +#define NONBUFD_MODE 0x00 +#define AUTO_EOI_MOD 0x02 +#define NRML_EOI_MOD 0x00 +#define I8086_EMM_MOD 0x01 +#define SET_MCS_MODE 0x00 + +/* +** OCW1 +*/ + +#define PICM_MASK 0xFF +#define PICS_MASK 0xFF + +/* +** OCW2 +*/ + +#define NON_SPEC_EOI 0x20 +#define SPECIFIC_EOI 0x60 +#define ROT_NON_SPEC 0xa0 +#define SET_ROT_AEOI 0x80 +#define RSET_ROTAEOI 0x00 +#define ROT_SPEC_EOI 0xe0 +#define SET_PRIORITY 0xc0 +#define NO_OPERATION 0x40 + +#define SEND_EOI_IR0 0x00 +#define SEND_EOI_IR1 0x01 +#define SEND_EOI_IR2 0x02 +#define SEND_EOI_IR3 0x03 +#define SEND_EOI_IR4 0x04 +#define SEND_EOI_IR5 0x05 +#define SEND_EOI_IR6 0x06 +#define SEND_EOI_IR7 0x07 + +/* +** OCW3 +*/ + +#define OCW_TEMPLATE 0x08 +#define SPECIAL_MASK 0x40 +#define MASK_MDE_SET 0x20 +#define MASK_MDE_RST 0x00 +#define POLL_COMMAND 0x04 +#define NO_POLL_CMND 0x00 +#define READ_NEXT_RD 0x02 +#define READ_IR_ONRD 0x00 +#define READ_IS_ONRD 0x01 + + +/* +** Standard PIC initialization values for PCs. +*/ +#define PICM_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICM_ICW3 (SLAVE_ON_IR2) +#define PICM_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +#define PICS_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICS_ICW3 (I_AM_SLAVE_2) +#define PICS_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +__FLUX_BEGIN_DECLS +extern void pic_init(unsigned char master_base, unsigned char slave_base); +extern void pic_disable_irq(unsigned char irq); +extern void pic_enable_irq(unsigned char irq); +__FLUX_END_DECLS + +#include + +#define pic_enable_all() ({ \ + outb(MASTER_OCW, 0); \ + outb(SLAVES_OCW, 0); \ +}) + +#define pic_disable_all() ({ \ + outb(MASTER_OCW, PICM_MASK); \ + outb(SLAVES_OCW, PICS_MASK); \ +}) + +#define pic_ack(irq) ({ \ + outb(MASTER_ICW, NON_SPEC_EOI); \ + if ((irq) >= 8) \ + outb(SLAVES_ICW, NON_SPEC_EOI); \ +}) + +#endif _I386_PIC_H_ diff --git a/apps/rmgr/include/flux/machine/pc/pit.h b/apps/rmgr/include/flux/machine/pc/pit.h new file mode 100644 index 0000000..25d9339 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/pit.h @@ -0,0 +1,90 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Intel +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef _FLUX_X86_PC_PIT_H_ +#define _FLUX_X86_PC_PIT_H_ + +#include + +/* Definitions for 8254 Programmable Interrupt Timer ports on AT 386 */ +#define PITCTR0_PORT 0x40 /* counter 0 port */ +#define PITCTR1_PORT 0x41 /* counter 1 port */ +#define PITCTR2_PORT 0x42 /* counter 2 port */ +#define PITCTL_PORT 0x43 /* PIT control port */ +#define PITAUX_PORT 0x61 /* PIT auxiliary port */ +/* bits used in auxiliary control port for timer 2 */ +#define PITAUX_GATE2 0x01 /* aux port, PIT gate 2 input */ +#define PITAUX_OUT2 0x02 /* aux port, PIT clock out 2 enable */ + + +/* Following are used for Timer 0 */ +#define PIT_C0 0x00 /* select counter 0 */ +#define PIT_LOADMODE 0x30 /* load least significant byte followed + * by most significant byte */ +#define PIT_NDIVMODE 0x04 /*divide by N counter */ +#define PIT_SQUAREMODE 0x06 /* square-wave mode */ + +/* Used for Timer 1. Used for delay calculations in countdown mode */ +#define PIT_C1 0x40 /* select counter 1 */ +#define PIT_READMODE 0x30 /* read or load least significant byte + * followed by most significant byte */ +#define PIT_RATEMODE 0x06 /* square-wave mode for USART */ + +/* + * Clock speed for the timer in hz divided by the constant HZ + * (defined in param.h) + */ +#define CLKNUM 1193167 + + +__FLUX_BEGIN_DECLS +void init_pit(int hz); +__FLUX_END_DECLS + + +#endif /* _FLUX_X86_PC_PIT_H_ */ + diff --git a/apps/rmgr/include/flux/machine/pc/reset.h b/apps/rmgr/include/flux/machine/pc/reset.h new file mode 100644 index 0000000..43f6726 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/reset.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_X86_PC_RESET_H_ +#define _FLUX_X86_PC_RESET_H_ + +#include + +__FLUX_BEGIN_DECLS +void pc_reset(void); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_RESET_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/rtc.h b/apps/rmgr/include/flux/machine/pc/rtc.h new file mode 100644 index 0000000..010277c --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/rtc.h @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * from: @(#)rtc.h 7.1 (Berkeley) 5/12/91 + * $\Id: rtc.h,v 1.7 1994/12/04 20:22:20 joerg Exp $ + */ +/* + * Things of use when manipulating the Real Time Clock or other stuff + * in NVRAM. + */ + +#ifndef _FLUX_X86_PC_RTC_H_ +#define _FLUX_X86_PC_RTC_H_ + +#include + +__FLUX_BEGIN_DECLS +unsigned char rtcin(unsigned char addr); +void rtcout(unsigned char addr, unsigned char val); +__FLUX_END_DECLS + +/* + * RTC Register locations + */ + +#define RTC_SEC 0x00 /* seconds */ +#define RTC_SECALRM 0x01 /* seconds alarm */ +#define RTC_MIN 0x02 /* minutes */ +#define RTC_MINALRM 0x03 /* minutes alarm */ +#define RTC_HRS 0x04 /* hours */ +#define RTC_HRSALRM 0x05 /* hours alarm */ +#define RTC_WDAY 0x06 /* week day */ +#define RTC_DAY 0x07 /* day of month */ +#define RTC_MONTH 0x08 /* month of year */ +#define RTC_YEAR 0x09 /* month of year */ + +#define RTC_STATUSA 0x0a /* status register A */ +#define RTCSA_TUP 0x80 /* time update, don't look now */ +#define RTCSA_DIVIDER 0x20 /* divider correct for 32768 Hz */ +#define RTCSA_8192 0x03 +#define RTCSA_4096 0x04 +#define RTCSA_2048 0x05 +#define RTCSA_1024 0x06 /* default for profiling */ +#define RTCSA_PROF RTCSA_1024 +#define RTC_PROFRATE 1024 +#define RTCSA_512 0x07 +#define RTCSA_256 0x08 +#define RTCSA_128 0x09 +#define RTCSA_NOPROF RTCSA_128 +#define RTC_NOPROFRATE 128 +#define RTCSA_64 0x0a +#define RTCSA_32 0x0b + +#define RTC_STATUSB 0x0b /* status register B */ +#define RTCSB_DST 0x01 /* Daylight Savings Time enable */ +#define RTCSB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */ +#define RTCSB_BCD 0x04 /* 0 = BCD, 1 = Binary coded time */ +#define RTCSB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */ +#define RTCSB_UINTR 0x10 /* 1 = enable update-ended interrupt */ +#define RTCSB_AINTR 0x20 /* 1 = enable alarm interrupt */ +#define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */ +#define RTCSB_HALT 0x80 /* stop clock updates */ + +#define RTC_INTR 0x0c /* status register C (R) interrupt source */ +#define RTCIR_UPDATE 0x10 /* update intr */ +#define RTCIR_ALARM 0x20 /* alarm intr */ +#define RTCIR_PERIOD 0x40 /* periodic intr */ +#define RTCIR_INT 0x80 /* interrupt output signal */ + +#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ +#define RTCSD_PWR 0x80 /* clock lost power */ + +#define RTC_DIAG 0x0e /* status register E - bios diagnostic */ +#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" + +#define RTC_RESET 0x0f /* status register F - reset code byte */ +#define RTCRS_RST 0x00 /* normal reset */ +#define RTCRS_LOAD 0x04 /* load system */ + +#define RTC_FDISKETTE 0x10 /* diskette drive type in upper/lower nibble */ +#define RTCFDT_NONE 0 /* none present */ +#define RTCFDT_360K 0x10 /* 360K */ +#define RTCFDT_12M 0x20 /* 1.2M */ +#define RTCFDT_720K 0x30 /* 720K */ +#define RTCFDT_144M 0x40 /* 1.44M */ +#define RTCFDT_288M 0x60 /* 2.88M */ + +#define RTC_BASELO 0x15 /* low byte of basemem size */ +#define RTC_BASEHI 0x16 /* high byte of basemem size */ +#define RTC_EXTLO 0x17 /* low byte of ext mem size, see RTC_DEXTLO */ +#define RTC_EXTHI 0x18 /* high byte of ext mem size, see RTC_DEXTHI */ + +/* + * These two should return the same info as INT 0x15 function 88. + * However, _The_Undocumented_PC_ (page 644) says IBM PS/1 and PS/2 + * systems use 0x35 and 0x36 for this purpose. + */ +#define RTC_DEXTLO 0x30 /* low byte of DETECTED extended mem size */ +#define RTC_DEXTHI 0x31 /* high byte of DETECTED extended mem size */ + +#define RTC_CENTURY 0x32 /* current century */ + +#endif /* _FLUX_X86_PC_RTC_H_ */ diff --git a/apps/rmgr/include/flux/machine/pc/serial_gdb.h b/apps/rmgr/include/flux/machine/pc/serial_gdb.h new file mode 100644 index 0000000..c68f7d0 --- /dev/null +++ b/apps/rmgr/include/flux/machine/pc/serial_gdb.h @@ -0,0 +1,34 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ +#ifndef _FLUX_X86_PC_SERIAL_GDB_H_ +#define _FLUX_X86_PC_SERIAL_GDB_H_ + +#include + +extern int serial_gdb_enable; + +__FLUX_BEGIN_DECLS +extern void serial_gdb_init(); +extern int serial_gdb_signal(int *inout_sig, struct trap_state *ts); +extern void serial_gdb_shutdown(int exitcode); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_SERIAL_GDB_H_ */ diff --git a/apps/rmgr/include/flux/machine/pio.h b/apps/rmgr/include/flux/machine/pio.h new file mode 100644 index 0000000..bb1845d --- /dev/null +++ b/apps/rmgr/include/flux/machine/pio.h @@ -0,0 +1,108 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_PIO_H_ +#define _FLUX_X86_PIO_H_ + +#ifdef __GNUC__ + +/* This is a more reliable delay than a few short jmps. */ +#define iodelay() \ + asm volatile("pushl %eax; inb $0x80,%al; inb $0x80,%al; popl %eax") + +#define inl(port) \ +({ unsigned long _tmp__; \ + asm volatile("inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inl_p(port) ({ \ + unsigned long r; \ + r = inl(port); \ + iodelay(); \ + r; \ +}) + +#define inw(port) \ +({ unsigned short _tmp__; \ + asm volatile(".byte 0x66; inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inw_p(port) ({ \ + unsigned short r; \ + r = inw(port); \ + iodelay(); \ + r; \ +}) + +#define inb(port) \ +({ unsigned char _tmp__; \ + asm volatile("inb %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inb_p(port) ({ \ + unsigned char r; \ + r = inb(port); \ + iodelay(); \ + r; \ +}) + + +#define outl(port, val) \ +({ asm volatile("outl %0, %1" : : "a" (val) , "d" ((unsigned short)(port))); }) +#define outl_p(port, val) ({ \ + outl(port, val); \ + iodelay(); \ +}) + +#define outw(port, val) \ +({asm volatile(".byte 0x66; outl %0, %1" : : "a" ((unsigned short)(val)) , "d" ((unsigned short)(port))); }) +#define outw_p(port, val) ({ \ + outw(port, val); \ + iodelay(); \ +}) + +#define outb(port, val) \ +({ asm volatile("outb %0, %1" : : "a" ((unsigned char)(val)) , "d" ((unsigned short)(port))); }) +#define outb_p(port, val) ({ \ + outb(port, val); \ + iodelay(); \ +}) + + +/* Inline code works just as well for 16-bit code as for 32-bit. */ +#define i16_inl(port) inl(port) +#define i16_inl_p(port) inl_p(port) +#define i16_inw(port) inw(port) +#define i16_inw_p(port) inw_p(port) +#define i16_inb(port) inb(port) +#define i16_inb_p(port) inb_p(port) +#define i16_outl(port, val) outl(port, val) +#define i16_outl_p(port, val) outl_p(port, val) +#define i16_outw(port, val) outw(port, val) +#define i16_outw_p(port, val) outw_p(port, val) +#define i16_outb(port, val) outb(port, val) +#define i16_outb_p(port, val) outb_p(port, val) + +#endif __GNUC__ + +#endif /* _FLUX_X86_PIO_H_ */ diff --git a/apps/rmgr/include/flux/machine/pmode.h b/apps/rmgr/include/flux/machine/pmode.h new file mode 100644 index 0000000..591302a --- /dev/null +++ b/apps/rmgr/include/flux/machine/pmode.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PMODE_H_ +#define _FLUX_X86_PMODE_H_ + +#include +#include + + + +/* Enter protected mode on x86 machines. + Assumes: + * Running in real mode. + * Interrupts are turned off. + * A20 is enabled (if on a PC). + * A suitable GDT is already loaded. + + You must supply a 16-bit code segment + equivalent to the real-mode code segment currently in use. + + You must reload all segment registers except CS + immediately after invoking this macro. +*/ +FLUX_INLINE void i16_enter_pmode(int prot_cs) +{ + /* Switch to protected mode. */ + asm volatile(" + movl %0,%%cr0 + ljmp %1,$1f + 1: + " : : "r" (i16_get_cr0() | CR0_PE), "i" (prot_cs)); +} + + + +/* Leave protected mode and return to real mode. + Assumes: + * Running in protected mode + * Interrupts are turned off. + * Paging is turned off. + * All currently loaded segment registers + contain 16-bit segments with limits of 0xffff. + + You must supply a real-mode code segment + equivalent to the protected-mode code segment currently in use. + + You must reload all segment registers except CS + immediately after invoking this function. +*/ +FLUX_INLINE void i16_leave_pmode(int real_cs) +{ + /* Switch back to real mode. + Note: switching to the real-mode code segment + _must_ be done with an _immediate_ far jump, + not an indirect far jump. At least on my Am386DX/40, + an indirect far jump leaves the code segment read-only. */ + { + extern unsigned short real_jmp[]; + + real_jmp[3] = real_cs; + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + real_jmp: + _real_jmp: + ljmp $0,$1f + 1: + " : : "r" (i16_get_cr0() & ~CR0_PE)); + } +} + + + +#endif _FLUX_X86_PMODE_H_ diff --git a/apps/rmgr/include/flux/machine/proc_reg.h b/apps/rmgr/include/flux/machine/proc_reg.h new file mode 100644 index 0000000..9a93f14 --- /dev/null +++ b/apps/rmgr/include/flux/machine/proc_reg.h @@ -0,0 +1,410 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Processor registers for i386 and i486. + */ +#ifndef _FLUX_X86_PROC_REG_H_ +#define _FLUX_X86_PROC_REG_H_ + +#include + +/* + * CR0 + */ +#define CR0_PG 0x80000000 /* enable paging */ +#define CR0_CD 0x40000000 /* i486: cache disable */ +#define CR0_NW 0x20000000 /* i486: no write-through */ +#define CR0_AM 0x00040000 /* i486: alignment check mask */ +#define CR0_WP 0x00010000 /* i486: write-protect kernel access */ +#define CR0_NE 0x00000020 /* i486: handle numeric exceptions */ +#define CR0_ET 0x00000010 /* extension type is 80387 */ + /* (not official) */ +#define CR0_TS 0x00000008 /* task switch */ +#define CR0_EM 0x00000004 /* emulate coprocessor */ +#define CR0_MP 0x00000002 /* monitor coprocessor */ +#define CR0_PE 0x00000001 /* enable protected mode */ + +/* + * CR4 + */ +#define CR4_VME 0x00000001 /* enable virtual intrs in v86 mode */ +#define CR4_PVI 0x00000002 /* enable virtual intrs in pmode */ +#define CR4_TSD 0x00000004 /* disable RDTSC in user mode */ +#define CR4_DE 0x00000008 /* debug extensions (I/O breakpoints) */ +#define CR4_PSE 0x00000010 /* page size extensions */ +#define CR4_PGE 0x00000020 /* page global extensions */ +#define CR4_MCE 0x00000040 /* machine check exception */ +#define CR4_PCE 0x00000100 /* enable read perf counter instr */ + +#ifndef ASSEMBLER +#ifdef __GNUC__ + +#include + + +/* Some processors, notably my Am386DX/40, + seem to have some rather subtle pipeline- or timing-related bugs + which case really weird things to happen with pushf's and popf's + that come too close together... */ + +FLUX_INLINE unsigned get_eflags() +{ + unsigned eflags; + asm volatile(" + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: pushf + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: popl %0" : "=r" (eflags)); + return eflags; +} + +FLUX_INLINE void set_eflags(unsigned eflags) +{ + asm volatile(" + pushl %0 + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: popf + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: " : : "r" (eflags)); +} + +FLUX_INLINE void cli() { asm volatile("cli"); } +FLUX_INLINE void sti() { asm volatile("sti"); } +FLUX_INLINE void cld() { asm volatile("cld"); } +#ifdef __cplusplus +/* in C++, std is a reserved keyword -- so use a function macro instead */ +#define std() asm volatile("std") +#else +FLUX_INLINE void std() { asm volatile("std"); } +#endif +FLUX_INLINE void clts() { asm volatile("clts"); } + +FLUX_INLINE unsigned short get_cs() +{ + unsigned short cs; + asm volatile("movw %%cs,%w0" : "=r" (cs)); + return cs; +} + +FLUX_INLINE unsigned short get_ds() +{ + unsigned short ds; + asm volatile("movw %%ds,%w0" : "=r" (ds)); + return ds; +} +FLUX_INLINE void set_ds(unsigned short ds) +{ + asm volatile("movw %w0,%%ds" : : "r" (ds)); +} + +FLUX_INLINE unsigned short get_es() +{ + unsigned short es; + asm volatile("movw %%es,%w0" : "=r" (es)); + return es; +} +FLUX_INLINE void set_es(unsigned short es) +{ + asm volatile("movw %w0,%%es" : : "r" (es)); +} + +FLUX_INLINE unsigned short get_fs() +{ + unsigned short fs; + asm volatile("movw %%fs,%w0" : "=r" (fs)); + return fs; +} +FLUX_INLINE void set_fs(unsigned short fs) +{ + asm volatile("movw %w0,%%fs" : : "r" (fs)); +} + +FLUX_INLINE unsigned short get_gs() +{ + unsigned short gs; + asm volatile("movw %%gs,%w0" : "=r" (gs)); + return gs; +} +FLUX_INLINE void set_gs(unsigned short gs) +{ + asm volatile("movw %w0,%%gs" : : "r" (gs)); +} + +FLUX_INLINE unsigned short get_ss() +{ + unsigned short ss; + asm volatile("movw %%ss,%w0" : "=r" (ss)); + return ss; +} +FLUX_INLINE void set_ss(unsigned short ss) +{ + asm volatile("movw %w0,%%ss" : : "r" (ss)); +} + +#define get_eax() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%eax, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ebx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ebx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ecx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ecx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_edx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%edx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_esi() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%esi, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_edi() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%edi, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ebp() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ebp, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_esp() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%esp, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_eflags() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("pushf; popl %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_cr0() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("mov %%cr0, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define set_cr0(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr0" : : "r" (_temp__)); \ + }) + +#ifdef HAVE_CR4 +#define get_cr4() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("mov %%cr4, %0" : "=r" (_temp__)); \ + _temp__; \ + }) +#define set_cr4(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr4" : : "r" (_temp__)); \ + }) +#else /* not HAVE_CR4 */ +#define get_cr4() \ + ({ \ + register unsigned int _temp__; \ + asm volatile(".byte 0x0f,0x20,0xe0" : "=a" (_temp__)); \ + _temp__; \ + }) +#define set_cr4(value) \ + asm volatile(".byte 0x0f,0x22,0xe0" : : "a" (value)); +#endif /* HAVE_CR4 */ + +#define get_msw() \ + ({ \ + unsigned short _msw__; \ + asm volatile("smsw %0" : "=r" (_msw__)); \ + msw; \ + }) + +#define get_cr2() \ + ({ \ + register unsigned int _temp__; \ + asm("mov %%cr2, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_cr3() \ + ({ \ + register unsigned int _temp__; \ + asm("mov %%cr3, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define set_cr3(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr3" : : "r" (_temp__)); \ + }) + +#define set_ts() \ + set_cr0(get_cr0() | CR0_TS) + +#define clear_ts() \ + asm volatile("clts") + +#define get_tr() \ + ({ \ + unsigned short _seg__; \ + asm volatile("str %0" : "=rm" (_seg__) ); \ + _seg__; \ + }) + +#define set_tr(seg) \ + asm volatile("ltr %0" : : "rm" ((unsigned short)(seg)) ) + +#define set_gdt(pseudo_desc) \ + ({ \ + asm volatile("lgdt %0" : : "m" ((pseudo_desc)->limit)); \ + }) + +#define set_idt(pseudo_desc) \ + ({ \ + asm volatile("lidt %0" : : "m" ((pseudo_desc)->limit)); \ + }) + +#define get_ldt() \ + ({ \ + unsigned short _seg__; \ + asm volatile("sldt %0" : "=rm" (_seg__) ); \ + _seg__; \ + }) + +#define set_ldt(seg) \ + asm volatile("lldt %0" : : "rm" ((unsigned short)(seg)) ) + +/* + * Read the 64-bit timestamp counter (TSC) register. + * Works only on Pentium and higher processors, + * and in user mode only if the TSD bit in CR4 is not set. + */ +#if HAVE_RDTSC +#define get_tsc() \ + ({ \ + unsigned long low, high; \ + asm volatile("rdtsc" : "=d" (high), "=a" (low)); \ + ((unsigned long long)high << 32) | low; \ + }) +#else +#define get_tsc() \ + ({ \ + unsigned long low, high; \ + asm volatile( \ + ".byte 0x0f; .byte 0x31" \ + : "=d" (high), "=a" (low)); \ + ((unsigned long long)high << 32) | low; \ + }) +#endif + +/* + * This doesn't set a processor register, + * but it's often used immediately after setting one, + * to flush the instruction queue. + */ +#define flush_instr_queue() \ + asm volatile(" + jmp 0f + 0: + ") + +/* Inline functions work fine for 16-bit code as well. */ +#ifdef CODE16 +#define i16_get_eflags get_eflags +#define i16_set_eflags set_eflags +#define i16_cli cli +#define i16_sti sti +#define i16_cld cld +#define i16_std std +#define i16_clts clts +#define i16_get_cs get_cs +#define i16_set_cs set_cs +#define i16_get_ds get_ds +#define i16_set_ds set_ds +#define i16_get_es get_es +#define i16_set_es set_es +#define i16_get_fs get_fs +#define i16_set_fs set_fs +#define i16_get_gs get_gs +#define i16_set_gs set_gs +#define i16_get_ss get_ss +#define i16_set_ss set_ss +#define i16_get_cr0 get_cr0 +#define i16_set_cr0 set_cr0 +#define i16_get_cr3 get_cr3 +#define i16_set_cr3 set_cr3 +#define i16_get_msw get_msw +#define i16_set_gdt set_gdt +#define i16_set_idt set_idt +#define i16_set_ldt set_ldt +#define i16_set_tr set_tr +#define i16_flush_instr_queue flush_instr_queue +#endif + +#endif /* __GNUC__ */ +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_PROC_REG_H_ */ diff --git a/apps/rmgr/include/flux/machine/seg.h b/apps/rmgr/include/flux/machine/seg.h new file mode 100644 index 0000000..6c73c20 --- /dev/null +++ b/apps/rmgr/include/flux/machine/seg.h @@ -0,0 +1,199 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * Copyright (c) 1991 IBM Corporation + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation, + * and that the name IBM not be used in advertising or publicity + * pertaining to distribution of the software without specific, written + * prior permission. + * + * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_SEG_H_ +#define _FLUX_X86_SEG_H_ + + +/* + * x86 segmentation. + */ + +#ifndef ASSEMBLER + +/* + * Real segment descriptor. + */ +struct x86_desc { + unsigned int limit_low:16, /* limit 0..15 */ + base_low:16, /* base 0..15 */ + base_med:8, /* base 16..23 */ + access:8, /* access byte */ + limit_high:4, /* limit 16..19 */ + granularity:4, /* granularity */ + base_high:8; /* base 24..31 */ +}; + +/* + * Trap, interrupt, or call gate. + */ +struct x86_gate { + unsigned int offset_low:16, /* offset 0..15 */ + selector:16, + word_count:8, + access:8, + offset_high:16; /* offset 16..31 */ +}; + +#endif !ASSEMBLER + +#define SZ_32 0x4 /* 32-bit segment */ +#define SZ_16 0x0 /* 16-bit segment */ +#define SZ_G 0x8 /* 4K limit field */ + +#define ACC_A 0x01 /* accessed */ +#define ACC_TYPE 0x1e /* type field: */ + +#define ACC_TYPE_SYSTEM 0x00 /* system descriptors: */ + +#define ACC_LDT 0x02 /* LDT */ +#define ACC_CALL_GATE_16 0x04 /* 16-bit call gate */ +#define ACC_TASK_GATE 0x05 /* task gate */ +#define ACC_TSS 0x09 /* task segment */ +#define ACC_CALL_GATE 0x0c /* call gate */ +#define ACC_INTR_GATE 0x0e /* interrupt gate */ +#define ACC_TRAP_GATE 0x0f /* trap gate */ + +#define ACC_TSS_BUSY 0x02 /* task busy */ + +#define ACC_TYPE_USER 0x10 /* user descriptors */ + +#define ACC_DATA 0x10 /* data */ +#define ACC_DATA_W 0x12 /* data, writable */ +#define ACC_DATA_E 0x14 /* data, expand-down */ +#define ACC_DATA_EW 0x16 /* data, expand-down, + writable */ +#define ACC_CODE 0x18 /* code */ +#define ACC_CODE_R 0x1a /* code, readable */ +#define ACC_CODE_C 0x1c /* code, conforming */ +#define ACC_CODE_CR 0x1e /* code, conforming, + readable */ +#define ACC_PL 0x60 /* access rights: */ +#define ACC_PL_K 0x00 /* kernel access only */ +#define ACC_PL_U 0x60 /* user access */ +#define ACC_P 0x80 /* segment present */ + +/* + * Components of a selector + */ +#define SEL_LDT 0x04 /* local selector */ +#define SEL_PL 0x03 /* privilege level: */ +#define SEL_PL_K 0x00 /* kernel selector */ +#define SEL_PL_U 0x03 /* user selector */ + +/* + * Convert selector to descriptor table index. + */ +#define sel_idx(sel) ((sel)>>3) + + +#ifndef ASSEMBLER + +#include + +/* Return the privilege level of a segment selector */ +#define ISPL(s) ((s) & SEL_PL) + +#define USERMODE(s, f) (ISPL(s) == SEL_PL_U || ((f) & EFL_VM) != 0) +#define KERNELMODE(s, f) (ISPL(s) == SEL_PL_K && ((f) & EFL_VM) == 0) + + +/* Format of a "pseudo-descriptor", used for loading the IDT and GDT. */ +struct pseudo_descriptor +{ + short pad; + unsigned short limit; + unsigned long linear_base; +}; + + +/* Fill a segment descriptor. */ +FLUX_INLINE void +fill_descriptor(struct x86_desc *desc, unsigned base, unsigned limit, + unsigned char access, unsigned char sizebits) +{ + if (limit > 0xfffff) + { + limit >>= 12; + sizebits |= SZ_G; + } + desc->limit_low = limit & 0xffff; + desc->base_low = base & 0xffff; + desc->base_med = (base >> 16) & 0xff; + desc->access = access | ACC_P; + desc->limit_high = limit >> 16; + desc->granularity = sizebits; + desc->base_high = base >> 24; +} + +/* Set the base address in a segment descriptor. */ +FLUX_INLINE void +fill_descriptor_base(struct x86_desc *desc, unsigned base) +{ + desc->base_low = base & 0xffff; + desc->base_med = (base >> 16) & 0xff; + desc->base_high = base >> 24; +} + +/* Set the limit in a segment descriptor. */ +FLUX_INLINE void +fill_descriptor_limit(struct x86_desc *desc, unsigned limit) +{ + if (limit > 0xfffff) + { + limit >>= 12; + desc->granularity |= SZ_G; + } + else + desc->granularity &= ~SZ_G; + desc->limit_low = limit & 0xffff; + desc->limit_high = limit >> 16; +} + +/* Fill a gate with particular values. */ +FLUX_INLINE void +fill_gate(struct x86_gate *gate, unsigned offset, unsigned short selector, + unsigned char access, unsigned char word_count) +{ + gate->offset_low = offset & 0xffff; + gate->selector = selector; + gate->word_count = word_count; + gate->access = access | ACC_P; + gate->offset_high = (offset >> 16) & 0xffff; +} + +#ifdef CODE16 +#define i16_fill_descriptor fill_descriptor +#define i16_fill_gate fill_gate +#endif + +#endif !ASSEMBLER + +#endif /* _FLUX_X86_SEG_H_ */ diff --git a/apps/rmgr/include/flux/machine/smp/asm-smp.h b/apps/rmgr/include/flux/machine/smp/asm-smp.h new file mode 100644 index 0000000..13e59eb --- /dev/null +++ b/apps/rmgr/include/flux/machine/smp/asm-smp.h @@ -0,0 +1,269 @@ +#ifndef _FLUX_X86_SMP_ASM_SMP_H_ +#define _FLUX_X86_SMP_ASM_SMP_H_ + +#ifdef __SMP__ +#ifndef ASSEMBLY + +#include +#include +#if 0 +#include +#include +#include +#endif + +/* + * Support definitions for SMP machines following the intel multiprocessing + * specification + */ + +/* + * This tag identifies where the SMP configuration + * information is. + */ + +#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') + +struct intel_mp_floating +{ + char mpf_signature[4]; /* "_MP_" */ + unsigned long mpf_physptr; /* Configuration table address */ + unsigned char mpf_length; /* Our length (paragraphs) */ + unsigned char mpf_specification;/* Specification version */ + unsigned char mpf_checksum; /* Checksum (makes sum 0) */ + unsigned char mpf_feature1; /* Standard or configuration ? */ + unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ + unsigned char mpf_feature3; /* Unused (0) */ + unsigned char mpf_feature4; /* Unused (0) */ + unsigned char mpf_feature5; /* Unused (0) */ +}; + +struct mp_config_table +{ + char mpc_signature[4]; +#define MPC_SIGNATURE "PCMP" + unsigned short mpc_length; /* Size of table */ + char mpc_spec; /* 0x01 */ + char mpc_checksum; + char mpc_oem[8]; + char mpc_productid[12]; + unsigned long mpc_oemptr; /* 0 if not present */ + unsigned short mpc_oemsize; /* 0 if not present */ + unsigned short mpc_oemcount; + unsigned long mpc_lapic; /* APIC address */ + unsigned long reserved; +}; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 + +struct mpc_config_processor +{ + unsigned char mpc_type; + unsigned char mpc_apicid; /* Local APIC number */ + unsigned char mpc_apicver; /* Its versions */ + unsigned char mpc_cpuflag; +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + unsigned long mpc_cpufeature; +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + unsigned long mpc_featureflag; /* CPUID feature value */ + unsigned long mpc_reserved[2]; +}; + +struct mpc_config_bus +{ + unsigned char mpc_type; + unsigned char mpc_busid; + unsigned char mpc_bustype[6] __attribute((packed)); +}; + +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" + +/* We don't understand the others */ + +struct mpc_config_ioapic +{ + unsigned char mpc_type; + unsigned char mpc_apicid; + unsigned char mpc_apicver; + unsigned char mpc_flags; +#define MPC_APIC_USABLE 0x01 + unsigned long mpc_apicaddr; +}; + +struct mpc_config_intsrc +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbus; + unsigned char mpc_srcbusirq; + unsigned char mpc_dstapic; + unsigned char mpc_dstirq; +}; + +#define MP_INT_VECTORED 0 +#define MP_INT_NMI 1 +#define MP_INT_SMI 2 +#define MP_INT_EXTINT 3 + +#define MP_IRQDIR_DEFAULT 0 +#define MP_IRQDIR_HIGH 1 +#define MP_IRQDIR_LOW 3 + + +struct mpc_config_intlocal +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbusid; + unsigned char mpc_srcbusirq; + unsigned char mpc_destapic; +#define MP_APIC_ALL 0xFF + unsigned char mpc_destapiclint; +}; + + +/* + * Default configurations + * + * 1 2 CPU ISA 82489DX + * 2 2 CPU EISA 82489DX no IRQ 8 or timer chaining + * 3 2 CPU EISA 82489DX + * 4 2 CPU MCA 82489DX + * 5 2 CPU ISA+PCI + * 6 2 CPU EISA+PCI + * 7 2 CPU MCA+PCI + */ + +/* + * Per process x86 parameters + */ + +struct cpuinfo_x86 +{ + char hard_math; + char x86; + char x86_model; + char x86_mask; + char x86_vendor_id[16]; + int x86_capability; + int fdiv_bug; + int have_cpuid; + char wp_works_ok; + char hlt_works_ok; + unsigned long udelay_val; +}; + + +extern struct cpuinfo_x86 cpu_data[NR_CPUS]; + +__FLUX_BEGIN_DECLS +/* + * Private routines/data + */ + +extern int smp_found_config; +extern int smp_scan_config(unsigned long, unsigned long); +extern unsigned long smp_alloc_memory(unsigned long mem_base); + +#if 0 +extern unsigned char *apic_reg; +#endif 0 + +extern unsigned char *kernel_stacks[NR_CPUS]; +extern unsigned char boot_cpu_id; +extern unsigned long cpu_present_map; +extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int cpu_logical_map[NR_CPUS]; +extern volatile unsigned long smp_invalidate_needed; +extern void smp_flush_tlb(void); +extern volatile unsigned long kernel_flag, kernel_counter; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; +extern volatile unsigned char active_kernel_processor; +#if 0 +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); +extern unsigned long ipi_count; +extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern volatile unsigned long kernel_counter; +extern volatile unsigned long syscall_count; +#endif 0 + +/* + * General functions that each host system must provide. + */ + +extern void smp_callin(void); +extern int smp_boot_cpus(void); +extern void smp_store_cpu_info(int id); /* Store per cpu info (like the initial udelay numbers */ +__FLUX_END_DECLS + +extern volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ +extern volatile unsigned long smp_process_available; + +/* + * APIC handlers: Note according to the Intel specification update + * you should put reads between APIC writes. + * Intel Pentium processor specification update [11AP, pg 64] + * "Back to Back Assertions of HOLD May Cause Lost APIC Write Cycle" + */ + +extern __inline void apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(apic_reg+reg))=v; +} + +extern __inline unsigned long apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(apic_reg+reg)); +} + +/* + * This function is needed by all SMP systems. It must _always_ be valid from the initial + * startup. This may require magic on some systems (in the i86 case we dig out the boot + * cpu id from the config and set up a fake apic_reg pointer so that before we activate + * the apic we get the right answer). Hopefully other processors are more sensible 8) + */ + +extern __inline int smp_processor_id(void) +{ + return GET_APIC_ID(apic_read(APIC_ID)); +} + +#endif /* !ASSEMBLY */ + +#define NO_PROC_ID 0xFF /* No processor magic marker */ + +/* + * This magic constant controls our willingness to transfer + * a process across CPUs. Such a transfer incurs misses on the L1 + * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My + * gut feeling is this will vary by board in value. For a board + * with separate L2 cache it probably depends also on the RSS, and + * for a board with shared L2 cache it ought to decay fast as other + * processes are run. + */ + +#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ + +#define SMP_FROM_INT 1 +#define SMP_FROM_SYSCALL 2 + +#endif +#endif diff --git a/apps/rmgr/include/flux/machine/smp/bitops.h b/apps/rmgr/include/flux/machine/smp/bitops.h new file mode 100644 index 0000000..b71ea9d --- /dev/null +++ b/apps/rmgr/include/flux/machine/smp/bitops.h @@ -0,0 +1,137 @@ +#ifndef _FLUX_X86_SMP_BITOPS_H_ +#define _FLUX_X86_SMP_BITOPS_H_ + +/* + * Copyright 1992, Linus Torvalds. + */ + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef __SMP__ +#define LOCK_PREFIX "lock ; " +#define SMPVOL volatile +#else +#define LOCK_PREFIX "" +#define SMPVOL +#endif + +/* + * Some hacks to defeat gcc over-optimizations.. + */ +struct __dummy { unsigned long a[100]; }; +#define ADDR (*(struct __dummy *) addr) +#define CONST_ADDR (*(const struct __dummy *) addr) + +extern __inline__ int set_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +extern __inline__ int clear_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +extern __inline__ int change_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +/* + * This routine doesn't need to be atomic. + */ +extern __inline__ int test_bit(int nr, const SMPVOL void * addr) +{ + return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; +} + +/* + * Find-bit routines.. + */ +extern __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int res; + + if (!size) + return 0; + __asm__("cld\n\t" + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res) + :"c" ((size + 31) >> 5), "D" (addr), "b" (addr) + :"ax", "cx", "di"); + return res; +} + +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#endif /* _I386_BITOPS_H */ diff --git a/apps/rmgr/include/flux/machine/smp/i82489.h b/apps/rmgr/include/flux/machine/smp/i82489.h new file mode 100644 index 0000000..4a286c2 --- /dev/null +++ b/apps/rmgr/include/flux/machine/smp/i82489.h @@ -0,0 +1,88 @@ +#ifndef _FLUX_X86_SMP_I82489_H_ +#define _FLUX_X86_SMP_I82489_H_ + +/* + * Offsets for programming the 82489 and Pentium integrated APIC + * + * Alan Cox , 1995. + */ + +#define APIC_ID 0x20 +#define GET_APIC_ID(x) (((x)>>24)&0x0F) +#define APIC_VERSION 0x30 +#define APIC_TASKPRI 0x80 +#define APIC_TPRI_MASK 0xFF +#define APIC_ARBPRI 0x90 +#define APIC_PROCPRI 0xA0 +#define APIC_EOI 0xB0 +#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ +#define APIC_RRR 0xC0 +#define APIC_LDR 0xD0 +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define APIC_DFR 0xE0 +#define GET_APIC_DFR(x) (((x)>>28)&0x0F) +#define SET_APIC_DFR(x) ((x)<<28) +#define APIC_SPIV 0xF0 +#define APIC_ISR 0x100 +#define APIC_TMR 0x180 +#define APIC_IRR 0x200 +#define APIC_ESR 0x280 +#define APIC_ESR_SEND_CS 0x00001 +#define APIC_ESR_RECV_CS 0x00002 +#define APIC_ESR_SEND_ACC 0x00004 +#define APIC_ESR_RECV_ACC 0x00008 +#define APIC_ESR_SENDILL 0x00020 +#define APIC_ESR_RECVILL 0x00040 +#define APIC_ESR_ILLREGA 0x00080 +#define APIC_ICR 0x300 +#define APIC_DEST_FIELD 0x00000 +#define APIC_DEST_SELF 0x40000 +#define APIC_DEST_ALLINC 0x80000 +#define APIC_DEST_ALLBUT 0xC0000 +#define APIC_DEST_RR_MASK 0x30000 +#define APIC_DEST_RR_INVALID 0x00000 +#define APIC_DEST_RR_INPROG 0x10000 +#define APIC_DEST_RR_VALID 0x20000 +#define APIC_DEST_LEVELTRIG 0x08000 +#define APIC_DEST_ASSERT 0x04000 +#define APIC_DEST_BUSY 0x01000 +#define APIC_DEST_LOGICAL 0x00800 +#define APIC_DEST_DM_FIXED 0x00000 +#define APIC_DEST_DM_LOWEST 0x00100 +#define APIC_DEST_DM_SMI 0x00200 +#define APIC_DEST_DM_REMRD 0x00300 +#define APIC_DEST_DM_NMI 0x00400 +#define APIC_DEST_DM_INIT 0x00500 +#define APIC_DEST_DM_STARTUP 0x00600 +#define APIC_DEST_VECTOR_MASK 0x000FF +#define APIC_ICR2 0x310 +#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) +#define SET_APIC_DEST_FIELD(x) ((x)<<24) +#define APIC_LVTT 0x320 +#define APIC_LVT0 0x350 +#define APIC_LVT_TIMER_PERIODIC (1<<17) +#define APIC_LVT_MASKED (1<<16) +#define APIC_LVT_LEVEL_TRIGGER (1<<15) +#define APIC_LVT_REMOTE_IRR (1<<14) +#define APIC_INPUT_POLARITY (1<<13) +#define APIC_SEND_PENDING (1<<12) +#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define APIC_MODE_FIXED 0x0 +#define APIC_MODE_NMI 0x4 +#define APIC_MODE_EXINT 0x7 +#define APIC_LVT1 0x360 +#define APIC_LVERR 0x370 +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 +#define APIC_TDCR 0x3E0 +#define APIC_TDR_DIV_1 0xB +#define APIC_TDR_DIV_2 0x0 +#define APIC_TDR_DIV_4 0x1 +#define APIC_TDR_DIV_8 0x2 +#define APIC_TDR_DIV_16 0x3 +#define APIC_TDR_DIV_32 0x8 +#define APIC_TDR_DIV_64 0x9 +#define APIC_TDR_DIV_128 0xA + +#endif diff --git a/apps/rmgr/include/flux/machine/smp/linux-smp.h b/apps/rmgr/include/flux/machine/smp/linux-smp.h new file mode 100644 index 0000000..dec0b2f --- /dev/null +++ b/apps/rmgr/include/flux/machine/smp/linux-smp.h @@ -0,0 +1,58 @@ +#ifndef _FLUX_X86_SMP_LINUX_SMP_H_ +#define _FLUX_X86_SMP_LINUX_SMP_H_ + +/* + * Generic SMP support + * Alan Cox. + */ + +#ifdef __SMP__ +#include +#include + +__FLUX_BEGIN_DECLS +extern void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern int smp_boot_cpus(void); /* Boot processor call to load the other CPU's */ +extern void smp_callin(void); /* Processor call in. Must hold processors until .. */ +extern void smp_commence(void); /* Multiprocessors may now schedule */ +__FLUX_END_DECLS + +extern int smp_num_cpus; +extern int smp_threads_ready; /* True once the per process idle is forked */ +#ifdef __SMP_PROF__ +extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */ +extern volatile unsigned long smp_spins_sys_idle[]; /* count of idle spins */ +extern volatile unsigned long smp_spins_syscall[]; /* count of syscall spins */ +extern volatile unsigned long smp_spins_syscall_cur[]; /* count of syscall spins for the current + call */ +extern volatile unsigned long smp_idle_count[1+NR_CPUS];/* count idle ticks */ +extern volatile unsigned long smp_idle_map; /* map with idle cpus */ +#else +extern volatile unsigned long smp_spins; +#endif + + +extern volatile unsigned long smp_msg_data; +extern volatile int smp_src_cpu; +extern volatile int smp_msg_id; + +#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ +#define MSG_ALL 0x8001 + +#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */ +#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's when rebooting */ +#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU */ + +#else + +/* + * These macros fold the SMP functionality into a single CPU system + */ + +#define smp_num_cpus 1 +#define smp_processor_id() 0 +#define smp_message_pass(t,m,d,w) +#define smp_threads_ready 1 +#define kernel_lock() +#endif +#endif diff --git a/apps/rmgr/include/flux/machine/smp/smp.h b/apps/rmgr/include/flux/machine/smp/smp.h new file mode 100644 index 0000000..630968b --- /dev/null +++ b/apps/rmgr/include/flux/machine/smp/smp.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + */ + +#ifndef _FLUX_X86_SMP_SMP_H_ +#define _FLUX_X86_SMP_SMP_H_ + +#define __SMP__ +#define NR_CPUS 32 +extern unsigned long apic_addr; +#define apic_reg ((unsigned char *)(apic_addr)) + +#endif diff --git a/apps/rmgr/include/flux/machine/spin_lock.h b/apps/rmgr/include/flux/machine/spin_lock.h new file mode 100644 index 0000000..16cbd37 --- /dev/null +++ b/apps/rmgr/include/flux/machine/spin_lock.h @@ -0,0 +1,57 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_SPIN_LOCK_H_ +#define _FLUX_X86_SPIN_LOCK_H_ + +typedef volatile int spin_lock_t; + +#define SPIN_LOCK_INITIALIZER 0 + +#define spin_lock_init(s) (*(s) = 0) +#define spin_lock_locked(s) (*(s) != 0) + +#ifdef __GNUC__ + +#define spin_unlock(p) \ + ({ register int _u__ ; \ + __asm__ volatile("xorl %0, %0; \n\ + xchgl %0, %1" \ + : "=&r" (_u__), "=m" (*(p)) ); \ + 0; }) + +#define spin_try_lock(p)\ + (!({ register int _r__; \ + __asm__ volatile("movl $1, %0; \n\ + xchgl %0, %1" \ + : "=&r" (_r__), "=m" (*(p)) ); \ + _r__; })) + +#define spin_lock(p) \ + ({ while (!spin_try_lock(p)) while (*(p)); }) + +#endif /* __GNUC__ */ + +#endif /* _FLUX_X86_SPIN_LOCK_H_ */ diff --git a/apps/rmgr/include/flux/machine/trap.h b/apps/rmgr/include/flux/machine/trap.h new file mode 100644 index 0000000..bc98c8a --- /dev/null +++ b/apps/rmgr/include/flux/machine/trap.h @@ -0,0 +1,61 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_TRAP_H_ +#define _FLUX_X86_TRAP_H_ + +/* + * Hardware trap vectors for i386. + */ +#define T_DIVIDE_ERROR 0 +#define T_DEBUG 1 +#define T_NMI 2 /* non-maskable interrupt */ +#define T_INT3 3 /* int 3 instruction */ +#define T_OVERFLOW 4 /* overflow test */ +#define T_OUT_OF_BOUNDS 5 /* bounds check */ +#define T_INVALID_OPCODE 6 /* invalid op code */ +#define T_NO_FPU 7 /* no floating point */ +#define T_DOUBLE_FAULT 8 /* double fault */ +#define T_FPU_FAULT 9 +#define T_INVALID_TSS 10 +#define T_SEGMENT_NOT_PRESENT 11 +#define T_STACK_FAULT 12 +#define T_GENERAL_PROTECTION 13 +#define T_PAGE_FAULT 14 +/* 15 */ +#define T_FLOATING_POINT_ERROR 16 +#define T_ALIGNMENT_CHECK 17 +#define T_MACHINE_CHECK 18 + +/* + * Page-fault trap codes. + */ +#define T_PF_PROT 0x1 /* protection violation */ +#define T_PF_WRITE 0x2 /* write access */ +#define T_PF_USER 0x4 /* from user state */ + + +#endif _FLUX_X86_TRAP_H_ diff --git a/apps/rmgr/include/flux/machine/tss.h b/apps/rmgr/include/flux/machine/tss.h new file mode 100644 index 0000000..fa7bae7 --- /dev/null +++ b/apps/rmgr/include/flux/machine/tss.h @@ -0,0 +1,66 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_TSS_H_ +#define _FLUX_X86_TSS_H_ + +/* + * Intel x86 32-bit Task State Segment + */ +struct x86_tss { + int back_link; /* segment number of previous task, + if nested */ + int esp0; /* initial stack pointer ... */ + int ss0; /* and segment for ring 0 */ + int esp1; /* initial stack pointer ... */ + int ss1; /* and segment for ring 1 */ + int esp2; /* initial stack pointer ... */ + int ss2; /* and segment for ring 2 */ + int cr3; /* CR3 - page table directory + physical address */ + int eip; + int eflags; + int eax; + int ecx; + int edx; + int ebx; + int esp; /* current stack pointer */ + int ebp; + int esi; + int edi; + int es; + int cs; + int ss; /* current stack segment */ + int ds; + int fs; + int gs; + int ldt; /* local descriptor table segment */ + unsigned short trace_trap; /* trap on switch to this task */ + unsigned short io_bit_map_offset; + /* offset to start of IO permission + bit map */ +}; + +#endif /* _FLUX_X86_TSS_H_ */ diff --git a/apps/rmgr/include/flux/machine/types.h b/apps/rmgr/include/flux/machine/types.h new file mode 100644 index 0000000..878e55d --- /dev/null +++ b/apps/rmgr/include/flux/machine/types.h @@ -0,0 +1,103 @@ +/* + * Mach Operating System + * Copyright (c) 1992,1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Header file containing basic types for the x86 architecture. + */ +#ifndef _FLUX_X86_TYPES_H_ +#define _FLUX_X86_TYPES_H_ + +/* + * A natural_t is the type for the native + * integer type, e.g. 32 or 64 or.. whatever + * register size the machine has. Unsigned, it is + * used for entities that might be either + * unsigned integers or pointers, and for + * type-casting between the two. + * For instance, the IPC system represents + * a port in user space as an integer and + * in kernel space as a pointer. + */ +typedef unsigned int natural_t; + +/* + * An integer_t is the signed counterpart + * of the natural_t type. Both types are + * only supposed to be used to define + * other types in a machine-independent + * way. + */ +typedef int integer_t; + +/* + * A vm_offset_t is a type-neutral pointer, + * e.g. an offset into a virtual memory space. + */ +typedef natural_t vm_offset_t; + +/* + * A vm_size_t is the proper type for e.g. + * expressing the difference between two + * vm_offset_t entities. + */ +typedef natural_t vm_size_t; + +/* + * On any anchitecture, + * these types are _exactly_ as wide as indicated in their names. + */ +typedef signed char signed8_t; +typedef signed short signed16_t; +typedef signed long signed32_t; +typedef signed long long signed64_t; +typedef unsigned char unsigned8_t; +typedef unsigned short unsigned16_t; +typedef unsigned long unsigned32_t; +typedef unsigned long long unsigned64_t; +typedef float float32_t; +typedef double float64_t; + +/* + * On any given architecture, + * these types are guaranteed to be _at_least_ + * as wide as indicated in their names, + * but may be wider if a wider type can be more efficiently accessed. + * + * On the x86, bytes and 32-bit words are fast, + * but 16-bit words are slow; + * this property is reflected in these type definitions. + */ +typedef unsigned char boolean_t; +typedef signed char signed_min8_t; +typedef unsigned char unsigned_min8_t; +typedef signed int signed_min16_t; +typedef unsigned int unsigned_min16_t; +typedef signed int signed_min32_t; +typedef unsigned int unsigned_min32_t; + +#endif /* _FLUX_X86_TYPES_H_ */ diff --git a/apps/rmgr/include/flux/memdebug.h b/apps/rmgr/include/flux/memdebug.h new file mode 100644 index 0000000..5f862bc --- /dev/null +++ b/apps/rmgr/include/flux/memdebug.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_MEMDEBUG_H_ +#define _FLUX_MEMDEBUG_H_ + +/* + * We define this so malloc.h/stdlib.h knows not to prototype + * malloc and friends. + * Otherwise the prototypes will get macro expanded and bad things will + * happen. + */ +#define MALLOC_IS_MACRO + +#include + +#ifndef _SIZE_T +#define _SIZE_T +typedef __flux_size_t size_t; +#endif + +#define malloc(s) memdebug_traced_malloc(s, __FILE__, __LINE__) +#define memalign(a, s) memdebug_traced_memalign(a, s, __FILE__, __LINE__) +#define calloc(n, s) memdebug_traced_calloc(n, s, __FILE__, __LINE__) +#define realloc(m, s) memdebug_traced_realloc(m, s, __FILE__, __LINE__) +#define free(p) memdebug_traced_free(p, __FILE__, __LINE__) + +#define smalloc(s) memdebug_traced_smalloc(s, __FILE__, __LINE__) +#define smemalign(a, s) memdebug_traced_smemalign(a, s, __FILE__, __LINE__) +/* XXX these two are yet to be implemented. */ +/* #define scalloc(n, s) memdebug_traced_scalloc(n, s, __FILE__, __LINE__) */ +/* #define srealloc(m, s) memdebug_traced_srealloc(m, s, __FILE__, __LINE__) */ +#define sfree(p, s) memdebug_traced_sfree(p, s, __FILE__, __LINE__) + +__FLUX_BEGIN_DECLS + +/* + * Mark all currently allocated blocks, for a future memdebug_check(). + */ +void memdebug_mark(void); + +/* + * Look for allocated blocks that are unmarked--ie, alloced and + * not free'd since the last memdebug_mark(). + */ +void memdebug_check(void); + +/* + * Run a set of vailidity checks on the given memory block ptr. + */ +#define memdebug_ptrchk(ptr) memdebug_traced_ptrchk(ptr, __FILE__, __LINE__); +int memdebug_traced_ptrchk(void *__ptr, char *file, int line); + +/* + * Sweep through all allocated memory blocks and do a validity check. + */ +void memdebug_sweep(void); + +/* + * These functions are defined in libmemdebug, and are not meant to be + * used directly, but via the macros defined above. But who am I to + * tell you what to do. + */ +void *memdebug_traced_malloc(size_t bytes, char *file, int line); +void *memdebug_traced_memalign(size_t alignment, size_t size, char *file, int line); +void *memdebug_traced_calloc(size_t n, size_t elem_size, char *file, int line); +void memdebug_traced_free(void* mem, char *file, int line); +void *memdebug_traced_realloc(void* oldmem, size_t bytes, char *file, int line); +void *memdebug_traced_smalloc (size_t size, char *file, int line); +void *memdebug_traced_smemalign(size_t alignment, size_t size, char *file, int line); +void memdebug_traced_sfree(void* mem, size_t chunksize, char *file, int line); + +int memdebug_printf(const char *fmt, ...); + +__FLUX_END_DECLS + +#endif _FLUX_MEMDEBUG_H_ diff --git a/apps/rmgr/include/flux/page.h b/apps/rmgr/include/flux/page.h new file mode 100644 index 0000000..56e21b1 --- /dev/null +++ b/apps/rmgr/include/flux/page.h @@ -0,0 +1,80 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: flux/page.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young, Bryan Ford + * + * Machine independent virtual memory parameters. + * In this file, the term "page" refers to the _minimum_ page size + * supported by the hardware architecture, and is always a power of two. + * Some architectures and OS environments support optional + * larger page sizes as well, and/or unaligned "block mappings". + */ +#ifndef _FLUX_PAGE_H_ +#define _FLUX_PAGE_H_ + +#include + +#ifndef PAGE_SHIFT +#error flux/machine/page.h needs to define PAGE_SHIFT. +#endif + +#ifndef PAGE_SIZE +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif + +#ifndef PAGE_MASK +#define PAGE_MASK (PAGE_SIZE-1) +#endif + +/* + * Convert addresses to pages and vice versa. + * No rounding is used. + */ + +#define atop(x) (((vm_size_t)(x)) >> PAGE_SHIFT) +#define ptoa(x) ((vm_offset_t)((x) << PAGE_SHIFT)) + +/* + * Round off or truncate to the nearest page. These will work + * for either addresses or counts. (i.e. 1 byte rounds to 1 page + * bytes. + */ + +#define round_page(x) ((vm_offset_t)((((vm_offset_t)(x)) + PAGE_MASK) & ~PAGE_MASK)) +#define trunc_page(x) ((vm_offset_t)(((vm_offset_t)(x)) & ~PAGE_MASK)) + +/* + * Determine whether an address is page-aligned, or a count is + * an exact page multiple. + */ + +#define page_aligned(x) ((((vm_offset_t) (x)) & PAGE_MASK) == 0) + +#endif /* _FLUX_PAGE_H_ */ diff --git a/apps/rmgr/include/flux/queue.h b/apps/rmgr/include/flux/queue.h new file mode 100644 index 0000000..a1e9611 --- /dev/null +++ b/apps/rmgr/include/flux/queue.h @@ -0,0 +1,377 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon rights + * to redistribute these changes. + */ +/* + * File: queue.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * Type definitions for generic queues. + * + */ + +#ifndef _KERN_QUEUE_H_ +#define _KERN_QUEUE_H_ + +/* + * Queue of abstract objects. Queue is maintained + * within that object. + * + * Supports fast removal from within the queue. + * + * How to declare a queue of elements of type "foo_t": + * In the "*foo_t" type, you must have a field of + * type "queue_chain_t" to hold together this queue. + * There may be more than one chain through a + * "foo_t", for use by different queues. + * + * Declare the queue as a "queue_t" type. + * + * Elements of the queue (of type "foo_t", that is) + * are referred to by reference, and cast to type + * "queue_entry_t" within this module. + */ + +/* + * A generic doubly-linked list (queue). + */ + +struct queue_entry { + struct queue_entry *next; /* next element */ + struct queue_entry *prev; /* previous element */ +}; + +typedef struct queue_entry *queue_t; +typedef struct queue_entry queue_head_t; +typedef struct queue_entry queue_chain_t; +typedef struct queue_entry *queue_entry_t; + +/* + * Macro: queue_init + * Function: + * Initialize the given queue. + * Header: + * void queue_init(q) + * queue_t q; *MODIFIED* + */ +#define queue_init(q) ((q)->next = (q)->prev = q) + +/* + * Macro: queue_first + * Function: + * Returns the first entry in the queue, + * Header: + * queue_entry_t queue_first(q) + * queue_t q; *IN* + */ +#define queue_first(q) ((q)->next) + +/* + * Macro: queue_next + * Function: + * Returns the entry after an item in the queue. + * Header: + * queue_entry_t queue_next(qc) + * queue_t qc; + */ +#define queue_next(qc) ((qc)->next) + +/* + * Macro: queue_last + * Function: + * Returns the last entry in the queue. + * Header: + * queue_entry_t queue_last(q) + * queue_t q; *IN* + */ +#define queue_last(q) ((q)->prev) + +/* + * Macro: queue_prev + * Function: + * Returns the entry before an item in the queue. + * Header: + * queue_entry_t queue_prev(qc) + * queue_t qc; + */ +#define queue_prev(qc) ((qc)->prev) + +/* + * Macro: queue_end + * Function: + * Tests whether a new entry is really the end of + * the queue. + * Header: + * boolean_t queue_end(q, qe) + * queue_t q; + * queue_entry_t qe; + */ +#define queue_end(q, qe) ((q) == (qe)) + +/* + * Macro: queue_empty + * Function: + * Tests whether a queue is empty. + * Header: + * boolean_t queue_empty(q) + * queue_t q; + */ +#define queue_empty(q) queue_end((q), queue_first(q)) + + +/*----------------------------------------------------------------*/ +/* + * Macros that operate on generic structures. The queue + * chain may be at any location within the structure, and there + * may be more than one chain. + */ + +/* + * Macro: queue_enter + * Function: + * Insert a new element at the tail of the queue. + * Header: + * void queue_enter(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter(head, elt, type, field) \ +{ \ + register queue_entry_t prev; \ + \ + prev = (head)->prev; \ + if ((head) == prev) { \ + (head)->next = (queue_entry_t) (elt); \ + } \ + else { \ + ((type)prev)->field.next = (queue_entry_t)(elt);\ + } \ + (elt)->field.prev = prev; \ + (elt)->field.next = head; \ + (head)->prev = (queue_entry_t) elt; \ +} + +/* + * Macro: queue_enter_first + * Function: + * Insert a new element at the head of the queue. + * Header: + * void queue_enter_first(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter_first(head, elt, type, field) \ +{ \ + register queue_entry_t next; \ + \ + next = (head)->next; \ + if ((head) == next) { \ + (head)->prev = (queue_entry_t) (elt); \ + } \ + else { \ + ((type)next)->field.prev = (queue_entry_t)(elt);\ + } \ + (elt)->field.next = next; \ + (elt)->field.prev = head; \ + (head)->next = (queue_entry_t) elt; \ +} + +/* + * Macro: queue_enter_before + * Function: + * Insert a new element before the indicated element. + * Header: + * void queue_enter_before(q, nelt, elt, type, field) + * queue_t q; + * nelt, elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter_before(head, nelt, elt, type, field) \ +{ \ + register queue_entry_t prev; \ + \ + (elt)->field.next = (queue_entry_t)(nelt); \ + if ((head) == (queue_entry_t)(nelt)) { \ + (elt)->field.prev = (head)->prev; \ + prev = (head)->prev; \ + (head)->prev = (queue_entry_t)(elt); \ + } else { \ + (elt)->field.prev = (nelt)->field.prev; \ + prev = (nelt)->field.prev; \ + (nelt)->field.prev = (queue_entry_t)(elt); \ + } \ + if ((head) == prev) \ + (head)->next = (queue_entry_t)(elt); \ + else \ + ((type)prev)->field.next = (queue_entry_t)(elt);\ +} + +/* + * Macro: queue_enter_after + * Function: + * Insert a new element after the indicated element. + * Header: + * void queue_enter_after(q, pelt, elt, type, field) + * queue_t q; + * pelt, elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter_after(head, pelt, elt, type, field) \ +{ \ + register queue_entry_t next; \ + \ + (elt)->field.prev = (queue_entry_t)(pelt); \ + if ((head) == (queue_entry_t)(pelt)) { \ + (elt)->field.next = (head)->next; \ + next = (head)->next; \ + (head)->next = (queue_entry_t)(elt); \ + } else { \ + (elt)->field.next = (pelt)->field.next; \ + next = (pelt)->field.next; \ + (pelt)->field.next = (queue_entry_t)(elt); \ + } \ + if ((head) == next) \ + (head)->prev = (queue_entry_t)(elt); \ + else \ + ((type)next)->field.prev = (queue_entry_t)(elt);\ +} + +/* + * Macro: queue_field [internal use only] + * Function: + * Find the queue_chain_t (or queue_t) for the + * given element (thing) in the given queue (head) + */ +#define queue_field(head, thing, type, field) \ + (((head) == (thing)) ? (head) : &((type)(thing))->field) + +/* + * Macro: queue_remove + * Function: + * Remove an arbitrary item from the queue. + * Header: + * void queue_remove(q, qe, type, field) + * arguments as in queue_enter + */ +#define queue_remove(head, elt, type, field) \ +{ \ + register queue_entry_t next, prev; \ + \ + next = (elt)->field.next; \ + prev = (elt)->field.prev; \ + \ + if ((head) == next) \ + (head)->prev = prev; \ + else \ + ((type)next)->field.prev = prev; \ + \ + if ((head) == prev) \ + (head)->next = next; \ + else \ + ((type)prev)->field.next = next; \ +} + +/* + * Macro: queue_remove_first + * Function: + * Remove and return the entry at the head of + * the queue. + * Header: + * queue_remove_first(head, entry, type, field) + * entry is returned by reference + */ +#define queue_remove_first(head, entry, type, field) \ +{ \ + register queue_entry_t next; \ + \ + (entry) = (type) ((head)->next); \ + next = (entry)->field.next; \ + \ + if ((head) == next) \ + (head)->prev = (head); \ + else \ + ((type)(next))->field.prev = (head); \ + (head)->next = next; \ +} + +/* + * Macro: queue_remove_last + * Function: + * Remove and return the entry at the tail of + * the queue. + * Header: + * queue_remove_last(head, entry, type, field) + * entry is returned by reference + */ +#define queue_remove_last(head, entry, type, field) \ +{ \ + register queue_entry_t prev; \ + \ + (entry) = (type) ((head)->prev); \ + prev = (entry)->field.prev; \ + \ + if ((head) == prev) \ + (head)->next = (head); \ + else \ + ((type)(prev))->field.next = (head); \ + (head)->prev = prev; \ +} + +/* + * Macro: queue_assign + */ +#define queue_assign(to, from, type, field) \ +{ \ + ((type)((from)->prev))->field.next = (to); \ + ((type)((from)->next))->field.prev = (to); \ + *to = *from; \ +} + +/* + * Macro: queue_iterate + * Function: + * iterate over each item in the queue. + * Generates a 'for' loop, setting elt to + * each item in turn (by reference). + * Header: + * queue_iterate(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_iterate(head, elt, type, field) \ + for ((elt) = (type) queue_first(head); \ + !queue_end((head), (queue_entry_t)(elt)); \ + (elt) = (type) queue_next(&(elt)->field)) + + +#endif /* _KERN_QUEUE_H_ */ diff --git a/apps/rmgr/include/flux/smp/smp.h b/apps/rmgr/include/flux/smp/smp.h new file mode 100644 index 0000000..8dad416 --- /dev/null +++ b/apps/rmgr/include/flux/smp/smp.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + */ + +#ifndef _FLUX_SMP_SMP_H_ +#define _FLUX_SMP_SMP_H_ + +#include + +#undef SMP_DEBUG + +/* + * Header file for SMP-specific functions + */ + +/* + * General Notes: + * 1. Processors are not assumed to be numbered sequentially. + * 2. smp_get_num_cpus() may take a LONG time (seconds?) the + * first time it is called. + * XXX == only if called before smp_initialize!! + * + * 3. The division of labor between smg_get_num_cpus and + * smp_startup_processor is arbitrary, and transparent to + * the programmer (except for elapsed time), and may change. + */ + + +__FLUX_BEGIN_DECLS +/* + * This gets everything going... + * This should be the first SMP routine called. + * It returns 0 on success (if it found a SMP system). + * Success doesn't mean more than one processor, although + * failure indicates only one. + */ +int smp_initialize(void); + + + +/* + * This routine returns the current processor number (UID) + * It is only valid after smp_initialize() has bee called. + */ +int smp_find_cur_cpu(void); + + +/* + * This routine determines the number of processors available. + * It is called early enough so that any information it may need is + * still intact. + */ +int smp_get_num_cpus(void); + + + +/* + * This is an iterator function to get all the CPU ID's + * Call it the first time with 0; subsequently with (res+1) + * Returns (<0) if no such processor + */ +int smp_find_cpu(int first); + + + + +/* + * This function causes the processor numbered to begin + * executing the function passed, with the stack passed, and + * the data_arg on the stack (so it can bootstrap itself). + * Note: on the x86, it will already be in protected mode + * + * If the processor doesn't exist, it will return E_SMP_NO_PROC + */ +void smp_start_cpu(int processor_id, void (*func)(void *data), + void *data, void *stack_ptr); + +__FLUX_END_DECLS + +#define E_SMP_NO_CONFIG -135 +#define E_SMP_NO_PROC -579 + +#endif diff --git a/apps/rmgr/include/flux/tty.h b/apps/rmgr/include/flux/tty.h new file mode 100644 index 0000000..ab448d1 --- /dev/null +++ b/apps/rmgr/include/flux/tty.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Library of definitions and routines relating to POSIX tty I/O support. + */ +#ifndef _FLUX_TTY_H_ +#define _FLUX_TTY_H_ + +/* + * Ready-made termios structures containing default settings + * for typical cooked and raw console modes, respectively. + * The serial settings are 9600,8,N,1. + */ +extern struct termios base_cooked_termios; +extern struct termios base_raw_termios; + +#endif /* _FLUX_TTY_H_ */ diff --git a/apps/rmgr/include/flux/x86/anno.h b/apps/rmgr/include/flux/x86/anno.h new file mode 100644 index 0000000..bd0d01b --- /dev/null +++ b/apps/rmgr/include/flux/x86/anno.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_ANNO_H_ +#define _FLUX_X86_ANNO_H_ + +#ifndef ASSEMBLER + + + +#else /* ASSEMBLER */ + + +/* Create an arbitrary annotation entry. + Must switch back to an appropriate segment afterward. */ +#define ANNO_ENTRY(table, val1, val2, val3) \ + .section .anno,"aw",@progbits ;\ + .long val1,val2,val3,table + +/* Create an annotation entry for code in a text segment. */ +#define ANNO_TEXT(table, val2, val3) \ +9: ANNO_ENTRY(table, 9b, val2, val3) ;\ + .text + + + +/* The following are for common annotation tables. + These don't have to be used in any given kernel, + and others can be defined as convenient. */ + + +/* The anno_intr table is generally accessed + on hardware interrupts that occur while running in kernel mode. + The value is a routine for the trap handler in interrupt.S + to jump to before processing the hardware interrupt. + This routine applies to all code from this address + up to but not including the address of the next ANNO_INTR. + To disable interrupt redirection for a piece of code, + place an ANNO_INTR(0) before it. */ + +#define ANNO_INTR(routine) \ + ANNO_TEXT(anno_intr, routine, 0) + + +/* The anno_trap table is accessed + on processor traps that occur in kernel mode. + If a match is found in this table, + the specified alternate handler is run instead of the generic handler. + A match is found only if the EIP exactly matches an ANNO_TRAP entry + (i.e. these entries apply to individual instructions, not groups), + and if the trap type that occurred matches the type specified. */ + +#define ANNO_TRAP(routine) \ + ANNO_TEXT(anno_trap, routine, 0) + + +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_ANNO_H_ */ diff --git a/apps/rmgr/include/flux/x86/asm.h b/apps/rmgr/include/flux/x86/asm.h new file mode 100644 index 0000000..45a467e --- /dev/null +++ b/apps/rmgr/include/flux/x86/asm.h @@ -0,0 +1,119 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_ASM_H_ +#define _FLUX_X86_ASM_H_ + +#include + +/* This is a more reliable delay than a few short jmps. */ +#define IODELAY pushl %eax; inb $0x80,%al; inb $0x80,%al; popl %eax + +#define S_ARG0 4(%esp) +#define S_ARG1 8(%esp) +#define S_ARG2 12(%esp) +#define S_ARG3 16(%esp) + +#define FRAME pushl %ebp; movl %esp, %ebp +#define EMARF leave + +#define B_ARG0 8(%ebp) +#define B_ARG1 12(%ebp) +#define B_ARG2 16(%ebp) +#define B_ARG3 20(%ebp) + +#ifdef i486 +#define TEXT_ALIGN 4 +#else +#define TEXT_ALIGN 2 +#endif +#define DATA_ALIGN 2 +#define ALIGN TEXT_ALIGN + +/* + * The .align directive has different meaning on the x86 when using ELF + * than when using a.out. + * Newer GNU as remedies this problem by providing .p2align and .balign. + */ +#if defined(HAVE_P2ALIGN) +# define P2ALIGN(p2) .p2align p2 +#elif defined(__ELF__) +# define P2ALIGN(p2) .align (1<<(p2)) +#else +# define P2ALIGN(p2) .align p2 +#endif + +#define LCL(x) x + +#define LB(x,n) n +#ifndef __ELF__ +#define EXT(x) _ ## x +#define LEXT(x) _ ## x ## : +#define SEXT(x) "_"#x +#else +#define EXT(x) x +#define LEXT(x) x ## : +#define SEXT(x) #x +#endif +#define GLEXT(x) .globl EXT(x); LEXT(x) +#define LCLL(x) x ## : +#define gLB(n) n ## : +#define LBb(x,n) n ## b +#define LBf(x,n) n ## f + + +/* Symbol types */ +#ifdef __ELF__ +#define FUNCSYM(x) .type x,@function +#else +#define FUNCSYM(x) /* nothing */ +#endif + + +#ifdef GPROF + +#define MCOUNT .data; gLB(9) .long 0; .text; lea LBb(x, 9),%edx; call mcount +#define ENTRY(x) .globl EXT(x); P2ALIGN(TEXT_ALIGN); LEXT(x) ; \ + pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + P2ALIGN(TEXT_ALIGN); LEXT(x) LEXT(y) +#define ASENTRY(x) .globl x; P2ALIGN(TEXT_ALIGN); gLB(x) ; \ + pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; + +#else /* ndef GPROF */ + +#define MCOUNT +#define ENTRY(x) FUNCSYM(x); .globl EXT(x); P2ALIGN(TEXT_ALIGN); LEXT(x) +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + P2ALIGN(TEXT_ALIGN); LEXT(x) LEXT(y) +#define ASENTRY(x) .globl x; P2ALIGN(TEXT_ALIGN); gLB(x) + +#endif /* ndef GPROF */ + + +#define Entry(x) P2ALIGN(TEXT_ALIGN); GLEXT(x) +#define DATA(x) P2ALIGN(DATA_ALIGN); GLEXT(x) + +#endif /* _FLUX_X86_ASM_H_ */ diff --git a/apps/rmgr/include/flux/x86/base_asm.sym b/apps/rmgr/include/flux/x86/base_asm.sym new file mode 100644 index 0000000..9de12c3 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_asm.sym @@ -0,0 +1,36 @@ +/* + * MOSS - DOS extender built from the Mach 4 source tree + * Copyright (C) 1995-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ + +#include + +#include "gdt.h" + +offset i386_tss tss esp0 +offset i386_tss tss ss +size i386_tss tss + +expr KERNEL_CS +expr KERNEL_DS +expr KERNEL_16_CS +expr KERNEL_16_DS +expr LINEAR_CS +expr LINEAR_DS + diff --git a/apps/rmgr/include/flux/x86/base_cpu.h b/apps/rmgr/include/flux/x86/base_cpu.h new file mode 100644 index 0000000..0eb6ea5 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_cpu.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Functions for setting up and activating + * a basic x86 protected-mode kernel execution environment. + */ +#ifndef _FLUX_X86_BASE_CPU_H_ +#define _FLUX_X86_BASE_CPU_H_ + +#include +#include + +__FLUX_BEGIN_DECLS +/* + * CPU information for the processor base_cpu_init() was called on. + */ +extern struct cpu_info base_cpuid; + +/* + * Initialize all the processor data structures defining the base environment: + * the base_cpuid, the base_idt, the base_gdt, and the base_tss. + */ +extern void base_cpu_init(void); + +/* + * Load all of the above into the processor, + * properly setting up the protected-mode environment. + */ +extern void base_cpu_load(void); +__FLUX_END_DECLS + +/* + * Do both at once. + */ +#define base_cpu_setup() (base_cpu_init(), base_cpu_load()) + +#endif /* _FLUX_X86_BASE_CPU_H_ */ diff --git a/apps/rmgr/include/flux/x86/base_gdt.h b/apps/rmgr/include/flux/x86/base_gdt.h new file mode 100644 index 0000000..ac9e838 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_gdt.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This file defines a basic global descriptor table that can be used + * for simple protected-mode execution in both kernel and user mode. + */ +#ifndef _FLUX_X86_BASE_GDT_H_ +#define _FLUX_X86_BASE_GDT_H_ + +#include + + +#define BASE_TSS 0x08 +#define KERNEL_CS 0x10 /* Kernel's PL0 code segment */ +#define KERNEL_DS 0x18 /* Kernel's PL0 data segment */ +#define KERNEL_16_CS 0x20 /* 16-bit version of KERNEL_CS */ +#define KERNEL_16_DS 0x28 /* 16-bit version of KERNEL_DS */ +#define LINEAR_CS 0x30 /* PL0 code segment mapping to linear space */ +#define LINEAR_DS 0x38 /* PL0 data segment mapping to linear space */ +#define USER_CS 0x43 /* User-defined descriptor, RPL=3 */ +#define USER_DS 0x4b /* User-defined descriptor, RPL=3 */ + +#define GDTSZ (0x50/8) + + +#ifndef ASSEMBLER + +#include + +extern struct x86_desc base_gdt[GDTSZ]; + +__FLUX_BEGIN_DECLS +/* Initialize the base GDT descriptors with sensible defaults. */ +extern void base_gdt_init(void); + +/* Load the base GDT into the CPU. */ +extern void base_gdt_load(void); + +/* 16-bit versions of the above functions, + which can be executed in real mode. */ +extern void i16_base_gdt_init(void); +extern void i16_base_gdt_load(void); +__FLUX_END_DECLS + +#endif /* not ASSEMBLER */ + +#endif _FLUX_X86_BASE_GDT_H_ diff --git a/apps/rmgr/include/flux/x86/base_idt.h b/apps/rmgr/include/flux/x86/base_idt.h new file mode 100644 index 0000000..d9ec20b --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_idt.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_BASE_IDT_H_ +#define _FLUX_X86_BASE_IDT_H_ + +#include +#include + + +/* The base environment provides a full-size 256-entry IDT. + This is needed, for example, under VCPI or Intel MP Standard PCs. */ +#define IDTSZ 256 + +extern struct x86_gate base_idt[IDTSZ]; + + +/* Note that there is no base_idt_init() function, + because the IDT is used for both trap and interrupt vectors. + To initialize the processor trap vectors, call base_trap_init(). + Inititalizing hardware interrupt vectors is platform-specific. */ + + +__FLUX_BEGIN_DECLS +/* Load the base IDT into the CPU. */ +extern void base_idt_load(void); +__FLUX_END_DECLS + + +#endif /* _FLUX_X86_BASE_IDT_H_ */ diff --git a/apps/rmgr/include/flux/x86/base_paging.h b/apps/rmgr/include/flux/x86/base_paging.h new file mode 100644 index 0000000..6272ac0 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_paging.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Basic page directory and page table management routines for the x86. + */ +#ifndef _FLUX_X86_BASE_PAGING_H_ +#define _FLUX_X86_BASE_PAGING_H_ + +#include +#include +#include +#include +#include + +/* + * Find the entry in a page directory or page table + * for a particular linear address. + */ +#define pdir_find_pde(pdir_pa, la) \ + (&((pd_entry_t*)phystokv(pdir_pa))[lin2pdenum(la)]) +#define ptab_find_pte(ptab_pa, la) \ + (&((pt_entry_t*)phystokv(ptab_pa))[lin2ptenum(la)]) + +/* + * Find a page table entry given a page directory and a linear address. + * Returns NULL if there is no page table covering that address. + * Assumes that if there is a valid PDE, it's a page table, _not_ a 4MB page. + */ +FLUX_INLINE pt_entry_t *pdir_find_pte(vm_offset_t pdir_pa, vm_offset_t la) +{ + pd_entry_t *pde = pdir_find_pde(pdir_pa, la); + if (!(*pde & INTEL_PDE_VALID)) + return 0; + return ptab_find_pte(pde_to_pa(*pde), la); +} + +/* + * Get the value of a page table entry, + * or return zero if no such entry exists. + * As above, doesn't check for 4MB pages. + */ +FLUX_INLINE pt_entry_t pdir_get_pte(vm_offset_t pdir_pa, vm_offset_t la) +{ + pt_entry_t *pte = pdir_find_pte(pdir_pa, la); + return pte ? *pte : 0; +} + +__FLUX_BEGIN_DECLS +/* + * Functions called by the following routines to allocate a page table. + * Supplies a single page of CLEARED memory, by its physical address. + * Returns zero if successful, nonzero on failure. + * The default implementation simply allocates a page from the malloc_lmm, + * returning -1 if the LMM runs out of memory. + * This implementation can be overridden, of course. + */ +int ptab_alloc(vm_offset_t *out_ptab_pa); + +/* + * Free a page table allocated using ptab_alloc(). + * The caller must ensure that it is not still in use in any page directories. + */ +void ptab_free(vm_offset_t ptab_pa); + +/* + * Map a 4KB page into a page directory. + * Calls page_alloc_func if a new page table needs to be allocated. + * If page_alloc_func returns nonzero, pdir_map_page aborts with that value. + * Otherwise, inserts the mapping and returns zero. + * Doesn't check for 4MB pages. + */ +int pdir_map_page(vm_offset_t pdir_pa, vm_offset_t la, pt_entry_t mapping); + + +/* + * Map a continuous range of virtual addresses + * to a continuous range of physical addresses. + * If the processor supports 4MB pages, uses them if possible. + * Assumes that there are no valid mappings already in the specified range. + * The 'mapping_bits' parameter must include INTEL_PTE_VALID, + * and may include other permissions as desired. + */ +int pdir_map_range(vm_offset_t pdir_pa, vm_offset_t la, vm_offset_t pa, + vm_size_t size, pt_entry_t mapping_bits); + +/* + * Change the permissions on an existing mapping range. + * The 'new_mapping_bits' parameter must include INTEL_PTE_VALID, + * and may include other permissions as desired. + * Assumes that the mappings being changed were produced + * by a previous call to pdir_map_range() + * with identical linear address and size parameters. + */ +void pdir_prot_range(vm_offset_t pdir_pa, vm_offset_t la, vm_size_t size, + pt_entry_t new_mapping_bits); + +/* + * Unmap a continuous range of virtual addresses. + * Assumes that the mappings being unmapped were produced + * by a previous call to pdir_map_range() + * with identical linear address and size parameters. + */ +void pdir_unmap_range(vm_offset_t pdir_pa, vm_offset_t la, vm_size_t size); + +/* + * These functions are primarily for debugging VM-related code: + * they pretty-print a dump of a page directory or page table + * and all their mappings. + */ +void pdir_dump(vm_offset_t pdir_pa); +void ptab_dump(vm_offset_t ptab_pa, vm_offset_t base_la); + +/* + * Initialize a basic paged environment. + * Sets up the base_pdir (see below) which direct maps + * all physical memory from 0 to (at least) phys_mem_max, + * and enables paging on the current processor using that page directory. + * The client can then modify this page directory or create others as needed. + * The base physical memory mappings are accessible from user mode by default. + */ +void base_paging_init(void); +__FLUX_END_DECLS + +/* + * Physical address of the base page directory, + * set up by base_paging_init(). + */ +extern vm_offset_t base_pdir_pa; + +#endif _FLUX_X86_BASE_PAGING_H_ diff --git a/apps/rmgr/include/flux/x86/base_stack.h b/apps/rmgr/include/flux/x86/base_stack.h new file mode 100644 index 0000000..61cf75e --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_stack.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This header file defines the initial stack provided by the base environment. + * The stack is BASE_STACK_SIZE bytes by default. + */ +#ifndef _FLUX_X86_BASE_STACK_H_ +#define _FLUX_X86_BASE_STACK_H_ + +#define BASE_STACK_SIZE 4096 + +#ifndef ASSEMBLER + +extern char base_stack_start[], base_stack_end[]; + +#endif + +#endif /* _FLUX_X86_BASE_STACK_H_ */ diff --git a/apps/rmgr/include/flux/x86/base_trap.h b/apps/rmgr/include/flux/x86/base_trap.h new file mode 100644 index 0000000..0ab39b2 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_trap.h @@ -0,0 +1,162 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University. + * Copyright (c) 1994 The University of Utah and + * the Center for Software Science (CSS). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_BASE_TRAP_H_ +#define _FLUX_X86_BASE_TRAP_H_ + +#ifndef ASSEMBLER + +#include + +/* + * This structure corresponds to the state of user registers + * as saved upon kernel trap/interrupt entry. + * As always, it is only a default implementation; + * a well-optimized kernel will probably want to override it + * with something that allows better optimization. + */ +struct trap_state +{ + /* Saved segment registers */ + unsigned int gs; + unsigned int fs; + unsigned int es; + unsigned int ds; + + /* PUSHA register state frame */ + unsigned int edi; + unsigned int esi; + unsigned int ebp; + unsigned int cr2; /* we save cr2 over esp for page faults */ + unsigned int ebx; + unsigned int edx; + unsigned int ecx; + unsigned int eax; + + /* Processor trap number, 0-31. */ + unsigned int trapno; + + /* Error code pushed by the processor, 0 if none. */ + unsigned int err; + + /* Processor state frame */ + unsigned int eip; + unsigned int cs; + unsigned int eflags; + unsigned int esp; + unsigned int ss; + + /* Virtual 8086 segment registers */ + unsigned int v86_es; + unsigned int v86_ds; + unsigned int v86_fs; + unsigned int v86_gs; +}; + +/* + * The actual trap_state frame pushed by the processor + * varies in size depending on where the trap came from. + */ +#define TR_KSIZE ((int)&((struct trap_state*)0)->esp) +#define TR_USIZE ((int)&((struct trap_state*)0)->v86_es) +#define TR_V86SIZE sizeof(struct trap_state) + + +__FLUX_BEGIN_DECLS +/* + * This library routine initializes the trap vectors in the base IDT + * to point to default trap handler entrypoints + * which merely push the standard trap saved-state frame above + * and call the default trap handler routine, 'trap_handler'. + */ +extern void base_trap_init(void); + +/* + * This gate initialization table is used by base_trap_init + * to initialize the base IDT to the default trap entrypoint code, + * which pushes the state frame described above + * and calls the trap handler, below. + */ +extern struct gate_init_entry base_trap_inittab[]; + +/* + * The default trap entrypoint code checks this function pointer + * (after saving the trap_state frame described by the structure above), + * and if non-null, calls the C function it points to. + * The function can examine and modify the provided trap_state as appropriate. + * If the trap handler function returns zero, + * execution will be resumed or resterted with the final trap_state; + * if the trap handler function returns nonzero, + * the trap handler dumps the trap state to the console and panics. + */ +extern int (*base_trap_handler)(struct trap_state *state); + + +/* + * This routine dumps the contents of the specified trap_state structure + * to the console using printf. + * It is normally called automatically from trap_dump_panic + * when an unexpected trap occurs; + * however, can be called at other times as well + * (e.g., for debugging custom trap handlers). + */ +void trap_dump(const struct trap_state *st); + +/* + * This routine simply calls trap_dump to dump the trap state, + * and then calls panic. + * It is used by the default trap entrypoint code + * when a trap occurs and there is no trap handler, + * and by the UNEXPECTED_TRAP assembly language macro below. + */ +void trap_dump_panic(const struct trap_state *st); +__FLUX_END_DECLS + + +#else ASSEMBLER + +#include + + +/* + * Simple assembly language macro that can be called from most anywhere + * to dump a trap state frame at the top of the kernel stack and panic. + */ +#define UNEXPECTED_TRAP \ + movw %ss,%ax ;\ + movw %ax,%ds ;\ + movw %ax,%es ;\ + movl %esp,%eax ;\ + pushl %eax ;\ + call EXT(trap_dump_panic) ;\ + + +#endif ASSEMBLER + + +#endif /* _FLUX_X86_BASE_TRAP_H_ */ diff --git a/apps/rmgr/include/flux/x86/base_tss.h b/apps/rmgr/include/flux/x86/base_tss.h new file mode 100644 index 0000000..ba87455 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_tss.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions for a basic x86 32-bit Task State Segment (TSS) + * which is set up and and used by the base environment as a "default" TSS. + */ +#ifndef _FLUX_X86_BASE_TSS_H_ +#define _FLUX_X86_BASE_TSS_H_ + +#include +#include + +extern struct x86_tss base_tss; + +__FLUX_BEGIN_DECLS +/* Initialize the base TSS with sensible default values. + The current stack pointer is used as the TSS's ring 0 stack pointer. */ +extern void base_tss_init(void); + +/* Load the base TSS into the current CPU. + Assumes that the base GDT is already loaded, + and that the BASE_TSS descriptor in the GDT refers to the base TSS. */ +extern void base_tss_load(void); +__FLUX_END_DECLS + +#endif _FLUX_X86_BASE_TSS_H_ diff --git a/apps/rmgr/include/flux/x86/base_vm.h b/apps/rmgr/include/flux/x86/base_vm.h new file mode 100644 index 0000000..317b427 --- /dev/null +++ b/apps/rmgr/include/flux/x86/base_vm.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Definitions for the base VM environment provided by the OS toolkit: + * how to change pointers between physical, virtual, and linear addresses, etc. + */ +#ifndef _FLUX_X86_BASE_VM_H_ +#define _FLUX_X86_BASE_VM_H_ + +#include + + +/* This variable is expected always to contain + the kernel virtual address at which physical memory is mapped. + It may change as paging is turned on or off. */ +extern vm_offset_t phys_mem_va; + + +/* Calculate a kernel virtual address from a physical address. */ +#define phystokv(pa) ((vm_offset_t)(pa) + phys_mem_va) + +/* Same, but in reverse. + This only works for the region of kernel virtual addresses + that directly map physical addresses. */ +#define kvtophys(va) ((vm_offset_t)(va) - phys_mem_va) + + +/* This variable contains the kernel virtual address + corresponding to linear address 0. + In the absence of paging, + linear addresses are always the same as physical addresses. */ +extern vm_offset_t linear_base_va; + +/* Convert between linear and kernel virtual addresses. */ +#define lintokv(la) ((vm_offset_t)(la) + linear_base_va) +#define kvtolin(va) ((vm_offset_t)(va) - linear_base_va) + + +/* If the kernel was started from real mode, + this variable contains our original real-mode code segment. */ +extern unsigned short real_cs; + + +#endif /* _FLUX_X86_BASE_VM_H_ */ diff --git a/apps/rmgr/include/flux/x86/c/common.h b/apps/rmgr/include/flux/x86/c/common.h new file mode 100644 index 0000000..2963de6 --- /dev/null +++ b/apps/rmgr/include/flux/x86/c/common.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Common machine-dependent definitions + * used by the Flux minimal C library headers. + */ +#ifndef _FLUX_X86_MC_COMMON_H_ +#define _FLUX_X86_MC_COMMON_H_ + +typedef unsigned int __flux_size_t; +typedef int __flux_ssize_t; +typedef unsigned int __flux_off_t; +typedef char * __flux_va_list; + +#endif /* _FLUX_X86_MC_COMMON_H_ */ diff --git a/apps/rmgr/include/flux/x86/c/setjmp.h b/apps/rmgr/include/flux/x86/c/setjmp.h new file mode 100644 index 0000000..7717100 --- /dev/null +++ b/apps/rmgr/include/flux/x86/c/setjmp.h @@ -0,0 +1,34 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * setjmp/longjmp buffer for x86. + */ +#ifndef _FLUX_X86_C_SETJMP_H_ +#define _FLUX_X86_C_SETJMP_H_ + +typedef int jmp_buf[6]; /* ebx, esi, edi, ebp, esp, eip */ + +#endif /* _FLUX_X86_C_SETJMP_H_ */ diff --git a/apps/rmgr/include/flux/x86/c/stdarg.h b/apps/rmgr/include/flux/x86/c/stdarg.h new file mode 100644 index 0000000..7bfd87d --- /dev/null +++ b/apps/rmgr/include/flux/x86/c/stdarg.h @@ -0,0 +1,48 @@ +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University. + * Copyright (c) 1994 The University of Utah and + * the Center for Software Science (CSS). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_C_STDARG_H_ +#define _FLUX_X86_C_STDARG_H_ + +#include + +#define __va_size(type) ((sizeof(type)+3) & ~0x3) + +#ifndef _VA_LIST_ +#define _VA_LIST_ +typedef __flux_va_list va_list; +#endif + +#define va_start(pvar, lastarg) \ + ((pvar) = (char*)(void*)&(lastarg) + __va_size(lastarg)) +#define va_end(pvar) +#define va_arg(pvar,type) \ + ((pvar) += __va_size(type), \ + *((type *)((pvar) - __va_size(type)))) + +#endif _FLUX_X86_C_STDARG_H_ diff --git a/apps/rmgr/include/flux/x86/cpuid.h b/apps/rmgr/include/flux/x86/cpuid.h new file mode 100644 index 0000000..34a0890 --- /dev/null +++ b/apps/rmgr/include/flux/x86/cpuid.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * CPU identification for x86 processors. + */ +#ifndef _FLUX_X86_CPUID_H_ +#define _FLUX_X86_CPUID_H_ + +#include + +struct cpu_info +{ + unsigned stepping : 4; + unsigned model : 4; + unsigned family : 4; + unsigned type : 2; + unsigned reserved : 18; + unsigned feature_flags; + char vendor_id[12]; + unsigned char cache_config[16]; +}; + +/* + * Values of the cpu_info.family field + */ +#define CPU_FAMILY_386 3 +#define CPU_FAMILY_486 4 +#define CPU_FAMILY_PENTIUM 5 +#define CPU_FAMILY_PENTIUM_PRO 6 + +/* + * Values of the cpu_info.type field + */ +#define CPU_TYPE_ORIGINAL 0 +#define CPU_TYPE_OVERDRIVE 1 +#define CPU_TYPE_DUAL 2 + +/* + * CPU feature_flags bit definitions. + */ +#define CPUF_ON_CHIP_FPU 0x00000001 /* On-chip floating point */ +#define CPUF_VM86_EXT 0x00000002 /* Virtual mode extensions */ +#define CPUF_IO_BKPTS 0x00000004 /* I/O breakpoint support */ +#define CPUF_4MB_PAGES 0x00000008 /* 4MB page support */ +#define CPUF_TS_COUNTER 0x00000010 /* Timestamp counter */ +#define CPUF_PENTIUM_MSR 0x00000020 /* Pentium model-spec regs */ +#define CPUF_PAGE_ADDR_EXT 0x00000040 /* Page address extensions */ +#define CPUF_MACHINE_CHECK_EXCP 0x00000080 /* Machine check exception */ +#define CPUF_CMPXCHG8B 0x00000100 /* CMPXCHG8B instruction */ +#define CPUF_LOCAL_APIC 0x00000200 /* CPU contains a local APIC */ +#define CPUF_MEM_RANGE_REGS 0x00001000 /* memory type range regs */ +#define CPUF_PAGE_GLOBAL_EXT 0x00002000 /* page global extensions */ +#define CPUF_MACHINE_CHECK_ARCH 0x00004000 /* Machine check architecture */ +#define CPUF_CMOVCC 0x00008000 /* CMOVcc instructions */ + +/* + * Cache configuration descriptor entry values. + */ +#define CPUC_NULL 0x00 +#define CPUC_CODE_TLB_4K_4W_64E 0x01 +#define CPUC_CODE_TLB_4M_4W_4E 0x02 +#define CPUC_DATA_TLB_4K_4W_64E 0x03 +#define CPUC_DATA_TLB_4M_4W_8E 0x04 +#define CPUC_CODE_L1_32B_4W_8KB 0x06 +#define CPUC_DATA_L1_32B_2W_8KB 0x0a +#define CPUC_COMB_L2_32B_4W_128KB 0x41 +#define CPUC_COMB_L2_32B_4W_256KB 0x42 +#define CPUC_COMB_L2_32B_4W_512KB 0x43 + + +__FLUX_BEGIN_DECLS +/* + * Generic routine to detect the current processor + * and fill in the supplied cpu_info structure with all information available. + * If the vendor ID cannot be determined, it is left a zero-length string. + * This routine assumes the processor is at least a 386 - + * since it's a 32-bit function, it wouldn't run on anything less anyway. + */ +void cpuid(struct cpu_info *out_id); + +/* + * Format the information in a cpu_info structure + * into a human-readable ASCII representation, + * using the specified printf-like formatting function for output. + */ +void cpu_info_format( + struct cpu_info *info, + void (*formatter)(void *data, const char *fmt, ...), + void *data); + +/* + * Pretty-print a cpu_info structure to the console using printf(). + */ +void cpu_info_dump(struct cpu_info *info); + +/* + * Given two cpu_info structures, reduce 'id' to be the minimum + * (least-common-denominator) of the two structurens. + * Typically used on SMP systems to determine the basic feature set + * common across all processors in the system regardless of type. + */ +void cpu_info_min(struct cpu_info *id, const struct cpu_info *id2); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_CPUID_H_ */ diff --git a/apps/rmgr/include/flux/x86/debug.h b/apps/rmgr/include/flux/x86/debug.h new file mode 100644 index 0000000..90a497b --- /dev/null +++ b/apps/rmgr/include/flux/x86/debug.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DEBUG_H_ +#define _FLUX_X86_DEBUG_H_ + +#define PRINT_STACK_TRACE(num_frames) { \ + int i = (num_frames); \ + unsigned *fp; \ + printf("stack trace:\n"); \ + asm volatile ("movl %%ebp,%0" : "=r" (fp)); \ + while (fp && --i >= 0) { \ + printf("\t0x%08x\n", *(fp + 1)); \ + fp = (unsigned *)(*fp); \ + } \ +} + +#ifdef ASSEMBLER +#ifdef DEBUG + + +#define A(cond,a,b) \ + a,b ;\ + j##cond 8f ;\ + int $0xda ;\ +8: + + +#else /* !DEBUG */ + + +#define A(cond,a,b) + + +#endif /* !DEBUG */ +#else /* !ASSEMBLER */ + + +#endif /* !ASSEMBLER */ + +#endif /* _FLUX_X86_DEBUG_H_ */ diff --git a/apps/rmgr/include/flux/x86/debug_reg.h b/apps/rmgr/include/flux/x86/debug_reg.h new file mode 100644 index 0000000..6e1b8ee --- /dev/null +++ b/apps/rmgr/include/flux/x86/debug_reg.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DEBUG_REG_H_ +#define _FLUX_X86_DEBUG_REG_H_ + +/* Bits in DR7 - debug control register */ +#define DR7_LEN3 0xc0000000 +#define DR7_RW3 0x30000000 +#define DR7_LEN2 0x0c000000 +#define DR7_RW2 0x03000000 +#define DR7_LEN1 0x00c00000 +#define DR7_RW1 0x00300000 +#define DR7_LEN0 0x000c0000 +#define DR7_RW0 0x00030000 +#define DR7_GD 0x00002000 +#define DR7_GE 0x00000200 +#define DR7_LE 0x00000100 +#define DR7_G3 0x00000080 +#define DR7_L3 0x00000040 +#define DR7_G2 0x00000020 +#define DR7_L2 0x00000010 +#define DR7_G1 0x00000008 +#define DR7_L1 0x00000004 +#define DR7_G0 0x00000002 +#define DR7_L0 0x00000001 + +/* Shift values for multibit fields in DR7 */ +#define DR7_LEN3_SHIFT 30 +#define DR7_RW3_SHIFT 28 +#define DR7_LEN2_SHIFT 26 +#define DR7_RW2_SHIFT 24 +#define DR7_LEN1_SHIFT 22 +#define DR7_RW1_SHIFT 20 +#define DR7_LEN0_SHIFT 18 +#define DR7_RW0_SHIFT 16 + +/* Values for LEN fields in DR7 */ +#define DR7_LEN_1 0 +#define DR7_LEN_2 1 +#define DR7_LEN_4 3 + +/* Values for RW fields in DR7 */ +#define DR7_RW_INST 0 /* Break on instruction execution */ +#define DR7_RW_WRITE 1 /* Break on data writes */ +#define DR7_RW_IO 2 /* Break on I/O reads and writes (Pentium only) */ +#define DR7_RW_DATA 3 /* Break on data reads and writes */ + + +/* Bits in DR6 - debug status register */ +#define DR6_BT 0x00008000 +#define DR6_BS 0x00004000 +#define DR6_BD 0x00002000 +#define DR6_B3 0x00000008 +#define DR6_B2 0x00000004 +#define DR6_B1 0x00000002 +#define DR6_B0 0x00000001 + + +#include + +/* Functions to set debug registers. */ + +FLUX_INLINE unsigned get_dr0() +{ + unsigned val; + asm volatile("movl %%dr0,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr1() +{ + unsigned val; + asm volatile("movl %%dr1,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr2() +{ + unsigned val; + asm volatile("movl %%dr2,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr3() +{ + unsigned val; + asm volatile("movl %%dr3,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr6() +{ + unsigned val; + asm volatile("movl %%dr6,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE unsigned get_dr7() +{ + unsigned val; + asm volatile("movl %%dr7,%0" : "=r" (val)); + return val; +} + +FLUX_INLINE void set_dr0(unsigned val) +{ + asm volatile("movl %0,%%dr0" : : "r" (val)); +} + + +/* Functions to read debug registers. */ + +FLUX_INLINE void set_dr1(unsigned val) +{ + asm volatile("movl %0,%%dr1" : : "r" (val)); +} + +FLUX_INLINE void set_dr2(unsigned val) +{ + asm volatile("movl %0,%%dr2" : : "r" (val)); +} + +FLUX_INLINE void set_dr3(unsigned val) +{ + asm volatile("movl %0,%%dr3" : : "r" (val)); +} + +FLUX_INLINE void set_dr6(unsigned val) +{ + asm volatile("movl %0,%%dr6" : : "r" (val)); +} + +FLUX_INLINE void set_dr7(unsigned val) +{ + asm volatile("movl %0,%%dr7" : : "r" (val)); +} + + +/* Functions to set global breakpoints. */ + +FLUX_INLINE void set_b0(unsigned addr, unsigned len, unsigned rw) +{ + set_dr0(addr); + addr = ((get_dr7() & ~(DR7_LEN0 | DR7_RW0)) + | (len << DR7_LEN0_SHIFT) | (rw << DR7_RW0_SHIFT) + | DR7_GE | DR7_G0); + set_dr7(addr); +} + +FLUX_INLINE void set_b1(unsigned addr, unsigned len, unsigned rw) +{ + set_dr1(addr); + set_dr7((get_dr7() & ~(DR7_LEN1 | DR7_RW1)) + | (len << DR7_LEN1_SHIFT) | (rw << DR7_RW1_SHIFT) + | DR7_GE | DR7_G1); +} + +FLUX_INLINE void set_b2(unsigned addr, unsigned len, unsigned rw) +{ + set_dr2(addr); + set_dr7((get_dr7() & ~(DR7_LEN2 | DR7_RW2)) + | (len << DR7_LEN2_SHIFT) | (rw << DR7_RW2_SHIFT) + | DR7_GE | DR7_G2); +} + +FLUX_INLINE void set_b3(unsigned addr, unsigned len, unsigned rw) +{ + set_dr3(addr); + set_dr7((get_dr7() & ~(DR7_LEN3 | DR7_RW3)) + | (len << DR7_LEN3_SHIFT) | (rw << DR7_RW3_SHIFT) + | DR7_GE | DR7_G3); +} + + + +#endif /* _FLUX_X86_DEBUG_REG_H_ */ diff --git a/apps/rmgr/include/flux/x86/dos/dpmi.h b/apps/rmgr/include/flux/x86/dos/dpmi.h new file mode 100644 index 0000000..db1526e --- /dev/null +++ b/apps/rmgr/include/flux/x86/dos/dpmi.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DOS_DPMI_H_ +#define _FLUX_X86_DOS_DPMI_H_ + +#include +#include + +typedef unsigned short dpmi_error_t; + +#define DPMI_UNSUPPORTED_FUNCTION 0x8001 +#define DPMI_OBJECT_WRONG_STATE 0x8002 +#define DPMI_SYSTEM_INTEGRITY 0x8003 +#define DPMI_DEADLOCK 0x8004 +#define DPMI_SERIALIZATION_CANCELLED 0x8005 +#define DPMI_OUT_OF_RESOURCES 0x8010 +#define DPMI_DESCRIPTOR_UNAVAILABLE 0x8011 +#define DPMI_LINEAR_MEMORY_UNAVAILABLE 0x8012 +#define DPMI_PHYSICAL_MEMORY_UNAVAILABLE 0x8013 +#define DPMI_BACKING_STORE_UNAVAILABLE 0x8014 +#define DPMI_CALLBACK_UNAVAILABLE 0x8015 +#define DPMI_HANDLE_UNAVAILABLE 0x8016 +#define DPMI_MAX_LOCK_COUNT_EXCEEDED 0x8017 +#define DPMI_ALREADY_SERIALIZED_EXCLUSIVELY 0x8018 +#define DPMI_ALREADY_SERIALIZED_SHARED 0x8019 +#define DPMI_INVALID_VALUE 0x8021 +#define DPMI_INVALID_SELECTOR 0x8022 +#define DPMI_INVALID_HANDLE 0x8023 +#define DPMI_INVALID_CALLBACK 0x8024 +#define DPMI_INVALID_LINEAR_ADDRESS 0x8025 +#define DPMI_NOT_SUPPORTED_BY_HARDWARE 0x8026 + +struct real_call_data; /*XXX*/ + +MACH_INLINE dpmi_error_t dpmi_switch_to_pmode( + struct far_pointer_16 *pmode_entry_vector, + unsigned short host_data_seg) +{ + dpmi_error_t err; + + asm volatile(" + movw %3,%%es + lcallw %2 + jc 1f + xorw %%ax,%%ax + 1: pushw %%ds + popw %%es + " : "=a" (err) + : "a" (1), + "m" (*pmode_entry_vector), + "rm" (host_data_seg)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_descriptors( + unsigned short count, + unsigned short *out_selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + movw %%ax,%1 + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=rm" (*out_selector) + : "a" (0x0000), + "c" (count)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_segment_base( + unsigned short selector, + unsigned long *out_base) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + shll $16,%ecx + movw %dx,%cx + 1: + " : "=a" (err), + "=c" (*out_base) + : "a" (0x0006), + "b" (selector) + : "edx"); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_segment_base( + unsigned short selector, + unsigned long base) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0007), + "b" (selector), + "c" (base >> 16), + "d" (base)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_segment_limit( + unsigned short selector, + unsigned limit) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0008), + "b" (selector), + "c" (limit >> 16), + "d" (limit)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_create_code_segment_alias( + unsigned short code_selector, + unsigned short *out_data_selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + movw %%ax,%1 + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=rm" (*out_data_selector) + : "a" (0x000a), + "b" (code_selector)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_descriptor( + unsigned short selector, + struct i386_descriptor *out_descriptor) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000b), + "b" (selector), + "D" (out_descriptor)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_descriptor( + unsigned short selector, + struct i386_descriptor *descriptor) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000c), + "b" (selector), + "D" (descriptor)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_specific_descriptor( + unsigned short selector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x000d), + "b" (selector)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_exception_handler( + unsigned char trapno, + struct far_pointer_32 *out_vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=c" (out_vector->seg), + "=d" (out_vector->ofs) + : "a" (0x0202), + "b" (trapno)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_exception_handler( + unsigned char trapno, + struct far_pointer_32 *vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0203), + "b" (trapno), + "c" (vector->seg), + "d" (vector->ofs)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_interrupt_handler( + unsigned char intvec, + struct far_pointer_32 *out_vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=c" (out_vector->seg), + "=d" (out_vector->ofs) + : "a" (0x0204), + "b" (intvec)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_set_interrupt_handler( + unsigned char intvec, + struct far_pointer_32 *vector) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0205), + "b" (intvec), + "c" (vector->seg), + "d" (vector->ofs)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_simulate_real_mode_interrupt( + unsigned char intnum, + struct real_call_data *call_data) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0300), + "b" ((unsigned short)intnum), + "c" (0), + "D" (call_data)); + + return err; +} + +struct dpmi_version_status +{ + unsigned char minor_version; + unsigned char major_version; + unsigned short flags; + unsigned char slave_pic_base; + unsigned char master_pic_base; + unsigned char processor_type; +}; + +MACH_INLINE void dpmi_get_version(struct dpmi_version_status *status) +{ + asm volatile(" + int $0x31 + " : "=a" (*((short*)&status->minor_version)), + "=b" (status->flags), + "=c" (status->processor_type), + "=d" (*((short*)&status->slave_pic_base)) + : "a" (0x0400)); +} + +MACH_INLINE dpmi_error_t dpmi_allocate_memory( + unsigned size, + unsigned *out_linear_addr, + unsigned *out_mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + shll $16,%%ebx + movw %%cx,%%bx + shll $16,%%esi + movw %%di,%%si + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_linear_addr), + "=S" (*out_mem_handle) + : "a" (0x0501), + "b" (size >> 16), + "c" (size) + : "ebx", "ecx", "esi", "edi"); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_free_memory( + unsigned mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0502), + "S" (mem_handle >> 16), + "D" (mem_handle)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_allocate_linear_memory( + unsigned linear_addr, + unsigned size, + unsigned flags, + unsigned *out_linear_addr, + unsigned *out_mem_handle) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_linear_addr), + "=S" (*out_mem_handle) + : "a" (0x0504), + "b" (linear_addr), + "c" (size), + "d" (flags)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_resize_linear_memory( + unsigned handle, + unsigned new_size, + unsigned flags, + unsigned short *update_selector_array, + unsigned update_selector_count, + unsigned *out_new_linear_addr) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_new_linear_addr) + : "a" (0x0505), + "b" (update_selector_array), + "c" (new_size), + "d" (flags), + "S" (handle), + "D" (update_selector_count)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_map_conventional_memory( + unsigned handle, + vm_offset_t offset, + vm_offset_t low_addr, + vm_size_t page_count) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0509), + "S" (handle), + "b" (offset), + "c" (page_count), + "d" (low_addr)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_lock_linear_region( + vm_offset_t start_la, + vm_size_t size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0600), + "b" (start_la >> 16), + "c" (start_la), + "S" (size >> 16), + "D" (size)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_unlock_linear_region( + vm_offset_t start_la, + vm_size_t size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + xorw %%ax,%%ax + 1: + " : "=a" (err) + : "a" (0x0601), + "b" (start_la >> 16), + "c" (start_la), + "S" (size >> 16), + "D" (size)); + + return err; +} + +MACH_INLINE dpmi_error_t dpmi_get_page_size( + unsigned *out_page_size) +{ + dpmi_error_t err; + + asm volatile(" + int $0x31 + jc 1f + shll $16,%%ebx + movw %%cx,%%bx + xorw %%ax,%%ax + 1: + " : "=a" (err), + "=b" (*out_page_size) + : "a" (0x0604) + : "ecx"); + + return err; +} + + +#endif /* _FLUX_X86_DOS_DPMI_H_ */ diff --git a/apps/rmgr/include/flux/x86/dos/vcpi.h b/apps/rmgr/include/flux/x86/dos/vcpi.h new file mode 100644 index 0000000..99b56b0 --- /dev/null +++ b/apps/rmgr/include/flux/x86/dos/vcpi.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_DOS_VCPI_H_ +#define _FLUX_X86_DOS_VCPI_H_ + +struct vcpi_switch_data +{ + vm_offset_t phys_pdir; + vm_offset_t lin_gdt; + vm_offset_t lin_idt; + unsigned short ldt_sel; + unsigned short tss_sel; + unsigned long entry_eip; + unsigned short entry_cs; +}; + +#endif /* _FLUX_X86_DOS_VCPI_H_ */ diff --git a/apps/rmgr/include/flux/x86/eflags.h b/apps/rmgr/include/flux/x86/eflags.h new file mode 100644 index 0000000..7a0cf64 --- /dev/null +++ b/apps/rmgr/include/flux/x86/eflags.h @@ -0,0 +1,53 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_EFLAGS_H_ +#define _FLUX_X86_EFLAGS_H_ + +/* + * i386 flags register + */ +#define EFL_CF 0x00000001 /* carry */ +#define EFL_PF 0x00000004 /* parity of low 8 bits */ +#define EFL_AF 0x00000010 /* carry out of bit 3 */ +#define EFL_ZF 0x00000040 /* zero */ +#define EFL_SF 0x00000080 /* sign */ +#define EFL_TF 0x00000100 /* trace trap */ +#define EFL_IF 0x00000200 /* interrupt enable */ +#define EFL_DF 0x00000400 /* direction */ +#define EFL_OF 0x00000800 /* overflow */ +#define EFL_IOPL 0x00003000 /* IO privilege level: */ +#define EFL_IOPL_KERNEL 0x00000000 /* kernel */ +#define EFL_IOPL_USER 0x00003000 /* user */ +#define EFL_NT 0x00004000 /* nested task */ +#define EFL_RF 0x00010000 /* resume without tracing */ +#define EFL_VM 0x00020000 /* virtual 8086 mode */ +#define EFL_AC 0x00040000 /* alignment check */ +#define EFL_VIF 0x00080000 /* virtual interrupt flag */ +#define EFL_VIP 0x00100000 /* virtual interrupt pending */ +#define EFL_ID 0x00200000 /* CPUID instruction support */ + +#endif _FLUX_X86_EFLAGS_H_ diff --git a/apps/rmgr/include/flux/x86/exec/elf.h b/apps/rmgr/include/flux/x86/exec/elf.h new file mode 100644 index 0000000..0c3f9a1 --- /dev/null +++ b/apps/rmgr/include/flux/x86/exec/elf.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_EXEC_ELF_H_ +#define _FLUX_X86_EXEC_ELF_H_ + +typedef unsigned long Elf32_Addr; +typedef unsigned short Elf32_Half; +typedef unsigned long Elf32_Off; +typedef signed long Elf32_Sword; +typedef unsigned long Elf32_Word; + +/* Architecture identification parameters for x86 architecture. */ +#define MY_EI_DATA ELFDATA2LSB +#define MY_E_MACHINE EM_386 + +#endif /* _FLUX_X86_EXEC_ELF_H_ */ diff --git a/apps/rmgr/include/flux/x86/far_ptr.h b/apps/rmgr/include/flux/x86/far_ptr.h new file mode 100644 index 0000000..cd5c2b6 --- /dev/null +++ b/apps/rmgr/include/flux/x86/far_ptr.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_FAR_PTR_H_ +#define _FLUX_X86_FAR_PTR_H_ + +struct far_pointer_16 +{ + unsigned short ofs; + unsigned short seg; +}; + +struct far_pointer_32 +{ + unsigned long ofs; + unsigned short seg; +}; + +#endif /* _FLUX_X86_FAR_PTR_H_ */ diff --git a/apps/rmgr/include/flux/x86/fdev.h b/apps/rmgr/include/flux/x86/fdev.h new file mode 100644 index 0000000..5e1d99a --- /dev/null +++ b/apps/rmgr/include/flux/x86/fdev.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Machine-specific definitions for device interface. + */ + +#ifndef _FLUX_X86_FDEV_H_ +#define _FLUX_X86_FDEV_H_ + +#include + +#endif /* _FLUX_X86_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/x86/fp_reg.h b/apps/rmgr/include/flux/x86/fp_reg.h new file mode 100644 index 0000000..dbc1055 --- /dev/null +++ b/apps/rmgr/include/flux/x86/fp_reg.h @@ -0,0 +1,108 @@ +/* + * Mach Operating System + * Copyright (c) 1992-1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_FP_REG_H_ +#define _FLUX_X86_FP_REG_H_ +/* + * Floating point registers and status, as saved + * and restored by FP save/restore instructions. + */ +struct i386_fp_save { + unsigned short fp_control; /* control */ + unsigned short fp_unused_1; + unsigned short fp_status; /* status */ + unsigned short fp_unused_2; + unsigned short fp_tag; /* register tags */ + unsigned short fp_unused_3; + unsigned int fp_eip; /* eip at failed instruction */ + unsigned short fp_cs; /* cs at failed instruction */ + unsigned short fp_opcode; /* opcode of failed instruction */ + unsigned int fp_dp; /* data address */ + unsigned short fp_ds; /* data segment */ + unsigned short fp_unused_4; +}; + +struct i386_fp_regs { + unsigned short fp_reg_word[5][8]; + /* space for 8 80-bit FP registers */ +}; + +/* + * Control register + */ +#define FPC_IE 0x0001 /* enable invalid operation + exception */ +#define FPC_IM FPC_IE +#define FPC_DE 0x0002 /* enable denormalized operation + exception */ +#define FPC_DM FPC_DE +#define FPC_ZE 0x0004 /* enable zero-divide exception */ +#define FPC_ZM FPC_ZE +#define FPC_OE 0x0008 /* enable overflow exception */ +#define FPC_OM FPC_OE +#define FPC_UE 0x0010 /* enable underflow exception */ +#define FPC_PE 0x0020 /* enable precision exception */ +#define FPC_PC 0x0300 /* precision control: */ +#define FPC_PC_24 0x0000 /* 24 bits */ +#define FPC_PC_53 0x0200 /* 53 bits */ +#define FPC_PC_64 0x0300 /* 64 bits */ +#define FPC_RC 0x0c00 /* rounding control: */ +#define FPC_RC_RN 0x0000 /* round to nearest or even */ +#define FPC_RC_RD 0x0400 /* round down */ +#define FPC_RC_RU 0x0800 /* round up */ +#define FPC_RC_CHOP 0x0c00 /* chop */ +#define FPC_IC 0x1000 /* infinity control (obsolete) */ +#define FPC_IC_PROJ 0x0000 /* projective infinity */ +#define FPC_IC_AFF 0x1000 /* affine infinity (std) */ + +/* + * Status register + */ +#define FPS_IE 0x0001 /* invalid operation */ +#define FPS_DE 0x0002 /* denormalized operand */ +#define FPS_ZE 0x0004 /* divide by zero */ +#define FPS_OE 0x0008 /* overflow */ +#define FPS_UE 0x0010 /* underflow */ +#define FPS_PE 0x0020 /* precision */ +#define FPS_SF 0x0040 /* stack flag */ +#define FPS_ES 0x0080 /* error summary */ +#define FPS_C0 0x0100 /* condition code bit 0 */ +#define FPS_C1 0x0200 /* condition code bit 1 */ +#define FPS_C2 0x0400 /* condition code bit 2 */ +#define FPS_TOS 0x3800 /* top-of-stack pointer */ +#define FPS_TOS_SHIFT 11 +#define FPS_C3 0x4000 /* condition code bit 3 */ +#define FPS_BUSY 0x8000 /* FPU busy */ + +/* + * Kind of floating-point support provided by kernel. + */ +#define FP_NO 0 /* no floating point */ +#define FP_SOFT 1 /* software FP emulator */ +#define FP_287 2 /* 80287 */ +#define FP_387 3 /* 80387 or 80486 */ + +#endif /* _FLUX_X86_FP_REG_H_ */ diff --git a/apps/rmgr/include/flux/x86/gate_init.h b/apps/rmgr/include/flux/x86/gate_init.h new file mode 100644 index 0000000..0e933b3 --- /dev/null +++ b/apps/rmgr/include/flux/x86/gate_init.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * This file defines a simple, clean method provided by the OS toolkit + * for initializing x86 gate descriptors: + * call gates, interrupt gates, trap gates, and task gates. + * Simply create a table of gate_init_entry structures + * (or use the corresponding assembly-language macros below), + * and then call the x86_gate_init() routine. + */ +#ifndef _FLUX_X86_KERN_GATE_INIT_H_ +#define _FLUX_X86_KERN_GATE_INIT_H_ + +#ifndef ASSEMBLER + +#include + +/* One entry in the list of gates to initialized. + Terminate with an entry with a null entrypoint. */ +struct gate_init_entry +{ + unsigned entrypoint; + unsigned short vector; + unsigned short type; +}; + +struct x86_gate; + +__FLUX_BEGIN_DECLS +/* Initialize a set of gates in a descriptor table. + All gates will use the same code segment selector, 'entry_cs'. */ +void gate_init(struct x86_gate *dest, const struct gate_init_entry *src, + unsigned entry_cs); +__FLUX_END_DECLS + +#else /* ASSEMBLER */ + +/* + * We'll be using macros to fill in a table in data hunk 2 + * while writing trap entrypoint routines at the same time. + * Here's the header that comes before everything else. + */ +#define GATE_INITTAB_BEGIN(name) \ + .data 2 ;\ +ENTRY(name) ;\ + .text + +/* + * Interrupt descriptor table and code vectors for it. + */ +#define GATE_ENTRY(n,entry,type) \ + .data 2 ;\ + .long entry ;\ + .word n ;\ + .word type ;\ + .text + +/* + * Terminator for the end of the table. + */ +#define GATE_INITTAB_END \ + .data 2 ;\ + .long 0 ;\ + .text + + +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_KERN_GATE_INIT_H_ */ diff --git a/apps/rmgr/include/flux/x86/gdb.h b/apps/rmgr/include/flux/x86/gdb.h new file mode 100644 index 0000000..101bdb4 --- /dev/null +++ b/apps/rmgr/include/flux/x86/gdb.h @@ -0,0 +1,79 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + * Loosely based on i386-stub.c from GDB 4.14 + */ +/* + * Definitions for remote GDB debugging of x86 programs. + */ +#ifndef _FLUX_X86_GDB_H_ +#define _FLUX_X86_GDB_H_ + +#include + +/* This structure represents the x86 register state frame as GDB wants it. */ +struct gdb_state +{ + unsigned eax; + unsigned ecx; + unsigned edx; + unsigned ebx; + unsigned esp; + unsigned ebp; + unsigned esi; + unsigned edi; + unsigned eip; + unsigned eflags; + unsigned cs; + unsigned ss; + unsigned ds; + unsigned es; + unsigned fs; + unsigned gs; +}; + +struct trap_state; +struct termios; + +/* + * While copying data to or from arbitrary locations, + * the gdb_copyin() and gdb_copyout() routines set this address + * so they can recover from any memory access traps that may occur. + * On receiving a trap, if this address is non-null, + * gdb_trap() simply sets the EIP to it and resumes execution, + * at which point the gdb_copyin/gdb_copyout routines return an error. + * If the default gdb_copyin/gdb_copyout routines are overridden, + * the replacement routines can use this facility as well. + */ +extern unsigned gdb_trap_recover; + +/* + * Use this macro to insert a breakpoint manually anywhere in your code. + */ +#define gdb_breakpoint() asm volatile("int $3"); + + +__FLUX_BEGIN_DECLS +/* + * Set up serial-line debugging over a COM port + */ +void gdb_pc_com_init(int com_port, struct termios *com_params); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_GDB_H_ */ diff --git a/apps/rmgr/include/flux/x86/multiboot.h b/apps/rmgr/include/flux/x86/multiboot.h new file mode 100644 index 0000000..59f88f7 --- /dev/null +++ b/apps/rmgr/include/flux/x86/multiboot.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_MULTIBOOT_H_ +#define _FLUX_X86_MULTIBOOT_H_ + +#include + +/* For a.out kernel boot images, the following header must appear + somewhere in the first 8192 bytes of the kernel image file. */ +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC */ + unsigned magic; + + /* Feature flags - see below. */ + unsigned flags; + + /* Checksum: magic + flags + checksum == 0 */ + unsigned checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + vm_offset_t header_addr; + vm_offset_t load_addr; + vm_offset_t load_end_addr; + vm_offset_t bss_end_addr; + vm_offset_t entry; +}; + +/* The entire multiboot_header must be contained + within the first MULTIBOOT_SEARCH bytes of the kernel image. */ +#define MULTIBOOT_SEARCH 8192 + +/* Magic value identifying the multiboot_header. */ +#define MULTIBOOT_MAGIC 0x1badb002 + +/* Features flags for 'flags'. + If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set + and it doesn't understand it, it must fail. */ +#define MULTIBOOT_MUSTKNOW 0x0000ffff + +/* Align all boot modules on page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must be provided memory information in multiboot_info structure */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Use the load address fields above instead of the ones in the a.out header + to figure out what to load where, and what to do afterwards. + This should only be needed for a.out kernel images + (ELF and other formats can generally provide the needed information). */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* The boot loader passes this value in register EAX to signal the kernel + that the multiboot method is being used */ +#define MULTIBOOT_VALID 0x2badb002 + +/* The boot loader passes this data structure to the kernel in + register EBX on entry. */ +struct multiboot_info +{ + /* These flags indicate which parts of the multiboot_info are valid; + see below for the actual flag bit definitions. */ + unsigned flags; + + /* Lower/Upper memory installed in the machine. + Valid only if MULTIBOOT_MEMORY is set in flags word above. */ + vm_size_t mem_lower; + vm_size_t mem_upper; + + /* BIOS disk device the kernel was loaded from. + Valid only if MULTIBOOT_BOOT_DEVICE is set in flags word above. */ + unsigned char boot_device[4]; + + /* Command-line for the OS kernel: a null-terminated ASCII string. + Valid only if MULTIBOOT_CMDLINE is set in flags word above. */ + vm_offset_t cmdline; + + /* List of boot modules loaded with the kernel. + Valid only if MULTIBOOT_MODS is set in flags word above. */ + unsigned mods_count; + vm_offset_t mods_addr; + + /* Symbol information for a.out or ELF executables. */ + union + { + struct + { + /* a.out symbol information valid only if MULTIBOOT_AOUT_SYMS + is set in flags word above. */ + vm_size_t tabsize; + vm_size_t strsize; + vm_offset_t addr; + unsigned reserved; + } a; + + struct + { + /* ELF section header information valid only if + MULTIBOOT_ELF_SHDR is set in flags word above. */ + unsigned num; + vm_size_t size; + vm_offset_t addr; + unsigned shndx; + } e; + } syms; + + /* Memory map buffer. + Valid only if MULTIBOOT_MEM_MAP is set in flags word above. */ + vm_size_t mmap_count; + vm_offset_t mmap_addr; +}; + +#define MULTIBOOT_MEMORY (1L<<0) +#define MULTIBOOT_BOOT_DEVICE (1L<<1) +#define MULTIBOOT_CMDLINE (1L<<2) +#define MULTIBOOT_MODS (1L<<3) +#define MULTIBOOT_AOUT_SYMS (1L<<4) +#define MULTIBOOT_ELF_SHDR (1L<<5) +#define MULTIBOOT_MEM_MAP (1L<<6) + +/* For use with printf's %b format. */ +#define MULTIBOOT_FLAGS_FORMAT \ + "\20\1MEMORY\2BOOT_DEVICE\3CMDLINE\4MODS\5AOUT_SYMS\6ELF_SHDR\7MEM_MAP" + +/* The mods_addr field above contains the physical address of the first + of 'mods_count' multiboot_module structures. */ +struct multiboot_module +{ + /* Physical start and end addresses of the module data itself. */ + vm_offset_t mod_start; + vm_offset_t mod_end; + + /* Arbitrary ASCII string associated with the module. */ + vm_offset_t string; + + /* Boot loader must set to 0; OS must ignore. */ + unsigned reserved; +}; + + +/* The mmap_addr field above contains the physical address of the first + of the AddrRangeDesc structure. "size" represents the size of the + rest of the structure and optional padding. The offset to the beginning + of the next structure is therefore "size + 4". */ +struct AddrRangeDesc +{ + unsigned long size; + unsigned long BaseAddrLow; + unsigned long BaseAddrHigh; + unsigned long LengthLow; + unsigned long LengthHigh; + unsigned long Type; + + /* unspecified optional padding... */ +}; + +/* usable memory "Type", all others are reserved. */ +#define MB_ARD_MEMORY 1 + + +#endif /* _FLUX_X86_MULTIBOOT_H_ */ diff --git a/apps/rmgr/include/flux/x86/page.h b/apps/rmgr/include/flux/x86/page.h new file mode 100644 index 0000000..cf165a6 --- /dev/null +++ b/apps/rmgr/include/flux/x86/page.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PAGE_H_ +#define _FLUX_X86_PAGE_H_ + +#define PAGE_SHIFT 12 + +#endif /* _FLUX_X86_PAGE_H_ */ diff --git a/apps/rmgr/include/flux/x86/paging.h b/apps/rmgr/include/flux/x86/paging.h new file mode 100644 index 0000000..0b813e7 --- /dev/null +++ b/apps/rmgr/include/flux/x86/paging.h @@ -0,0 +1,182 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Definitions relating to x86 page directories and page tables. + */ +#ifndef _FLUX_X86_PAGING_H_ +#define _FLUX_X86_PAGING_H_ + +#include + +#define INTEL_OFFMASK 0xfff /* offset within page */ +#define PDESHIFT 22 /* page descriptor shift */ +#define PDEMASK 0x3ff /* mask for page descriptor index */ +#define PTESHIFT 12 /* page table shift */ +#define PTEMASK 0x3ff /* mask for page table index */ + +/* + * Convert linear offset to page descriptor/page table index + */ +#define lin2pdenum(a) (((a) >> PDESHIFT) & PDEMASK) +#define lin2ptenum(a) (((a) >> PTESHIFT) & PTEMASK) + +/* + * Convert page descriptor/page table index to linear address + */ +#define pdenum2lin(a) ((vm_offset_t)(a) << PDESHIFT) +#define ptenum2lin(a) ((vm_offset_t)(a) << PTESHIFT) + +/* + * Number of ptes/pdes in a page table/directory. + */ +#define NPTES (ptoa(1)/sizeof(pt_entry_t)) +#define NPDES (ptoa(1)/sizeof(pt_entry_t)) + +/* + * Hardware pte bit definitions (to be used directly on the ptes + * without using the bit fields). + */ +#define INTEL_PTE_VALID 0x00000001 +#define INTEL_PTE_WRITE 0x00000002 +#define INTEL_PTE_USER 0x00000004 +#define INTEL_PTE_WTHRU 0x00000008 +#define INTEL_PTE_NCACHE 0x00000010 +#define INTEL_PTE_REF 0x00000020 +#define INTEL_PTE_MOD 0x00000040 +#define INTEL_PTE_GLOBAL 0x00000100 +#define INTEL_PTE_AVAIL 0x00000e00 +#define INTEL_PTE_PFN 0xfffff000 + +#define INTEL_PDE_VALID 0x00000001 +#define INTEL_PDE_WRITE 0x00000002 +#define INTEL_PDE_USER 0x00000004 +#define INTEL_PDE_WTHRU 0x00000008 +#define INTEL_PDE_NCACHE 0x00000010 +#define INTEL_PDE_REF 0x00000020 +#define INTEL_PDE_MOD 0x00000040 /* only for superpages */ +#define INTEL_PDE_SUPERPAGE 0x00000080 +#define INTEL_PDE_GLOBAL 0x00000100 /* only for superpages */ +#define INTEL_PDE_AVAIL 0x00000e00 +#define INTEL_PDE_PFN 0xfffff000 + +/* + * Macros to translate between page table entry values + * and physical addresses. + */ +#define pa_to_pte(a) ((a) & INTEL_PTE_PFN) +#define pte_to_pa(p) ((p) & INTEL_PTE_PFN) +#define pte_increment_pa(p) ((p) += INTEL_OFFMASK+1) + +#define pa_to_pde(a) ((a) & INTEL_PDE_PFN) +#define pde_to_pa(p) ((p) & INTEL_PDE_PFN) +#define pde_increment_pa(p) ((p) += INTEL_OFFMASK+1) + +/* + * Superpage-related macros. + */ +#define SUPERPAGE_SHIFT PDESHIFT +#define SUPERPAGE_SIZE (1 << SUPERPAGE_SHIFT) +#define SUPERPAGE_MASK (SUPERPAGE_SIZE - 1) + +#define round_superpage(x) ((vm_offset_t)((((vm_offset_t)(x)) \ + + SUPERPAGE_MASK) & ~SUPERPAGE_MASK)) +#define trunc_superpage(x) ((vm_offset_t)(((vm_offset_t)(x)) \ + & ~SUPERPAGE_MASK)) + +#define superpage_aligned(x) ((((vm_offset_t)(x)) & SUPERPAGE_MASK) == 0) + + +#ifndef ASSEMBLER + +#include +#include +#include + +/* + * i386/i486/i860 Page Table Entry + */ +typedef unsigned int pt_entry_t; +#define PT_ENTRY_NULL ((pt_entry_t *) 0) + +typedef unsigned int pd_entry_t; +#define PD_ENTRY_NULL ((pt_entry_t *) 0) + +/* + * Read and write the page directory base register (PDBR). + */ +#define set_pdbr(pdir) set_cr3(pdir) +#define get_pdbr() get_cr3() + +/* + * Invalidate the entire TLB. + */ +#define inval_tlb() set_pdbr(get_pdbr()) + +/* + * Load page directory 'pdir' and turn paging on. + * Assumes that 'pdir' equivalently maps the physical memory + * that contains the currently executing code, + * the currently loaded GDT and IDT, etc. + */ +FLUX_INLINE void paging_enable(vm_offset_t pdir) +{ + /* Load the page directory. */ + set_cr3(pdir); + + /* Turn on paging. */ + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + " : : "r" (get_cr0() | CR0_PG)); +} + +/* + * Turn paging off. + * Assumes that the currently loaded page directory + * equivalently maps the physical memory + * that contains the currently executing code, + * the currently loaded GDT and IDT, etc. + */ +FLUX_INLINE void paging_disable(void) +{ + /* Turn paging off. */ + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + " : : "r" (get_cr0() & ~CR0_PG)); + + /* Flush the TLB. */ + set_cr3(0); +} + +#endif /* !ASSEMBLER */ + +#endif _FLUX_X86_PAGING_H_ diff --git a/apps/rmgr/include/flux/x86/pc/base_irq.h b/apps/rmgr/include/flux/x86/pc/base_irq.h new file mode 100644 index 0000000..3f0a489 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/base_irq.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1996-1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PC_BASE_IRQ_H_ +#define _FLUX_X86_PC_BASE_IRQ_H_ + + +/* On normal PCs, there are always 16 IRQ lines. */ +#define IRQ_COUNT 16 + + +/* Variables storing the master and slave PIC interrupt vector base. */ +extern int irq_master_base, irq_slave_base; + + +/* Fill an IRQ gate in the base IDT. + Always uses an interrupt gate; just set `access' to the privilege level. */ +#define fill_irq_gate(irq_num, entry, selector, access) \ + fill_gate(&base_idt[(irq_num) < 8 \ + ? irq_master_base+(irq_num) \ + : irq_slave_base+(irq_num)-8], \ + entry, selector, ACC_INTR_GATE | (access), 0) + +#endif /* _FLUX_X86_PC_BASE_IRQ_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/base_multiboot.h b/apps/rmgr/include/flux/x86/pc/base_multiboot.h new file mode 100644 index 0000000..65169df --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/base_multiboot.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * Functions and data definitions for kernels + * that want to start up from a MultiBoot boot loader. + */ +#ifndef _FLUX_X86_PC_BASE_MULTIBOOT_H_ +#define _FLUX_X86_PC_BASE_MULTIBOOT_H_ + +#include +#include +#include + +/* + * This variable holds a copy of the multiboot_info structure + * which was passed to us by the boot loader. + */ +extern struct multiboot_info boot_info; + +__FLUX_BEGIN_DECLS +/* + * This function digs through the boot_info structure + * to find out what physical memory is available to us, + * and initalizes the malloc_lmm with those memory regions. + * It is smart enough to skip our own executable, wherever it may be, + * as well as the important stuff passed by the boot loader + * such as our command line and boot modules. + */ +void base_multiboot_init_mem(void); + +/* + * This function parses the command-line passed by the boot loader + * into a nice POSIX-like set of argument and environment strings. + * It depends on being able to call malloc(). + */ +void base_multiboot_init_cmdline(); + +/* + * This is the first C routine called by crt0/multiboot.o; + * its default implementation sets up the base kernel environment + * and then calls main() and exit(). + */ +void multiboot_main(vm_offset_t boot_info_pa); + +/* + * This routine finds the MultiBoot boot module in the boot_info structure + * whose associated `string' matches the provided `string' parameter. + * If the strings attached to boot modules are assumed to be filenames, + * this function can serve as a primitive "open" operation + * for a simple "boot module file system". + */ +struct multiboot_module *base_multiboot_find(const char *string); + +/* + * Dump out the boot_info struct nicely. + */ +void multiboot_info_dump(); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_BASE_MULTIBOOT_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/com_cons.h b/apps/rmgr/include/flux/x86/pc/com_cons.h new file mode 100644 index 0000000..8876e01 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/com_cons.h @@ -0,0 +1,56 @@ +/* + * Simple polling serial console for the Flux OS toolkit + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ +#ifndef _FLUX_X86_PC_COM_CONS_H_ +#define _FLUX_X86_PC_COM_CONS_H_ + +#include + +struct termios; + +__FLUX_BEGIN_DECLS +/* + * This routine must be called once to initialize the COM port. + * The com_port parameter specifies which COM port to use, 1 through 4. + * The supplied termios structure indicates the baud rate and other settings. + * If com_params is NULL, a default of 9600,8,N,1 is used. + */ +void com_cons_init(int com_port, struct termios *com_params); + +/* + * Primary serial character I/O routines. + */ +int com_cons_getchar(void); +void com_cons_putchar(int ch); + +/* + * Since the com_console operates by polling, + * there is no need to handle serial interrupts in order to do basic I/O. + * However, if you want to be notified up when a character is received, + * call this function immediately after com_cons_init(), + * and make sure the appropriate IDT entry is initialized properly. + * For example, the serial debugging code for the PC COM port + * uses this so that the program can be woken up + * when the user presses CTRL-C from the remote debugger. + */ +void com_cons_enable_receive_interrupt(); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_COM_CONS_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/debug.h b/apps/rmgr/include/flux/x86/pc/debug.h new file mode 100644 index 0000000..6ee78cc --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/debug.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _KUKM_I386_PC_DEBUG_H_ +#define _KUKM_I386_PC_DEBUG_H_ + +#ifdef ASSEMBLER +#ifdef DEBUG + + +/* Poke a character directly onto the VGA text display, + as a very quick, mostly-reliable status indicator. + Assumes ss is a kernel data segment register. */ +#define POKE_STATUS(char,scratch) \ + ss/*XXX gas bug */ ;\ + movl %ss:_phys_mem_va,scratch ;\ + addl $0xb8000+80*2*13+40*2,scratch ;\ + movb char,%ss:(scratch) ;\ + movb $0xf0,%ss:1(scratch) + + +#else !DEBUG + +#define POKE_STATUS(char,scratch) + +#endif !DEBUG +#else !ASSEMBLER +#ifdef DEBUG + +#include + + +#define POKE_STATUS(string) \ + ({ unsigned char *s = (string); \ + extern vm_offset_t phys_mem_va; \ + short *d = (short*)(phys_mem_va+0xb8000+80*2*13+40*2); \ + while (*s) { (*d++) = 0x3000 | (*s++); } \ + *d = ' '; \ + }) + + +#else !DEBUG + +#define POKE_STATUS(char) + +#endif !DEBUG +#endif !ASSEMBLER + + +#include_next "debug.h" + +#endif _KUKM_I386_PC_DEBUG_H_ diff --git a/apps/rmgr/include/flux/x86/pc/direct_cons.h b/apps/rmgr/include/flux/x86/pc/direct_cons.h new file mode 100644 index 0000000..8b8b7ef --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/direct_cons.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * The "direct console" is an extremely simple console "driver" for PCs, + * which writes directly to CGA/EGA/VGA display memory to output text, + * and reads directly from the keyboard using polling to read characters. + * The putchar and getchar routines are completely independent; + * either can be used without the other. + */ +#ifndef _FLUX_X86_PC_DIRECT_CONS_H_ +#define _FLUX_X86_PC_DIRECT_CONS_H_ + +#include + +__FLUX_BEGIN_DECLS +void direct_cons_putchar(unsigned char c); +int direct_cons_getchar(void); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_DIRECT_CONS_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/fdev.h b/apps/rmgr/include/flux/x86/pc/fdev.h new file mode 100644 index 0000000..8252a08 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/fdev.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * PC-specific definitions for device interface. + */ + +#ifndef _FLUX_X86_PC_FDEV_H_ +#define _FLUX_X86_PC_FDEV_H_ + +#include + +__FLUX_BEGIN_DECLS +/* + * DRQ manipulation. + */ +int fdev_dma_alloc(int channel); +void fdev_dma_free(int channel); + +/* + * I/O ports (modeled after the Linux interface). + */ +int fdev_port_avail(unsigned port, unsigned size); +void fdev_port_alloc(unsigned port, unsigned size); +void fdev_port_free(unsigned port, unsigned size); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_FDEV_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/irq_list.h b/apps/rmgr/include/flux/x86/pc/irq_list.h new file mode 100644 index 0000000..cc3bb05 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/irq_list.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +/* + * This is just a handy file listing all the IRQ's on the PC, + * whether they're on the master or slave PIC, + * what interrupt line on that PIC they're connected to, + * and a simple keyword/string describing their "standard" assignment, if any. + * To use this, just define the 'irq()' macro however you want + * and #include this file in the appropriate place. + */ + +irq(master,0,0,timer) +irq(master,1,1,keyboard) +irq(master,2,2,slave) +irq(master,3,3,com2) +irq(master,4,4,com1) +irq(master,5,5,lpt2) +irq(master,6,6,fd) +irq(master,7,7,lpt1) + +irq(slave,0,8,rtc) +irq(slave,1,9,) +irq(slave,2,10,) +irq(slave,3,11,) +irq(slave,4,12,) +irq(slave,5,13,coprocessor) +irq(slave,6,14,hd) +irq(slave,7,15,) + diff --git a/apps/rmgr/include/flux/x86/pc/keyboard.h b/apps/rmgr/include/flux/x86/pc/keyboard.h new file mode 100644 index 0000000..427f452 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/keyboard.h @@ -0,0 +1,159 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* ********************************************************************** + File: kd.h + Description: definitions for AT keyboard/display driver + Authors: Eugene Kuerner, Adrienne Jardetzky, Mike Kupfer + + $ Header: $ + + Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989. + All rights reserved. +********************************************************************** */ +/* + Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc., +Cupertino, California. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Olivetti +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + + OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* + * Definitions describing the PC keyboard hardware. + */ +#ifndef _FLUX_X86_PC_KEYBOARD_H_ +#define _FLUX_X86_PC_KEYBOARD_H_ + +#include + +/* + * Keyboard I/O ports. + */ +#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ +#define K_STATUS 0x64 /* keybd status (read-only) */ +#define K_CMD 0x64 /* keybd ctlr command (write-only) */ + +/* + * Bit definitions for K_STATUS port. + */ +#define K_OBUF_FUL 0x01 /* output (from keybd) buffer full */ +#define K_IBUF_FUL 0x02 /* input (to keybd) buffer full */ +#define K_SYSFLAG 0x04 /* "System Flag" */ +#define K_CMD_DATA 0x08 /* 1 = input buf has cmd, 0 = data */ +#define K_KBD_INHIBIT 0x10 /* 0 if keyboard inhibited */ +#define K_AUX_OBUF_FUL 0x20 /* 1 = obuf holds aux device data */ +#define K_TIMEOUT 0x40 /* timout error flag */ +#define K_PARITY_ERROR 0x80 /* parity error flag */ + +/* + * Keyboard controller commands (sent to K_CMD port). + */ +#define KC_CMD_READ 0x20 /* read controller command byte */ +#define KC_CMD_WRITE 0x60 /* write controller command byte */ +#define KC_CMD_DIS_AUX 0xa7 /* disable auxiliary device */ +#define KC_CMD_ENB_AUX 0xa8 /* enable auxiliary device */ +#define KC_CMD_TEST_AUX 0xa9 /* test auxiliary device interface */ +#define KC_CMD_SELFTEST 0xaa /* keyboard controller self-test */ +#define KC_CMD_TEST 0xab /* test keyboard interface */ +#define KC_CMD_DUMP 0xac /* diagnostic dump */ +#define KC_CMD_DISABLE 0xad /* disable keyboard */ +#define KC_CMD_ENABLE 0xae /* enable keyboard */ +#define KC_CMD_RDKBD 0xc4 /* read keyboard ID */ +#define KC_CMD_WIN 0xd0 /* read output port */ +#define KC_CMD_WOUT 0xd1 /* write output port */ +#define KC_CMD_ECHO 0xee /* used for diagnostic testing */ +#define KC_CMD_PULSE 0xff /* pulse bits 3-0 based on low nybble */ + +/* + * Keyboard commands (send to K_RDWR). + */ +#define K_CMD_LEDS 0xed /* set status LEDs (caps lock, etc.) */ + +/* + * Bit definitions for controller command byte (sent following + * K_CMD_WRITE command). + */ +#define K_CB_ENBLIRQ 0x01 /* enable data-ready intrpt */ +#define K_CB_SETSYSF 0x04 /* Set System Flag */ +#define K_CB_INHBOVR 0x08 /* Inhibit Override */ +#define K_CB_DISBLE 0x10 /* disable keyboard */ + +/* + * Bit definitions for "Indicator Status Byte" (sent after a + * K_CMD_LEDS command). If the bit is on, the LED is on. Undefined + * bit positions must be 0. + */ +#define K_LED_SCRLLK 0x1 /* scroll lock */ +#define K_LED_NUMLK 0x2 /* num lock */ +#define K_LED_CAPSLK 0x4 /* caps lock */ + +/* + * Bit definitions for "Miscellaneous port B" (K_PORTB). + */ +/* read/write */ +#define K_ENABLETMR2 0x01 /* enable output from timer 2 */ +#define K_SPKRDATA 0x02 /* direct input to speaker */ +#define K_ENABLEPRTB 0x04 /* "enable" port B */ +#define K_EIOPRTB 0x08 /* enable NMI on parity error */ +/* read-only */ +#define K_REFRESHB 0x10 /* refresh flag from INLTCONT PAL */ +#define K_OUT2B 0x20 /* timer 2 output */ +#define K_ICKB 0x40 /* I/O channel check (parity error) */ + +/* + * Bit definitions for the keyboard controller's output port. + */ +#define KO_SYSRESET 0x01 /* processor reset */ +#define KO_GATE20 0x02 /* A20 address line enable */ +#define KO_AUX_DATA_OUT 0x04 /* output data to auxiliary device */ +#define KO_AUX_CLOCK 0x08 /* auxiliary device clock */ +#define KO_OBUF_FUL 0x10 /* keyboard output buffer full */ +#define KO_AUX_OBUF_FUL 0x20 /* aux device output buffer full */ +#define KO_CLOCK 0x40 /* keyboard clock */ +#define KO_DATA_OUT 0x80 /* output data to keyboard */ + +__FLUX_BEGIN_DECLS +extern void kb_command(unsigned char ch); +__FLUX_END_DECLS + +#endif _FLUX_X86_PC_KEYBOARD_H_ diff --git a/apps/rmgr/include/flux/x86/pc/phys_lmm.h b/apps/rmgr/include/flux/x86/pc/phys_lmm.h new file mode 100644 index 0000000..df1dc25 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/phys_lmm.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +/* + * PC-specific flag bits and priority values + * for the List Memory Manager (LMM) + * relevant for kernels managing physical memory. + */ +#ifndef _FLUX_X86_PC_PHYS_LMM_H_ +#define _FLUX_X86_PC_PHYS_LMM_H_ + +#include +#include + +/* + * <1MB memory is most precious, then <16MB memory, then high memory. + * Assign priorities to each region accordingly + * so that high memory will be used first when possible, + * then 16MB memory, then 1MB memory. + */ +#define LMM_PRI_1MB -2 +#define LMM_PRI_16MB -1 +#define LMM_PRI_HIGH 0 + +/* + * For memory <1MB, both LMMF_1MB and LMMF_16MB will be set. + * For memory from 1MB to 16MB, only LMMF_16MB will be set. + * For all memory higher than that, neither will be set. + */ +#define LMMF_1MB 0x01 +#define LMMF_16MB 0x02 + +__FLUX_BEGIN_DECLS +/* + * This routine sets up the malloc_lmm with three regions, + * one for each of the memory types above. + * You can then call phys_lmm_add() to add memory to those regions. + */ +void phys_lmm_init(void); + +/* + * Call one of these routines to add a chunk of physical memory found + * to the appropriate region(s) on the malloc_lmm. + * The provided memory block may be arbitrarily aligned + * and may cross region boundaries (e.g. the 16MB boundary); + * it will be shrunken and split apart as necessary. + * Note that these routines take _physical_ addresses, + * not virtual addresses as the underlying LMM routines do. + */ +void phys_lmm_add(vm_offset_t min_pa, vm_size_t size); +void i16_phys_lmm_add(vm_offset_t min_pa, vm_size_t size); +__FLUX_END_DECLS + +/* + * The above routines keep this variable up-to-date + * so that it always records the highest physical memory address seen so far; + * i.e. the end address of the highest free block added to the free list. + * After all physical memory is found and collected on the free list, + * this variable will contain the highest physical memory address + * that the kernel should ever have to deal with. + */ +extern vm_offset_t phys_mem_max; + +#endif /* _FLUX_X86_PC_PHYS_LMM_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/pic.h b/apps/rmgr/include/flux/x86/pc/pic.h new file mode 100644 index 0000000..bcc3049 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/pic.h @@ -0,0 +1,223 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* +Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760 +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and +without fee is hereby granted, provided that the above +copyright notice appears in all copies and that both the +copyright notice and this permission notice appear in +supporting documentation, and that the name of Prime +Computer, Inc. not be used in advertising or publicity +pertaining to distribution of the software without +specific, written prior permission. + +THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER, +INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY +SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR +OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* + * Definitions for the 8259A Programmable Interrupt Controller (PIC) + */ + +#ifndef _I386_PIC_H_ +#define _I386_PIC_H_ + +#include + +#define NINTR 0x10 +#define NPICS 0x02 + +/* +** The following are definitions used to locate the PICs in the system +** XXX "SLAVES" should be spelled "SLAVE". +*/ + +#define MASTER_PIC_BASE 0x20 +#define SLAVES_PIC_BASE 0xa0 +#define OFF_ICW 0x00 +#define OFF_OCW 0x01 + +#define MASTER_ICW (MASTER_PIC_BASE + OFF_ICW) +#define MASTER_OCW (MASTER_PIC_BASE + OFF_OCW) +#define SLAVES_ICW (SLAVES_PIC_BASE + OFF_ICW) +#define SLAVES_OCW (SLAVES_PIC_BASE + OFF_OCW) + +/* +** The following banks of definitions ICW1, ICW2, ICW3, and ICW4 are used +** to define the fields of the various ICWs for initialisation of the PICs +*/ + +/* +** ICW1 +*/ + +#define ICW_TEMPLATE 0x10 + +#define LEVL_TRIGGER 0x08 +#define EDGE_TRIGGER 0x00 +#define ADDR_INTRVL4 0x04 +#define ADDR_INTRVL8 0x00 +#define SINGLE__MODE 0x02 +#define CASCADE_MODE 0x00 +#define ICW4__NEEDED 0x01 +#define NO_ICW4_NEED 0x00 + +/* +** ICW2 +*/ + +#define PICM_VECTBASE IDT_IRQ_BASE +#define PICS_VECTBASE (PICM_VECTBASE + 0x08) + +/* +** ICW3 +*/ + +#define SLAVE_ON_IR0 0x01 +#define SLAVE_ON_IR1 0x02 +#define SLAVE_ON_IR2 0x04 +#define SLAVE_ON_IR3 0x08 +#define SLAVE_ON_IR4 0x10 +#define SLAVE_ON_IR5 0x20 +#define SLAVE_ON_IR6 0x40 +#define SLAVE_ON_IR7 0x80 + +#define I_AM_SLAVE_0 0x00 +#define I_AM_SLAVE_1 0x01 +#define I_AM_SLAVE_2 0x02 +#define I_AM_SLAVE_3 0x03 +#define I_AM_SLAVE_4 0x04 +#define I_AM_SLAVE_5 0x05 +#define I_AM_SLAVE_6 0x06 +#define I_AM_SLAVE_7 0x07 + +/* +** ICW4 +*/ + +#define SNF_MODE_ENA 0x10 +#define SNF_MODE_DIS 0x00 +#define BUFFERD_MODE 0x08 +#define NONBUFD_MODE 0x00 +#define AUTO_EOI_MOD 0x02 +#define NRML_EOI_MOD 0x00 +#define I8086_EMM_MOD 0x01 +#define SET_MCS_MODE 0x00 + +/* +** OCW1 +*/ + +#define PICM_MASK 0xFF +#define PICS_MASK 0xFF + +/* +** OCW2 +*/ + +#define NON_SPEC_EOI 0x20 +#define SPECIFIC_EOI 0x60 +#define ROT_NON_SPEC 0xa0 +#define SET_ROT_AEOI 0x80 +#define RSET_ROTAEOI 0x00 +#define ROT_SPEC_EOI 0xe0 +#define SET_PRIORITY 0xc0 +#define NO_OPERATION 0x40 + +#define SEND_EOI_IR0 0x00 +#define SEND_EOI_IR1 0x01 +#define SEND_EOI_IR2 0x02 +#define SEND_EOI_IR3 0x03 +#define SEND_EOI_IR4 0x04 +#define SEND_EOI_IR5 0x05 +#define SEND_EOI_IR6 0x06 +#define SEND_EOI_IR7 0x07 + +/* +** OCW3 +*/ + +#define OCW_TEMPLATE 0x08 +#define SPECIAL_MASK 0x40 +#define MASK_MDE_SET 0x20 +#define MASK_MDE_RST 0x00 +#define POLL_COMMAND 0x04 +#define NO_POLL_CMND 0x00 +#define READ_NEXT_RD 0x02 +#define READ_IR_ONRD 0x00 +#define READ_IS_ONRD 0x01 + + +/* +** Standard PIC initialization values for PCs. +*/ +#define PICM_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICM_ICW3 (SLAVE_ON_IR2) +#define PICM_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +#define PICS_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICS_ICW3 (I_AM_SLAVE_2) +#define PICS_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +__FLUX_BEGIN_DECLS +extern void pic_init(unsigned char master_base, unsigned char slave_base); +extern void pic_disable_irq(unsigned char irq); +extern void pic_enable_irq(unsigned char irq); +__FLUX_END_DECLS + +#include + +#define pic_enable_all() ({ \ + outb(MASTER_OCW, 0); \ + outb(SLAVES_OCW, 0); \ +}) + +#define pic_disable_all() ({ \ + outb(MASTER_OCW, PICM_MASK); \ + outb(SLAVES_OCW, PICS_MASK); \ +}) + +#define pic_ack(irq) ({ \ + outb(MASTER_ICW, NON_SPEC_EOI); \ + if ((irq) >= 8) \ + outb(SLAVES_ICW, NON_SPEC_EOI); \ +}) + +#endif _I386_PIC_H_ diff --git a/apps/rmgr/include/flux/x86/pc/pit.h b/apps/rmgr/include/flux/x86/pc/pit.h new file mode 100644 index 0000000..25d9339 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/pit.h @@ -0,0 +1,90 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Intel +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef _FLUX_X86_PC_PIT_H_ +#define _FLUX_X86_PC_PIT_H_ + +#include + +/* Definitions for 8254 Programmable Interrupt Timer ports on AT 386 */ +#define PITCTR0_PORT 0x40 /* counter 0 port */ +#define PITCTR1_PORT 0x41 /* counter 1 port */ +#define PITCTR2_PORT 0x42 /* counter 2 port */ +#define PITCTL_PORT 0x43 /* PIT control port */ +#define PITAUX_PORT 0x61 /* PIT auxiliary port */ +/* bits used in auxiliary control port for timer 2 */ +#define PITAUX_GATE2 0x01 /* aux port, PIT gate 2 input */ +#define PITAUX_OUT2 0x02 /* aux port, PIT clock out 2 enable */ + + +/* Following are used for Timer 0 */ +#define PIT_C0 0x00 /* select counter 0 */ +#define PIT_LOADMODE 0x30 /* load least significant byte followed + * by most significant byte */ +#define PIT_NDIVMODE 0x04 /*divide by N counter */ +#define PIT_SQUAREMODE 0x06 /* square-wave mode */ + +/* Used for Timer 1. Used for delay calculations in countdown mode */ +#define PIT_C1 0x40 /* select counter 1 */ +#define PIT_READMODE 0x30 /* read or load least significant byte + * followed by most significant byte */ +#define PIT_RATEMODE 0x06 /* square-wave mode for USART */ + +/* + * Clock speed for the timer in hz divided by the constant HZ + * (defined in param.h) + */ +#define CLKNUM 1193167 + + +__FLUX_BEGIN_DECLS +void init_pit(int hz); +__FLUX_END_DECLS + + +#endif /* _FLUX_X86_PC_PIT_H_ */ + diff --git a/apps/rmgr/include/flux/x86/pc/reset.h b/apps/rmgr/include/flux/x86/pc/reset.h new file mode 100644 index 0000000..43f6726 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/reset.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ + +#ifndef _FLUX_X86_PC_RESET_H_ +#define _FLUX_X86_PC_RESET_H_ + +#include + +__FLUX_BEGIN_DECLS +void pc_reset(void); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_RESET_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/rtc.h b/apps/rmgr/include/flux/x86/pc/rtc.h new file mode 100644 index 0000000..010277c --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/rtc.h @@ -0,0 +1,135 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * from: @(#)rtc.h 7.1 (Berkeley) 5/12/91 + * $\Id: rtc.h,v 1.7 1994/12/04 20:22:20 joerg Exp $ + */ +/* + * Things of use when manipulating the Real Time Clock or other stuff + * in NVRAM. + */ + +#ifndef _FLUX_X86_PC_RTC_H_ +#define _FLUX_X86_PC_RTC_H_ + +#include + +__FLUX_BEGIN_DECLS +unsigned char rtcin(unsigned char addr); +void rtcout(unsigned char addr, unsigned char val); +__FLUX_END_DECLS + +/* + * RTC Register locations + */ + +#define RTC_SEC 0x00 /* seconds */ +#define RTC_SECALRM 0x01 /* seconds alarm */ +#define RTC_MIN 0x02 /* minutes */ +#define RTC_MINALRM 0x03 /* minutes alarm */ +#define RTC_HRS 0x04 /* hours */ +#define RTC_HRSALRM 0x05 /* hours alarm */ +#define RTC_WDAY 0x06 /* week day */ +#define RTC_DAY 0x07 /* day of month */ +#define RTC_MONTH 0x08 /* month of year */ +#define RTC_YEAR 0x09 /* month of year */ + +#define RTC_STATUSA 0x0a /* status register A */ +#define RTCSA_TUP 0x80 /* time update, don't look now */ +#define RTCSA_DIVIDER 0x20 /* divider correct for 32768 Hz */ +#define RTCSA_8192 0x03 +#define RTCSA_4096 0x04 +#define RTCSA_2048 0x05 +#define RTCSA_1024 0x06 /* default for profiling */ +#define RTCSA_PROF RTCSA_1024 +#define RTC_PROFRATE 1024 +#define RTCSA_512 0x07 +#define RTCSA_256 0x08 +#define RTCSA_128 0x09 +#define RTCSA_NOPROF RTCSA_128 +#define RTC_NOPROFRATE 128 +#define RTCSA_64 0x0a +#define RTCSA_32 0x0b + +#define RTC_STATUSB 0x0b /* status register B */ +#define RTCSB_DST 0x01 /* Daylight Savings Time enable */ +#define RTCSB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */ +#define RTCSB_BCD 0x04 /* 0 = BCD, 1 = Binary coded time */ +#define RTCSB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */ +#define RTCSB_UINTR 0x10 /* 1 = enable update-ended interrupt */ +#define RTCSB_AINTR 0x20 /* 1 = enable alarm interrupt */ +#define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */ +#define RTCSB_HALT 0x80 /* stop clock updates */ + +#define RTC_INTR 0x0c /* status register C (R) interrupt source */ +#define RTCIR_UPDATE 0x10 /* update intr */ +#define RTCIR_ALARM 0x20 /* alarm intr */ +#define RTCIR_PERIOD 0x40 /* periodic intr */ +#define RTCIR_INT 0x80 /* interrupt output signal */ + +#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ +#define RTCSD_PWR 0x80 /* clock lost power */ + +#define RTC_DIAG 0x0e /* status register E - bios diagnostic */ +#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" + +#define RTC_RESET 0x0f /* status register F - reset code byte */ +#define RTCRS_RST 0x00 /* normal reset */ +#define RTCRS_LOAD 0x04 /* load system */ + +#define RTC_FDISKETTE 0x10 /* diskette drive type in upper/lower nibble */ +#define RTCFDT_NONE 0 /* none present */ +#define RTCFDT_360K 0x10 /* 360K */ +#define RTCFDT_12M 0x20 /* 1.2M */ +#define RTCFDT_720K 0x30 /* 720K */ +#define RTCFDT_144M 0x40 /* 1.44M */ +#define RTCFDT_288M 0x60 /* 2.88M */ + +#define RTC_BASELO 0x15 /* low byte of basemem size */ +#define RTC_BASEHI 0x16 /* high byte of basemem size */ +#define RTC_EXTLO 0x17 /* low byte of ext mem size, see RTC_DEXTLO */ +#define RTC_EXTHI 0x18 /* high byte of ext mem size, see RTC_DEXTHI */ + +/* + * These two should return the same info as INT 0x15 function 88. + * However, _The_Undocumented_PC_ (page 644) says IBM PS/1 and PS/2 + * systems use 0x35 and 0x36 for this purpose. + */ +#define RTC_DEXTLO 0x30 /* low byte of DETECTED extended mem size */ +#define RTC_DEXTHI 0x31 /* high byte of DETECTED extended mem size */ + +#define RTC_CENTURY 0x32 /* current century */ + +#endif /* _FLUX_X86_PC_RTC_H_ */ diff --git a/apps/rmgr/include/flux/x86/pc/serial_gdb.h b/apps/rmgr/include/flux/x86/pc/serial_gdb.h new file mode 100644 index 0000000..c68f7d0 --- /dev/null +++ b/apps/rmgr/include/flux/x86/pc/serial_gdb.h @@ -0,0 +1,34 @@ +/* + * Remote serial-line source-level debugging for the Flux OS Toolkit. + * Copyright (C) 1996-1994 Sleepless Software + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Bryan Ford + */ +#ifndef _FLUX_X86_PC_SERIAL_GDB_H_ +#define _FLUX_X86_PC_SERIAL_GDB_H_ + +#include + +extern int serial_gdb_enable; + +__FLUX_BEGIN_DECLS +extern void serial_gdb_init(); +extern int serial_gdb_signal(int *inout_sig, struct trap_state *ts); +extern void serial_gdb_shutdown(int exitcode); +__FLUX_END_DECLS + +#endif /* _FLUX_X86_PC_SERIAL_GDB_H_ */ diff --git a/apps/rmgr/include/flux/x86/pio.h b/apps/rmgr/include/flux/x86/pio.h new file mode 100644 index 0000000..bb1845d --- /dev/null +++ b/apps/rmgr/include/flux/x86/pio.h @@ -0,0 +1,108 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_PIO_H_ +#define _FLUX_X86_PIO_H_ + +#ifdef __GNUC__ + +/* This is a more reliable delay than a few short jmps. */ +#define iodelay() \ + asm volatile("pushl %eax; inb $0x80,%al; inb $0x80,%al; popl %eax") + +#define inl(port) \ +({ unsigned long _tmp__; \ + asm volatile("inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inl_p(port) ({ \ + unsigned long r; \ + r = inl(port); \ + iodelay(); \ + r; \ +}) + +#define inw(port) \ +({ unsigned short _tmp__; \ + asm volatile(".byte 0x66; inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inw_p(port) ({ \ + unsigned short r; \ + r = inw(port); \ + iodelay(); \ + r; \ +}) + +#define inb(port) \ +({ unsigned char _tmp__; \ + asm volatile("inb %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(port))); \ + _tmp__; }) +#define inb_p(port) ({ \ + unsigned char r; \ + r = inb(port); \ + iodelay(); \ + r; \ +}) + + +#define outl(port, val) \ +({ asm volatile("outl %0, %1" : : "a" (val) , "d" ((unsigned short)(port))); }) +#define outl_p(port, val) ({ \ + outl(port, val); \ + iodelay(); \ +}) + +#define outw(port, val) \ +({asm volatile(".byte 0x66; outl %0, %1" : : "a" ((unsigned short)(val)) , "d" ((unsigned short)(port))); }) +#define outw_p(port, val) ({ \ + outw(port, val); \ + iodelay(); \ +}) + +#define outb(port, val) \ +({ asm volatile("outb %0, %1" : : "a" ((unsigned char)(val)) , "d" ((unsigned short)(port))); }) +#define outb_p(port, val) ({ \ + outb(port, val); \ + iodelay(); \ +}) + + +/* Inline code works just as well for 16-bit code as for 32-bit. */ +#define i16_inl(port) inl(port) +#define i16_inl_p(port) inl_p(port) +#define i16_inw(port) inw(port) +#define i16_inw_p(port) inw_p(port) +#define i16_inb(port) inb(port) +#define i16_inb_p(port) inb_p(port) +#define i16_outl(port, val) outl(port, val) +#define i16_outl_p(port, val) outl_p(port, val) +#define i16_outw(port, val) outw(port, val) +#define i16_outw_p(port, val) outw_p(port, val) +#define i16_outb(port, val) outb(port, val) +#define i16_outb_p(port, val) outb_p(port, val) + +#endif __GNUC__ + +#endif /* _FLUX_X86_PIO_H_ */ diff --git a/apps/rmgr/include/flux/x86/pmode.h b/apps/rmgr/include/flux/x86/pmode.h new file mode 100644 index 0000000..591302a --- /dev/null +++ b/apps/rmgr/include/flux/x86/pmode.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1996-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + */ +#ifndef _FLUX_X86_PMODE_H_ +#define _FLUX_X86_PMODE_H_ + +#include +#include + + + +/* Enter protected mode on x86 machines. + Assumes: + * Running in real mode. + * Interrupts are turned off. + * A20 is enabled (if on a PC). + * A suitable GDT is already loaded. + + You must supply a 16-bit code segment + equivalent to the real-mode code segment currently in use. + + You must reload all segment registers except CS + immediately after invoking this macro. +*/ +FLUX_INLINE void i16_enter_pmode(int prot_cs) +{ + /* Switch to protected mode. */ + asm volatile(" + movl %0,%%cr0 + ljmp %1,$1f + 1: + " : : "r" (i16_get_cr0() | CR0_PE), "i" (prot_cs)); +} + + + +/* Leave protected mode and return to real mode. + Assumes: + * Running in protected mode + * Interrupts are turned off. + * Paging is turned off. + * All currently loaded segment registers + contain 16-bit segments with limits of 0xffff. + + You must supply a real-mode code segment + equivalent to the protected-mode code segment currently in use. + + You must reload all segment registers except CS + immediately after invoking this function. +*/ +FLUX_INLINE void i16_leave_pmode(int real_cs) +{ + /* Switch back to real mode. + Note: switching to the real-mode code segment + _must_ be done with an _immediate_ far jump, + not an indirect far jump. At least on my Am386DX/40, + an indirect far jump leaves the code segment read-only. */ + { + extern unsigned short real_jmp[]; + + real_jmp[3] = real_cs; + asm volatile(" + movl %0,%%cr0 + jmp 1f + 1: + real_jmp: + _real_jmp: + ljmp $0,$1f + 1: + " : : "r" (i16_get_cr0() & ~CR0_PE)); + } +} + + + +#endif _FLUX_X86_PMODE_H_ diff --git a/apps/rmgr/include/flux/x86/proc_reg.h b/apps/rmgr/include/flux/x86/proc_reg.h new file mode 100644 index 0000000..9a93f14 --- /dev/null +++ b/apps/rmgr/include/flux/x86/proc_reg.h @@ -0,0 +1,410 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Processor registers for i386 and i486. + */ +#ifndef _FLUX_X86_PROC_REG_H_ +#define _FLUX_X86_PROC_REG_H_ + +#include + +/* + * CR0 + */ +#define CR0_PG 0x80000000 /* enable paging */ +#define CR0_CD 0x40000000 /* i486: cache disable */ +#define CR0_NW 0x20000000 /* i486: no write-through */ +#define CR0_AM 0x00040000 /* i486: alignment check mask */ +#define CR0_WP 0x00010000 /* i486: write-protect kernel access */ +#define CR0_NE 0x00000020 /* i486: handle numeric exceptions */ +#define CR0_ET 0x00000010 /* extension type is 80387 */ + /* (not official) */ +#define CR0_TS 0x00000008 /* task switch */ +#define CR0_EM 0x00000004 /* emulate coprocessor */ +#define CR0_MP 0x00000002 /* monitor coprocessor */ +#define CR0_PE 0x00000001 /* enable protected mode */ + +/* + * CR4 + */ +#define CR4_VME 0x00000001 /* enable virtual intrs in v86 mode */ +#define CR4_PVI 0x00000002 /* enable virtual intrs in pmode */ +#define CR4_TSD 0x00000004 /* disable RDTSC in user mode */ +#define CR4_DE 0x00000008 /* debug extensions (I/O breakpoints) */ +#define CR4_PSE 0x00000010 /* page size extensions */ +#define CR4_PGE 0x00000020 /* page global extensions */ +#define CR4_MCE 0x00000040 /* machine check exception */ +#define CR4_PCE 0x00000100 /* enable read perf counter instr */ + +#ifndef ASSEMBLER +#ifdef __GNUC__ + +#include + + +/* Some processors, notably my Am386DX/40, + seem to have some rather subtle pipeline- or timing-related bugs + which case really weird things to happen with pushf's and popf's + that come too close together... */ + +FLUX_INLINE unsigned get_eflags() +{ + unsigned eflags; + asm volatile(" + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: pushf + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: popl %0" : "=r" (eflags)); + return eflags; +} + +FLUX_INLINE void set_eflags(unsigned eflags) +{ + asm volatile(" + pushl %0 + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: popf + jmp 1f + 1: jmp 1f + 1: jmp 1f + 1: " : : "r" (eflags)); +} + +FLUX_INLINE void cli() { asm volatile("cli"); } +FLUX_INLINE void sti() { asm volatile("sti"); } +FLUX_INLINE void cld() { asm volatile("cld"); } +#ifdef __cplusplus +/* in C++, std is a reserved keyword -- so use a function macro instead */ +#define std() asm volatile("std") +#else +FLUX_INLINE void std() { asm volatile("std"); } +#endif +FLUX_INLINE void clts() { asm volatile("clts"); } + +FLUX_INLINE unsigned short get_cs() +{ + unsigned short cs; + asm volatile("movw %%cs,%w0" : "=r" (cs)); + return cs; +} + +FLUX_INLINE unsigned short get_ds() +{ + unsigned short ds; + asm volatile("movw %%ds,%w0" : "=r" (ds)); + return ds; +} +FLUX_INLINE void set_ds(unsigned short ds) +{ + asm volatile("movw %w0,%%ds" : : "r" (ds)); +} + +FLUX_INLINE unsigned short get_es() +{ + unsigned short es; + asm volatile("movw %%es,%w0" : "=r" (es)); + return es; +} +FLUX_INLINE void set_es(unsigned short es) +{ + asm volatile("movw %w0,%%es" : : "r" (es)); +} + +FLUX_INLINE unsigned short get_fs() +{ + unsigned short fs; + asm volatile("movw %%fs,%w0" : "=r" (fs)); + return fs; +} +FLUX_INLINE void set_fs(unsigned short fs) +{ + asm volatile("movw %w0,%%fs" : : "r" (fs)); +} + +FLUX_INLINE unsigned short get_gs() +{ + unsigned short gs; + asm volatile("movw %%gs,%w0" : "=r" (gs)); + return gs; +} +FLUX_INLINE void set_gs(unsigned short gs) +{ + asm volatile("movw %w0,%%gs" : : "r" (gs)); +} + +FLUX_INLINE unsigned short get_ss() +{ + unsigned short ss; + asm volatile("movw %%ss,%w0" : "=r" (ss)); + return ss; +} +FLUX_INLINE void set_ss(unsigned short ss) +{ + asm volatile("movw %w0,%%ss" : : "r" (ss)); +} + +#define get_eax() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%eax, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ebx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ebx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ecx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ecx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_edx() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%edx, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_esi() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%esi, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_edi() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%edi, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_ebp() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%ebp, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_esp() \ + ({ \ + register unsigned int _temp__; \ + asm("movl %%esp, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_eflags() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("pushf; popl %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_cr0() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("mov %%cr0, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define set_cr0(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr0" : : "r" (_temp__)); \ + }) + +#ifdef HAVE_CR4 +#define get_cr4() \ + ({ \ + register unsigned int _temp__; \ + asm volatile("mov %%cr4, %0" : "=r" (_temp__)); \ + _temp__; \ + }) +#define set_cr4(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr4" : : "r" (_temp__)); \ + }) +#else /* not HAVE_CR4 */ +#define get_cr4() \ + ({ \ + register unsigned int _temp__; \ + asm volatile(".byte 0x0f,0x20,0xe0" : "=a" (_temp__)); \ + _temp__; \ + }) +#define set_cr4(value) \ + asm volatile(".byte 0x0f,0x22,0xe0" : : "a" (value)); +#endif /* HAVE_CR4 */ + +#define get_msw() \ + ({ \ + unsigned short _msw__; \ + asm volatile("smsw %0" : "=r" (_msw__)); \ + msw; \ + }) + +#define get_cr2() \ + ({ \ + register unsigned int _temp__; \ + asm("mov %%cr2, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define get_cr3() \ + ({ \ + register unsigned int _temp__; \ + asm("mov %%cr3, %0" : "=r" (_temp__)); \ + _temp__; \ + }) + +#define set_cr3(value) \ + ({ \ + register unsigned int _temp__ = (value); \ + asm volatile("mov %0, %%cr3" : : "r" (_temp__)); \ + }) + +#define set_ts() \ + set_cr0(get_cr0() | CR0_TS) + +#define clear_ts() \ + asm volatile("clts") + +#define get_tr() \ + ({ \ + unsigned short _seg__; \ + asm volatile("str %0" : "=rm" (_seg__) ); \ + _seg__; \ + }) + +#define set_tr(seg) \ + asm volatile("ltr %0" : : "rm" ((unsigned short)(seg)) ) + +#define set_gdt(pseudo_desc) \ + ({ \ + asm volatile("lgdt %0" : : "m" ((pseudo_desc)->limit)); \ + }) + +#define set_idt(pseudo_desc) \ + ({ \ + asm volatile("lidt %0" : : "m" ((pseudo_desc)->limit)); \ + }) + +#define get_ldt() \ + ({ \ + unsigned short _seg__; \ + asm volatile("sldt %0" : "=rm" (_seg__) ); \ + _seg__; \ + }) + +#define set_ldt(seg) \ + asm volatile("lldt %0" : : "rm" ((unsigned short)(seg)) ) + +/* + * Read the 64-bit timestamp counter (TSC) register. + * Works only on Pentium and higher processors, + * and in user mode only if the TSD bit in CR4 is not set. + */ +#if HAVE_RDTSC +#define get_tsc() \ + ({ \ + unsigned long low, high; \ + asm volatile("rdtsc" : "=d" (high), "=a" (low)); \ + ((unsigned long long)high << 32) | low; \ + }) +#else +#define get_tsc() \ + ({ \ + unsigned long low, high; \ + asm volatile( \ + ".byte 0x0f; .byte 0x31" \ + : "=d" (high), "=a" (low)); \ + ((unsigned long long)high << 32) | low; \ + }) +#endif + +/* + * This doesn't set a processor register, + * but it's often used immediately after setting one, + * to flush the instruction queue. + */ +#define flush_instr_queue() \ + asm volatile(" + jmp 0f + 0: + ") + +/* Inline functions work fine for 16-bit code as well. */ +#ifdef CODE16 +#define i16_get_eflags get_eflags +#define i16_set_eflags set_eflags +#define i16_cli cli +#define i16_sti sti +#define i16_cld cld +#define i16_std std +#define i16_clts clts +#define i16_get_cs get_cs +#define i16_set_cs set_cs +#define i16_get_ds get_ds +#define i16_set_ds set_ds +#define i16_get_es get_es +#define i16_set_es set_es +#define i16_get_fs get_fs +#define i16_set_fs set_fs +#define i16_get_gs get_gs +#define i16_set_gs set_gs +#define i16_get_ss get_ss +#define i16_set_ss set_ss +#define i16_get_cr0 get_cr0 +#define i16_set_cr0 set_cr0 +#define i16_get_cr3 get_cr3 +#define i16_set_cr3 set_cr3 +#define i16_get_msw get_msw +#define i16_set_gdt set_gdt +#define i16_set_idt set_idt +#define i16_set_ldt set_ldt +#define i16_set_tr set_tr +#define i16_flush_instr_queue flush_instr_queue +#endif + +#endif /* __GNUC__ */ +#endif /* ASSEMBLER */ + +#endif /* _FLUX_X86_PROC_REG_H_ */ diff --git a/apps/rmgr/include/flux/x86/seg.h b/apps/rmgr/include/flux/x86/seg.h new file mode 100644 index 0000000..6c73c20 --- /dev/null +++ b/apps/rmgr/include/flux/x86/seg.h @@ -0,0 +1,199 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * Copyright (c) 1991 IBM Corporation + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation, + * and that the name IBM not be used in advertising or publicity + * pertaining to distribution of the software without specific, written + * prior permission. + * + * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_SEG_H_ +#define _FLUX_X86_SEG_H_ + + +/* + * x86 segmentation. + */ + +#ifndef ASSEMBLER + +/* + * Real segment descriptor. + */ +struct x86_desc { + unsigned int limit_low:16, /* limit 0..15 */ + base_low:16, /* base 0..15 */ + base_med:8, /* base 16..23 */ + access:8, /* access byte */ + limit_high:4, /* limit 16..19 */ + granularity:4, /* granularity */ + base_high:8; /* base 24..31 */ +}; + +/* + * Trap, interrupt, or call gate. + */ +struct x86_gate { + unsigned int offset_low:16, /* offset 0..15 */ + selector:16, + word_count:8, + access:8, + offset_high:16; /* offset 16..31 */ +}; + +#endif !ASSEMBLER + +#define SZ_32 0x4 /* 32-bit segment */ +#define SZ_16 0x0 /* 16-bit segment */ +#define SZ_G 0x8 /* 4K limit field */ + +#define ACC_A 0x01 /* accessed */ +#define ACC_TYPE 0x1e /* type field: */ + +#define ACC_TYPE_SYSTEM 0x00 /* system descriptors: */ + +#define ACC_LDT 0x02 /* LDT */ +#define ACC_CALL_GATE_16 0x04 /* 16-bit call gate */ +#define ACC_TASK_GATE 0x05 /* task gate */ +#define ACC_TSS 0x09 /* task segment */ +#define ACC_CALL_GATE 0x0c /* call gate */ +#define ACC_INTR_GATE 0x0e /* interrupt gate */ +#define ACC_TRAP_GATE 0x0f /* trap gate */ + +#define ACC_TSS_BUSY 0x02 /* task busy */ + +#define ACC_TYPE_USER 0x10 /* user descriptors */ + +#define ACC_DATA 0x10 /* data */ +#define ACC_DATA_W 0x12 /* data, writable */ +#define ACC_DATA_E 0x14 /* data, expand-down */ +#define ACC_DATA_EW 0x16 /* data, expand-down, + writable */ +#define ACC_CODE 0x18 /* code */ +#define ACC_CODE_R 0x1a /* code, readable */ +#define ACC_CODE_C 0x1c /* code, conforming */ +#define ACC_CODE_CR 0x1e /* code, conforming, + readable */ +#define ACC_PL 0x60 /* access rights: */ +#define ACC_PL_K 0x00 /* kernel access only */ +#define ACC_PL_U 0x60 /* user access */ +#define ACC_P 0x80 /* segment present */ + +/* + * Components of a selector + */ +#define SEL_LDT 0x04 /* local selector */ +#define SEL_PL 0x03 /* privilege level: */ +#define SEL_PL_K 0x00 /* kernel selector */ +#define SEL_PL_U 0x03 /* user selector */ + +/* + * Convert selector to descriptor table index. + */ +#define sel_idx(sel) ((sel)>>3) + + +#ifndef ASSEMBLER + +#include + +/* Return the privilege level of a segment selector */ +#define ISPL(s) ((s) & SEL_PL) + +#define USERMODE(s, f) (ISPL(s) == SEL_PL_U || ((f) & EFL_VM) != 0) +#define KERNELMODE(s, f) (ISPL(s) == SEL_PL_K && ((f) & EFL_VM) == 0) + + +/* Format of a "pseudo-descriptor", used for loading the IDT and GDT. */ +struct pseudo_descriptor +{ + short pad; + unsigned short limit; + unsigned long linear_base; +}; + + +/* Fill a segment descriptor. */ +FLUX_INLINE void +fill_descriptor(struct x86_desc *desc, unsigned base, unsigned limit, + unsigned char access, unsigned char sizebits) +{ + if (limit > 0xfffff) + { + limit >>= 12; + sizebits |= SZ_G; + } + desc->limit_low = limit & 0xffff; + desc->base_low = base & 0xffff; + desc->base_med = (base >> 16) & 0xff; + desc->access = access | ACC_P; + desc->limit_high = limit >> 16; + desc->granularity = sizebits; + desc->base_high = base >> 24; +} + +/* Set the base address in a segment descriptor. */ +FLUX_INLINE void +fill_descriptor_base(struct x86_desc *desc, unsigned base) +{ + desc->base_low = base & 0xffff; + desc->base_med = (base >> 16) & 0xff; + desc->base_high = base >> 24; +} + +/* Set the limit in a segment descriptor. */ +FLUX_INLINE void +fill_descriptor_limit(struct x86_desc *desc, unsigned limit) +{ + if (limit > 0xfffff) + { + limit >>= 12; + desc->granularity |= SZ_G; + } + else + desc->granularity &= ~SZ_G; + desc->limit_low = limit & 0xffff; + desc->limit_high = limit >> 16; +} + +/* Fill a gate with particular values. */ +FLUX_INLINE void +fill_gate(struct x86_gate *gate, unsigned offset, unsigned short selector, + unsigned char access, unsigned char word_count) +{ + gate->offset_low = offset & 0xffff; + gate->selector = selector; + gate->word_count = word_count; + gate->access = access | ACC_P; + gate->offset_high = (offset >> 16) & 0xffff; +} + +#ifdef CODE16 +#define i16_fill_descriptor fill_descriptor +#define i16_fill_gate fill_gate +#endif + +#endif !ASSEMBLER + +#endif /* _FLUX_X86_SEG_H_ */ diff --git a/apps/rmgr/include/flux/x86/smp/asm-smp.h b/apps/rmgr/include/flux/x86/smp/asm-smp.h new file mode 100644 index 0000000..13e59eb --- /dev/null +++ b/apps/rmgr/include/flux/x86/smp/asm-smp.h @@ -0,0 +1,269 @@ +#ifndef _FLUX_X86_SMP_ASM_SMP_H_ +#define _FLUX_X86_SMP_ASM_SMP_H_ + +#ifdef __SMP__ +#ifndef ASSEMBLY + +#include +#include +#if 0 +#include +#include +#include +#endif + +/* + * Support definitions for SMP machines following the intel multiprocessing + * specification + */ + +/* + * This tag identifies where the SMP configuration + * information is. + */ + +#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') + +struct intel_mp_floating +{ + char mpf_signature[4]; /* "_MP_" */ + unsigned long mpf_physptr; /* Configuration table address */ + unsigned char mpf_length; /* Our length (paragraphs) */ + unsigned char mpf_specification;/* Specification version */ + unsigned char mpf_checksum; /* Checksum (makes sum 0) */ + unsigned char mpf_feature1; /* Standard or configuration ? */ + unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ + unsigned char mpf_feature3; /* Unused (0) */ + unsigned char mpf_feature4; /* Unused (0) */ + unsigned char mpf_feature5; /* Unused (0) */ +}; + +struct mp_config_table +{ + char mpc_signature[4]; +#define MPC_SIGNATURE "PCMP" + unsigned short mpc_length; /* Size of table */ + char mpc_spec; /* 0x01 */ + char mpc_checksum; + char mpc_oem[8]; + char mpc_productid[12]; + unsigned long mpc_oemptr; /* 0 if not present */ + unsigned short mpc_oemsize; /* 0 if not present */ + unsigned short mpc_oemcount; + unsigned long mpc_lapic; /* APIC address */ + unsigned long reserved; +}; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 + +struct mpc_config_processor +{ + unsigned char mpc_type; + unsigned char mpc_apicid; /* Local APIC number */ + unsigned char mpc_apicver; /* Its versions */ + unsigned char mpc_cpuflag; +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the BP */ + unsigned long mpc_cpufeature; +#define CPU_STEPPING_MASK 0x0F +#define CPU_MODEL_MASK 0xF0 +#define CPU_FAMILY_MASK 0xF00 + unsigned long mpc_featureflag; /* CPUID feature value */ + unsigned long mpc_reserved[2]; +}; + +struct mpc_config_bus +{ + unsigned char mpc_type; + unsigned char mpc_busid; + unsigned char mpc_bustype[6] __attribute((packed)); +}; + +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" + +/* We don't understand the others */ + +struct mpc_config_ioapic +{ + unsigned char mpc_type; + unsigned char mpc_apicid; + unsigned char mpc_apicver; + unsigned char mpc_flags; +#define MPC_APIC_USABLE 0x01 + unsigned long mpc_apicaddr; +}; + +struct mpc_config_intsrc +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbus; + unsigned char mpc_srcbusirq; + unsigned char mpc_dstapic; + unsigned char mpc_dstirq; +}; + +#define MP_INT_VECTORED 0 +#define MP_INT_NMI 1 +#define MP_INT_SMI 2 +#define MP_INT_EXTINT 3 + +#define MP_IRQDIR_DEFAULT 0 +#define MP_IRQDIR_HIGH 1 +#define MP_IRQDIR_LOW 3 + + +struct mpc_config_intlocal +{ + unsigned char mpc_type; + unsigned char mpc_irqtype; + unsigned short mpc_irqflag; + unsigned char mpc_srcbusid; + unsigned char mpc_srcbusirq; + unsigned char mpc_destapic; +#define MP_APIC_ALL 0xFF + unsigned char mpc_destapiclint; +}; + + +/* + * Default configurations + * + * 1 2 CPU ISA 82489DX + * 2 2 CPU EISA 82489DX no IRQ 8 or timer chaining + * 3 2 CPU EISA 82489DX + * 4 2 CPU MCA 82489DX + * 5 2 CPU ISA+PCI + * 6 2 CPU EISA+PCI + * 7 2 CPU MCA+PCI + */ + +/* + * Per process x86 parameters + */ + +struct cpuinfo_x86 +{ + char hard_math; + char x86; + char x86_model; + char x86_mask; + char x86_vendor_id[16]; + int x86_capability; + int fdiv_bug; + int have_cpuid; + char wp_works_ok; + char hlt_works_ok; + unsigned long udelay_val; +}; + + +extern struct cpuinfo_x86 cpu_data[NR_CPUS]; + +__FLUX_BEGIN_DECLS +/* + * Private routines/data + */ + +extern int smp_found_config; +extern int smp_scan_config(unsigned long, unsigned long); +extern unsigned long smp_alloc_memory(unsigned long mem_base); + +#if 0 +extern unsigned char *apic_reg; +#endif 0 + +extern unsigned char *kernel_stacks[NR_CPUS]; +extern unsigned char boot_cpu_id; +extern unsigned long cpu_present_map; +extern volatile int cpu_number_map[NR_CPUS]; +extern volatile int cpu_logical_map[NR_CPUS]; +extern volatile unsigned long smp_invalidate_needed; +extern void smp_flush_tlb(void); +extern volatile unsigned long kernel_flag, kernel_counter; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; +extern volatile unsigned char active_kernel_processor; +#if 0 +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); +extern unsigned long ipi_count; +extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern volatile unsigned long kernel_counter; +extern volatile unsigned long syscall_count; +#endif 0 + +/* + * General functions that each host system must provide. + */ + +extern void smp_callin(void); +extern int smp_boot_cpus(void); +extern void smp_store_cpu_info(int id); /* Store per cpu info (like the initial udelay numbers */ +__FLUX_END_DECLS + +extern volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ +extern volatile unsigned long smp_process_available; + +/* + * APIC handlers: Note according to the Intel specification update + * you should put reads between APIC writes. + * Intel Pentium processor specification update [11AP, pg 64] + * "Back to Back Assertions of HOLD May Cause Lost APIC Write Cycle" + */ + +extern __inline void apic_write(unsigned long reg, unsigned long v) +{ + *((volatile unsigned long *)(apic_reg+reg))=v; +} + +extern __inline unsigned long apic_read(unsigned long reg) +{ + return *((volatile unsigned long *)(apic_reg+reg)); +} + +/* + * This function is needed by all SMP systems. It must _always_ be valid from the initial + * startup. This may require magic on some systems (in the i86 case we dig out the boot + * cpu id from the config and set up a fake apic_reg pointer so that before we activate + * the apic we get the right answer). Hopefully other processors are more sensible 8) + */ + +extern __inline int smp_processor_id(void) +{ + return GET_APIC_ID(apic_read(APIC_ID)); +} + +#endif /* !ASSEMBLY */ + +#define NO_PROC_ID 0xFF /* No processor magic marker */ + +/* + * This magic constant controls our willingness to transfer + * a process across CPUs. Such a transfer incurs misses on the L1 + * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My + * gut feeling is this will vary by board in value. For a board + * with separate L2 cache it probably depends also on the RSS, and + * for a board with shared L2 cache it ought to decay fast as other + * processes are run. + */ + +#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ + +#define SMP_FROM_INT 1 +#define SMP_FROM_SYSCALL 2 + +#endif +#endif diff --git a/apps/rmgr/include/flux/x86/smp/bitops.h b/apps/rmgr/include/flux/x86/smp/bitops.h new file mode 100644 index 0000000..b71ea9d --- /dev/null +++ b/apps/rmgr/include/flux/x86/smp/bitops.h @@ -0,0 +1,137 @@ +#ifndef _FLUX_X86_SMP_BITOPS_H_ +#define _FLUX_X86_SMP_BITOPS_H_ + +/* + * Copyright 1992, Linus Torvalds. + */ + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef __SMP__ +#define LOCK_PREFIX "lock ; " +#define SMPVOL volatile +#else +#define LOCK_PREFIX "" +#define SMPVOL +#endif + +/* + * Some hacks to defeat gcc over-optimizations.. + */ +struct __dummy { unsigned long a[100]; }; +#define ADDR (*(struct __dummy *) addr) +#define CONST_ADDR (*(const struct __dummy *) addr) + +extern __inline__ int set_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +extern __inline__ int clear_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +extern __inline__ int change_bit(int nr, SMPVOL void * addr) +{ + int oldbit; + + __asm__ __volatile__(LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"ir" (nr)); + return oldbit; +} + +/* + * This routine doesn't need to be atomic. + */ +extern __inline__ int test_bit(int nr, const SMPVOL void * addr) +{ + return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; +} + +/* + * Find-bit routines.. + */ +extern __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int res; + + if (!size) + return 0; + __asm__("cld\n\t" + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res) + :"c" ((size + 31) >> 5), "D" (addr), "b" (addr) + :"ax", "cx", "di"); + return res; +} + +extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +extern __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#endif /* _I386_BITOPS_H */ diff --git a/apps/rmgr/include/flux/x86/smp/i82489.h b/apps/rmgr/include/flux/x86/smp/i82489.h new file mode 100644 index 0000000..4a286c2 --- /dev/null +++ b/apps/rmgr/include/flux/x86/smp/i82489.h @@ -0,0 +1,88 @@ +#ifndef _FLUX_X86_SMP_I82489_H_ +#define _FLUX_X86_SMP_I82489_H_ + +/* + * Offsets for programming the 82489 and Pentium integrated APIC + * + * Alan Cox , 1995. + */ + +#define APIC_ID 0x20 +#define GET_APIC_ID(x) (((x)>>24)&0x0F) +#define APIC_VERSION 0x30 +#define APIC_TASKPRI 0x80 +#define APIC_TPRI_MASK 0xFF +#define APIC_ARBPRI 0x90 +#define APIC_PROCPRI 0xA0 +#define APIC_EOI 0xB0 +#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ +#define APIC_RRR 0xC0 +#define APIC_LDR 0xD0 +#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define APIC_DFR 0xE0 +#define GET_APIC_DFR(x) (((x)>>28)&0x0F) +#define SET_APIC_DFR(x) ((x)<<28) +#define APIC_SPIV 0xF0 +#define APIC_ISR 0x100 +#define APIC_TMR 0x180 +#define APIC_IRR 0x200 +#define APIC_ESR 0x280 +#define APIC_ESR_SEND_CS 0x00001 +#define APIC_ESR_RECV_CS 0x00002 +#define APIC_ESR_SEND_ACC 0x00004 +#define APIC_ESR_RECV_ACC 0x00008 +#define APIC_ESR_SENDILL 0x00020 +#define APIC_ESR_RECVILL 0x00040 +#define APIC_ESR_ILLREGA 0x00080 +#define APIC_ICR 0x300 +#define APIC_DEST_FIELD 0x00000 +#define APIC_DEST_SELF 0x40000 +#define APIC_DEST_ALLINC 0x80000 +#define APIC_DEST_ALLBUT 0xC0000 +#define APIC_DEST_RR_MASK 0x30000 +#define APIC_DEST_RR_INVALID 0x00000 +#define APIC_DEST_RR_INPROG 0x10000 +#define APIC_DEST_RR_VALID 0x20000 +#define APIC_DEST_LEVELTRIG 0x08000 +#define APIC_DEST_ASSERT 0x04000 +#define APIC_DEST_BUSY 0x01000 +#define APIC_DEST_LOGICAL 0x00800 +#define APIC_DEST_DM_FIXED 0x00000 +#define APIC_DEST_DM_LOWEST 0x00100 +#define APIC_DEST_DM_SMI 0x00200 +#define APIC_DEST_DM_REMRD 0x00300 +#define APIC_DEST_DM_NMI 0x00400 +#define APIC_DEST_DM_INIT 0x00500 +#define APIC_DEST_DM_STARTUP 0x00600 +#define APIC_DEST_VECTOR_MASK 0x000FF +#define APIC_ICR2 0x310 +#define GET_APIC_DEST_FIELD(x) (((x)>>24)&0xFF) +#define SET_APIC_DEST_FIELD(x) ((x)<<24) +#define APIC_LVTT 0x320 +#define APIC_LVT0 0x350 +#define APIC_LVT_TIMER_PERIODIC (1<<17) +#define APIC_LVT_MASKED (1<<16) +#define APIC_LVT_LEVEL_TRIGGER (1<<15) +#define APIC_LVT_REMOTE_IRR (1<<14) +#define APIC_INPUT_POLARITY (1<<13) +#define APIC_SEND_PENDING (1<<12) +#define GET_APIC_DELIVERY_MODE(x) (((x)>>8)&0x7) +#define SET_APIC_DELIVERY_MODE(x,y) (((x)&~0x700)|((y)<<8)) +#define APIC_MODE_FIXED 0x0 +#define APIC_MODE_NMI 0x4 +#define APIC_MODE_EXINT 0x7 +#define APIC_LVT1 0x360 +#define APIC_LVERR 0x370 +#define APIC_TMICT 0x380 +#define APIC_TMCCT 0x390 +#define APIC_TDCR 0x3E0 +#define APIC_TDR_DIV_1 0xB +#define APIC_TDR_DIV_2 0x0 +#define APIC_TDR_DIV_4 0x1 +#define APIC_TDR_DIV_8 0x2 +#define APIC_TDR_DIV_16 0x3 +#define APIC_TDR_DIV_32 0x8 +#define APIC_TDR_DIV_64 0x9 +#define APIC_TDR_DIV_128 0xA + +#endif diff --git a/apps/rmgr/include/flux/x86/smp/linux-smp.h b/apps/rmgr/include/flux/x86/smp/linux-smp.h new file mode 100644 index 0000000..dec0b2f --- /dev/null +++ b/apps/rmgr/include/flux/x86/smp/linux-smp.h @@ -0,0 +1,58 @@ +#ifndef _FLUX_X86_SMP_LINUX_SMP_H_ +#define _FLUX_X86_SMP_LINUX_SMP_H_ + +/* + * Generic SMP support + * Alan Cox. + */ + +#ifdef __SMP__ +#include +#include + +__FLUX_BEGIN_DECLS +extern void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern int smp_boot_cpus(void); /* Boot processor call to load the other CPU's */ +extern void smp_callin(void); /* Processor call in. Must hold processors until .. */ +extern void smp_commence(void); /* Multiprocessors may now schedule */ +__FLUX_END_DECLS + +extern int smp_num_cpus; +extern int smp_threads_ready; /* True once the per process idle is forked */ +#ifdef __SMP_PROF__ +extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */ +extern volatile unsigned long smp_spins_sys_idle[]; /* count of idle spins */ +extern volatile unsigned long smp_spins_syscall[]; /* count of syscall spins */ +extern volatile unsigned long smp_spins_syscall_cur[]; /* count of syscall spins for the current + call */ +extern volatile unsigned long smp_idle_count[1+NR_CPUS];/* count idle ticks */ +extern volatile unsigned long smp_idle_map; /* map with idle cpus */ +#else +extern volatile unsigned long smp_spins; +#endif + + +extern volatile unsigned long smp_msg_data; +extern volatile int smp_src_cpu; +extern volatile int smp_msg_id; + +#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ +#define MSG_ALL 0x8001 + +#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */ +#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's when rebooting */ +#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU */ + +#else + +/* + * These macros fold the SMP functionality into a single CPU system + */ + +#define smp_num_cpus 1 +#define smp_processor_id() 0 +#define smp_message_pass(t,m,d,w) +#define smp_threads_ready 1 +#define kernel_lock() +#endif +#endif diff --git a/apps/rmgr/include/flux/x86/smp/smp.h b/apps/rmgr/include/flux/x86/smp/smp.h new file mode 100644 index 0000000..630968b --- /dev/null +++ b/apps/rmgr/include/flux/x86/smp/smp.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + */ + +#ifndef _FLUX_X86_SMP_SMP_H_ +#define _FLUX_X86_SMP_SMP_H_ + +#define __SMP__ +#define NR_CPUS 32 +extern unsigned long apic_addr; +#define apic_reg ((unsigned char *)(apic_addr)) + +#endif diff --git a/apps/rmgr/include/flux/x86/spin_lock.h b/apps/rmgr/include/flux/x86/spin_lock.h new file mode 100644 index 0000000..16cbd37 --- /dev/null +++ b/apps/rmgr/include/flux/x86/spin_lock.h @@ -0,0 +1,57 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_SPIN_LOCK_H_ +#define _FLUX_X86_SPIN_LOCK_H_ + +typedef volatile int spin_lock_t; + +#define SPIN_LOCK_INITIALIZER 0 + +#define spin_lock_init(s) (*(s) = 0) +#define spin_lock_locked(s) (*(s) != 0) + +#ifdef __GNUC__ + +#define spin_unlock(p) \ + ({ register int _u__ ; \ + __asm__ volatile("xorl %0, %0; \n\ + xchgl %0, %1" \ + : "=&r" (_u__), "=m" (*(p)) ); \ + 0; }) + +#define spin_try_lock(p)\ + (!({ register int _r__; \ + __asm__ volatile("movl $1, %0; \n\ + xchgl %0, %1" \ + : "=&r" (_r__), "=m" (*(p)) ); \ + _r__; })) + +#define spin_lock(p) \ + ({ while (!spin_try_lock(p)) while (*(p)); }) + +#endif /* __GNUC__ */ + +#endif /* _FLUX_X86_SPIN_LOCK_H_ */ diff --git a/apps/rmgr/include/flux/x86/trap.h b/apps/rmgr/include/flux/x86/trap.h new file mode 100644 index 0000000..bc98c8a --- /dev/null +++ b/apps/rmgr/include/flux/x86/trap.h @@ -0,0 +1,61 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _FLUX_X86_TRAP_H_ +#define _FLUX_X86_TRAP_H_ + +/* + * Hardware trap vectors for i386. + */ +#define T_DIVIDE_ERROR 0 +#define T_DEBUG 1 +#define T_NMI 2 /* non-maskable interrupt */ +#define T_INT3 3 /* int 3 instruction */ +#define T_OVERFLOW 4 /* overflow test */ +#define T_OUT_OF_BOUNDS 5 /* bounds check */ +#define T_INVALID_OPCODE 6 /* invalid op code */ +#define T_NO_FPU 7 /* no floating point */ +#define T_DOUBLE_FAULT 8 /* double fault */ +#define T_FPU_FAULT 9 +#define T_INVALID_TSS 10 +#define T_SEGMENT_NOT_PRESENT 11 +#define T_STACK_FAULT 12 +#define T_GENERAL_PROTECTION 13 +#define T_PAGE_FAULT 14 +/* 15 */ +#define T_FLOATING_POINT_ERROR 16 +#define T_ALIGNMENT_CHECK 17 +#define T_MACHINE_CHECK 18 + +/* + * Page-fault trap codes. + */ +#define T_PF_PROT 0x1 /* protection violation */ +#define T_PF_WRITE 0x2 /* write access */ +#define T_PF_USER 0x4 /* from user state */ + + +#endif _FLUX_X86_TRAP_H_ diff --git a/apps/rmgr/include/flux/x86/tss.h b/apps/rmgr/include/flux/x86/tss.h new file mode 100644 index 0000000..fa7bae7 --- /dev/null +++ b/apps/rmgr/include/flux/x86/tss.h @@ -0,0 +1,66 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#ifndef _FLUX_X86_TSS_H_ +#define _FLUX_X86_TSS_H_ + +/* + * Intel x86 32-bit Task State Segment + */ +struct x86_tss { + int back_link; /* segment number of previous task, + if nested */ + int esp0; /* initial stack pointer ... */ + int ss0; /* and segment for ring 0 */ + int esp1; /* initial stack pointer ... */ + int ss1; /* and segment for ring 1 */ + int esp2; /* initial stack pointer ... */ + int ss2; /* and segment for ring 2 */ + int cr3; /* CR3 - page table directory + physical address */ + int eip; + int eflags; + int eax; + int ecx; + int edx; + int ebx; + int esp; /* current stack pointer */ + int ebp; + int esi; + int edi; + int es; + int cs; + int ss; /* current stack segment */ + int ds; + int fs; + int gs; + int ldt; /* local descriptor table segment */ + unsigned short trace_trap; /* trap on switch to this task */ + unsigned short io_bit_map_offset; + /* offset to start of IO permission + bit map */ +}; + +#endif /* _FLUX_X86_TSS_H_ */ diff --git a/apps/rmgr/include/flux/x86/types.h b/apps/rmgr/include/flux/x86/types.h new file mode 100644 index 0000000..878e55d --- /dev/null +++ b/apps/rmgr/include/flux/x86/types.h @@ -0,0 +1,103 @@ +/* + * Mach Operating System + * Copyright (c) 1992,1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1996,1995 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Header file containing basic types for the x86 architecture. + */ +#ifndef _FLUX_X86_TYPES_H_ +#define _FLUX_X86_TYPES_H_ + +/* + * A natural_t is the type for the native + * integer type, e.g. 32 or 64 or.. whatever + * register size the machine has. Unsigned, it is + * used for entities that might be either + * unsigned integers or pointers, and for + * type-casting between the two. + * For instance, the IPC system represents + * a port in user space as an integer and + * in kernel space as a pointer. + */ +typedef unsigned int natural_t; + +/* + * An integer_t is the signed counterpart + * of the natural_t type. Both types are + * only supposed to be used to define + * other types in a machine-independent + * way. + */ +typedef int integer_t; + +/* + * A vm_offset_t is a type-neutral pointer, + * e.g. an offset into a virtual memory space. + */ +typedef natural_t vm_offset_t; + +/* + * A vm_size_t is the proper type for e.g. + * expressing the difference between two + * vm_offset_t entities. + */ +typedef natural_t vm_size_t; + +/* + * On any anchitecture, + * these types are _exactly_ as wide as indicated in their names. + */ +typedef signed char signed8_t; +typedef signed short signed16_t; +typedef signed long signed32_t; +typedef signed long long signed64_t; +typedef unsigned char unsigned8_t; +typedef unsigned short unsigned16_t; +typedef unsigned long unsigned32_t; +typedef unsigned long long unsigned64_t; +typedef float float32_t; +typedef double float64_t; + +/* + * On any given architecture, + * these types are guaranteed to be _at_least_ + * as wide as indicated in their names, + * but may be wider if a wider type can be more efficiently accessed. + * + * On the x86, bytes and 32-bit words are fast, + * but 16-bit words are slow; + * this property is reflected in these type definitions. + */ +typedef unsigned char boolean_t; +typedef signed char signed_min8_t; +typedef unsigned char unsigned_min8_t; +typedef signed int signed_min16_t; +typedef unsigned int unsigned_min16_t; +typedef signed int signed_min32_t; +typedef unsigned int unsigned_min32_t; + +#endif /* _FLUX_X86_TYPES_H_ */ diff --git a/apps/rmgr/include/l4/compiler.h b/apps/rmgr/include/l4/compiler.h new file mode 100644 index 0000000..03a5a8f --- /dev/null +++ b/apps/rmgr/include/l4/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include "linkage.h" + +#endif diff --git a/apps/rmgr/include/l4/l4.h b/apps/rmgr/include/l4/l4.h new file mode 100644 index 0000000..8f58783 --- /dev/null +++ b/apps/rmgr/include/l4/l4.h @@ -0,0 +1,12 @@ +#ifndef __L4_L4_H__ +#define __L4_L4_H__ + +#include +#include +#include +#include +#include +#include + +#endif __L4_L4_H__ + diff --git a/apps/rmgr/include/l4/linkage.h b/apps/rmgr/include/l4/linkage.h new file mode 100644 index 0000000..190202f --- /dev/null +++ b/apps/rmgr/include/l4/linkage.h @@ -0,0 +1,54 @@ +#ifndef _LINUX_LINKAGE_H +#define _LINUX_LINKAGE_H + +#ifdef __cplusplus +#define CPP_ASMLINKAGE extern "C" +#else +#define CPP_ASMLINKAGE +#endif + +#if defined __i386__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 7) +#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) +#else +#define asmlinkage CPP_ASMLINKAGE +#endif + +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X/**/: +#endif + +#ifdef __arm__ +#define __ALIGN .align 0 +#define __ALIGN_STR ".align 0" +#else +#ifdef __mc68000__ +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" +#else +#if !defined(__i486__) && !defined(__i586__) +#define __ALIGN .align 4,0x90 +#define __ALIGN_STR ".align 4,0x90" +#else /* __i486__/__i586__ */ +#define __ALIGN .align 16,0x90 +#define __ALIGN_STR ".align 16,0x90" +#endif /* __i486__/__i586__ */ +#endif /* __mc68000__ */ +#endif /* __arm__ */ + +#ifdef __ASSEMBLY__ + +#define ALIGN __ALIGN +#define ALIGN_STR __ALIGN_STR + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name); \ + ALIGN; \ + SYMBOL_NAME_LABEL(name) + +#endif + +#endif diff --git a/apps/rmgr/include/l4/rmgr/librmgr.h b/apps/rmgr/include/l4/rmgr/librmgr.h new file mode 100644 index 0000000..cc9bf9a --- /dev/null +++ b/apps/rmgr/include/l4/rmgr/librmgr.h @@ -0,0 +1,40 @@ +#ifndef __L4_I386_RMGR_H +#define __L4_I386_RMGR_H + +#include + +extern int have_rmgr; +extern l4_threadid_t rmgr_id; + +#ifdef __cplusplus +extern "C" { +#endif + +int rmgr_init(void); + +int rmgr_set_small_space(l4_threadid_t dest, int num); +int rmgr_set_prio(l4_threadid_t dest, int num); +int rmgr_get_prio(l4_threadid_t dest, int *num); + +int rmgr_get_task(int num); +int rmgr_delete_task(int num); +int rmgr_get_irq(int num); + +int rmgr_get_task_id(char *module_name, l4_threadid_t *thread_id); + +l4_taskid_t rmgr_task_new(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + +l4_taskid_t rmgr_task_new_with_prio(l4_taskid_t dest, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, + l4_threadid_t pager, + l4_sched_param_t sched_param); + +int rmgr_free_fpage(l4_fpage_t fp); +int rmgr_free_page(dword_t address); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apps/rmgr/include/l4/rmgr/rmgr.h b/apps/rmgr/include/l4/rmgr/rmgr.h new file mode 100644 index 0000000..6773dc0 --- /dev/null +++ b/apps/rmgr/include/l4/rmgr/rmgr.h @@ -0,0 +1,61 @@ +#ifndef __L4_SERVER_RMGR_H__ +#define __L4_SERVER_RMGR_H__ + +#include + +#define RMGR_LTHREAD_PAGER (0) +#define RMGR_LTHREAD_SUPER (1) + +#define RMGR_RMGR (0) /* PROTOCOL: rmgr meta protocol */ +#define RMGR_RMGR_PING (0xf3) /* ping -- returns ~arg in d2 */ + +#define RMGR_RMGR_MSG(action, arg) L4_PROTO_MSG(RMGR_RMGR, (action), (arg)) + +#define RMGR_MEM (1) /* PROTOCOL: memory operations */ +#define RMGR_MEM_FREE (1) /* free physical page */ +#define RMGR_MEM_FREE_FP (2) /* free an fpage */ +#define RMGR_MEM_INFO (3) /* dump info about memory regions */ +#define RMGR_MEM_RESERVE (4) /* reserve chunk of free pages */ +#define RMGR_MEM_GET_PAGE0 (5) /* explicit deliver physical page 0 */ + +#define RMGR_MEM_MSG(action) L4_PROTO_MSG(RMGR_MEM, (action), 0) + +#define RMGR_TASK (2) /* PROTOCOL: task operations */ +#define RMGR_TASK_ALLOC (1) /* allocate task number */ +#define RMGR_TASK_GET (2) /* allocate specific task number */ +#define RMGR_TASK_FREE (3) /* free task number */ +#define RMGR_TASK_CREATE (4) /* create a task XXX */ +#define RMGR_TASK_DELETE (5) /* delete a task */ +#define RMGR_TASK_SET_SMALL (6) /* set a task's small address space number */ +#define RMGR_TASK_SET_PRIO (7) /* set a task's priority */ +#define RMGR_TASK_GET_ID (8) /* get task id by module name */ + +#define RMGR_TASK_CREATE_WITH_PRIO (9) /* create a task and set priority XXX */ +#define RMGR_TASK_SET_ID (10) /* get task id by module name */ + +#define RMGR_TASK_MSG(action, taskno) \ + L4_PROTO_MSG(RMGR_TASK, (action), (taskno)) + +#define RMGR_IRQ (3) +#define RMGR_IRQ_GET (2) /* allocate an interrupt number */ +#define RMGR_IRQ_FREE (3) /* free an interrupt number */ + +#define RMGR_IRQ_MSG(action, intno) \ + L4_PROTO_MSG(RMGR_IRQ, (action), (intno)) + +#define RMGR_SYNC (4) +#define RMGR_WAIT_EVENT (1) +#define RMGR_SIGNAL_EVENT (2) +#define RMGR_ENTER_CRITICAL_SECTION (3) +#define RMGR_LEAVE_CRITICAL_SECTION (4) + +#define RMGR_SYNC_MSG(action, ident) \ + L4_PROTO_MSG(RMGR_SYNC, (action), (ident)) + +#define RMGR_MEM_RES_FLAGS_MASK 0x0FC0 +#define RMGR_MEM_RES_DMA_ABLE 0x0040 /* memory has to lay below 16 MB */ +#define RMGR_MEM_RES_UPWARDS 0x0080 /* search upwards */ +#define RMGR_MEM_RES_DOWNWARDS 0x0000 /* search downwards (default) */ + +#endif + diff --git a/apps/rmgr/include/l4/rmgr/server_proto.h b/apps/rmgr/include/l4/rmgr/server_proto.h new file mode 100644 index 0000000..78f9745 --- /dev/null +++ b/apps/rmgr/include/l4/rmgr/server_proto.h @@ -0,0 +1,20 @@ +#ifndef __L4_SERVER_PROTO_H__ +#define __L4_SERVER_PROTO_H__ + +#include + +typedef struct { + word_t param; + byte_t action; + byte_t proto; +} l4_proto_struct_t; + +typedef union { + l4_proto_struct_t proto; + dword_t request; +} l4_proto_t; + +#define L4_PROTO_MSG(proto, action, param) \ + (((proto) << 24) | ((action) << 16) | (param)) + +#endif diff --git a/apps/rmgr/include/l4/sys b/apps/rmgr/include/l4/sys new file mode 120000 index 0000000..2414330 --- /dev/null +++ b/apps/rmgr/include/l4/sys @@ -0,0 +1 @@ +x86-x0-32 \ No newline at end of file diff --git a/apps/rmgr/include/l4/x86-x0-32/compiler.h b/apps/rmgr/include/l4/x86-x0-32/compiler.h new file mode 100644 index 0000000..03a5a8f --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include "linkage.h" + +#endif diff --git a/apps/rmgr/include/l4/x86-x0-32/idt.h b/apps/rmgr/include/l4/x86-x0-32/idt.h new file mode 100644 index 0000000..c53a629 --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2000/02/21 19:13:23 uhlig Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/apps/rmgr/include/l4/x86-x0-32/ipc.h b/apps/rmgr/include/l4/x86-x0-32/ipc.h new file mode 100644 index 0000000..8a5e56c --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/ipc.h @@ -0,0 +1,386 @@ +/* + * $Id: ipc.h,v 1.5 2000/04/29 12:38:10 ud3 Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +#include "../../../../include/config.h" + +#if !defined(CONFIG_L4_SYSENTEREXIT) +#define IPC_SYSENTER "int $0x30 \n\t" +#else +#define IPC_SYSENTER \ +"push %%ecx \n\t" \ +"push %%ebp \n\t" \ +"push $0x23 /* linear_space_exec */ \n\t" \ +"push $0f /* offset ret_addr */ \n\t" \ +"mov %%esp,%%ecx \n\t" \ +"sysenter /* = db 0x0F,0x34 */ \n\t" \ +"mov %%ebp,%%edx \n\t" \ +"0: \n\t" +#endif + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + + +/* + * prototypes + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 +#ifdef __pic__ + +#error no version X bindings with __pic__ enabled + +#else /* __pic__ */ + +// ok +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dummy; + asm volatile( + "pushl %%esi \n\t" + "pushl %%edi \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%edi \n\t" + "popl %%esi \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (dummy) + : + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 5, rcv msg -> ebp */ + "S" (dest), /* ESI, 6, dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) + : "memory" + ); + return L4_IPC_ERROR(*result); +} + +// ok +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ecx \n\t" + "pushl %%edi \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%edi \n\t" + "popl %%ecx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=S" (*src) /* ESI, 4 */ + : + "c" (timeout), /* ECX, 5 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 6 -> ebp rcv_msg */ + "S" (dest.dw), /* ESI ,4 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) + :"memory" + ); + return L4_IPC_ERROR(*result); +} + + +// ok + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + int dummy; + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl $-1 ,%%ebp \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + , "=d"(dummy), "=c"(dummy), "=b"(dummy), "=S"(dummy) + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "S" (dest.dw), /* ESI, 4 */ + "a" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "edi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +// ok +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dummy; + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=S" (src->dw), /* ESI,4 */ + "=c" (dummy) + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "edi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +// ok + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + dword_t dummy; + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + IPC_SYSENTER + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=c" (dummy), + "=S" (dummy), + "=D" (dummy) + : + "c" (timeout), /* ECX, 4 */ + "S" (src.dw), /* ESI, 6 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ + : "memory" + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + + +#endif /* __L4_IPC__ */ diff --git a/apps/rmgr/include/l4/x86-x0-32/kdebug.h b/apps/rmgr/include/l4/x86-x0-32/kdebug.h new file mode 100644 index 0000000..616987f --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/kdebug.h @@ -0,0 +1,114 @@ +/* + * $Id: kdebug.h,v 1.1 2000/02/21 19:13:23 uhlig Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/apps/rmgr/include/l4/x86-x0-32/kernel.h b/apps/rmgr/include/l4/x86-x0-32/kernel.h new file mode 100644 index 0000000..c1349aa --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/kernel.h @@ -0,0 +1,75 @@ +/* + * $Id: kernel.h,v 1.1 2000/02/21 19:13:23 uhlig Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; + + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug; + dword_t default_kdebug_exception; + dword_t default_kdebug_begin; + dword_t default_kdebug_end; + + dword_t sigma0_esp; + dword_t sigma0_eip; + struct { + dword_t low; + dword_t high; + } sigma0_memory; + + dword_t sigma1_esp, sigma1_eip; + + struct { + dword_t low; + dword_t high; + } sigma1_memory; + + dword_t root_esp, root_eip; + + struct { + dword_t low; + dword_t high; + } root_memory; + + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; + + struct { + dword_t low; + dword_t high; + } main_memory; + + struct { + dword_t low; + dword_t high; + } reserved0; + + struct { + dword_t low; + dword_t high; + } reserved1; + + struct { + dword_t low; + dword_t high; + } dedicated[5]; + volatile dword_t clock; +} l4_kernel_info_t __attribute__((packed)); + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/apps/rmgr/include/l4/x86-x0-32/linkage.h b/apps/rmgr/include/l4/x86-x0-32/linkage.h new file mode 100644 index 0000000..190202f --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/linkage.h @@ -0,0 +1,54 @@ +#ifndef _LINUX_LINKAGE_H +#define _LINUX_LINKAGE_H + +#ifdef __cplusplus +#define CPP_ASMLINKAGE extern "C" +#else +#define CPP_ASMLINKAGE +#endif + +#if defined __i386__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 7) +#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) +#else +#define asmlinkage CPP_ASMLINKAGE +#endif + +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X/**/: +#endif + +#ifdef __arm__ +#define __ALIGN .align 0 +#define __ALIGN_STR ".align 0" +#else +#ifdef __mc68000__ +#define __ALIGN .align 4 +#define __ALIGN_STR ".align 4" +#else +#if !defined(__i486__) && !defined(__i586__) +#define __ALIGN .align 4,0x90 +#define __ALIGN_STR ".align 4,0x90" +#else /* __i486__/__i586__ */ +#define __ALIGN .align 16,0x90 +#define __ALIGN_STR ".align 16,0x90" +#endif /* __i486__/__i586__ */ +#endif /* __mc68000__ */ +#endif /* __arm__ */ + +#ifdef __ASSEMBLY__ + +#define ALIGN __ALIGN +#define ALIGN_STR __ALIGN_STR + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name); \ + ALIGN; \ + SYMBOL_NAME_LABEL(name) + +#endif + +#endif diff --git a/apps/rmgr/include/l4/x86-x0-32/syscalls.h b/apps/rmgr/include/l4/x86-x0-32/syscalls.h new file mode 100644 index 0000000..c4a6318 --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/syscalls.h @@ -0,0 +1,385 @@ +/* + * $Id: syscalls.h,v 1.4 2001/12/11 15:27:42 uhlig Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + dword_t dummy; + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a"(dummy), + "=b"(dummy), + "=c"(dummy), + "=d"(dummy), + "=S"(dummy), + "=D"(dummy) + : + "a" (fpage), + "c" (map_mask) + : "memory" + ); +}; + +/* + * L4 id myself + */ +// ok +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.dw) /* ESI, 0 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + +// ok +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->dw), /* ESI, 0 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.dw) /* ESI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +// ok +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x35 \n\t" /* execute system call */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->dw), /* ESI, 3 */ + "=b" (preempter->dw) /* EBX, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager->dw), /* ESI */ +#ifdef __pic__ + "D" (preempter->dw) /* EDI */ +#else + "b" (preempter->dw) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "edi" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + int dummy; + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : "=S"(dummy) + /* No output */ + : + "S" (destination.dw) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi" + ); +} + +/* + * L4 thread schedule + */ +// ok +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "movl %%ebx, %%edi \n\t" + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((dword_t*)&temp)[0]), /* ECX, 1 */ + "=d" (((dword_t*)&temp)[1]), /* EDX, 2 */ + "=S" (partner->dw), /* ESI, 3 */ +#ifdef __pic__ + "=D" (ext_preempter->dw) /* EDI, 4 */ +#else + "=b" (ext_preempter->dw) +#endif + : +#ifdef __pic__ + "2" (ext_preempter->dw), /* EDX, 2 */ +#else + "b" (ext_preempter->dw), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.dw) /* ESI */ +#ifndef __pic__ + : "edi" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +// ok +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + dword_t dummy; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.dw), /* ESI, 0 */ + "=c" (dummy), + "=a" (dummy), + "=d" (dummy), + "=b" (dummy) + : + "b" (pager.dw), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.dw) /* ESI */ + : "memory" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.dw), /* ESI, 0 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination.dw), /* ESI */ + "D" (pager.dw) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + diff --git a/apps/rmgr/include/l4/x86-x0-32/types.h b/apps/rmgr/include/l4/x86-x0-32/types.h new file mode 100644 index 0000000..f4556b4 --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/types.h @@ -0,0 +1,221 @@ + /* + * $Id: types.h,v 1.2 2000/04/18 21:35:53 ud3 Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#if defined(__L4_STANDARD__) +# error L4 version clash +#endif + + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef union { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:6; + unsigned task:8; + unsigned chief:8; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + dword_t dw; + dword_t raw; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} l4_intrid_struct_t; + +typedef union { + dword_t dw; + l4_intrid_struct_t id; +} l4_intrid_t; + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_NIL_ID ((l4_threadid_t){dw:0}) +#define L4_INVALID_ID ((l4_threadid_t){dw:0xffffffff}) + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} + +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.raw == 0; +} + +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.raw == 0xffffffff; +} + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + return (t1.raw == t2.raw); +} + +#define TASK_MASK 0xffff03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + return (t1.raw & TASK_MASK) == (t2.raw & TASK_MASK); +} + +#endif /* __L4TYPES_H__ */ diff --git a/apps/rmgr/include/l4/x86-x0-32/x86-x0-32 b/apps/rmgr/include/l4/x86-x0-32/x86-x0-32 new file mode 120000 index 0000000..2414330 --- /dev/null +++ b/apps/rmgr/include/l4/x86-x0-32/x86-x0-32 @@ -0,0 +1 @@ +x86-x0-32 \ No newline at end of file diff --git a/apps/rmgr/lib/libexec.a b/apps/rmgr/lib/libexec.a new file mode 100644 index 0000000..c584030 Binary files /dev/null and b/apps/rmgr/lib/libexec.a differ diff --git a/apps/rmgr/lib/libkern.a b/apps/rmgr/lib/libkern.a new file mode 100644 index 0000000..9954f5b Binary files /dev/null and b/apps/rmgr/lib/libkern.a differ diff --git a/apps/rmgr/lib/liblmm.a b/apps/rmgr/lib/liblmm.a new file mode 100644 index 0000000..3bb8b85 Binary files /dev/null and b/apps/rmgr/lib/liblmm.a differ diff --git a/apps/rmgr/lib/libmc.a b/apps/rmgr/lib/libmc.a new file mode 100644 index 0000000..0457cb9 Binary files /dev/null and b/apps/rmgr/lib/libmc.a differ diff --git a/apps/rmgr/src/#crt0.S# b/apps/rmgr/src/#crt0.S# new file mode 100644 index 0000000..c49d607 --- /dev/null +++ b/apps/rmgr/src/#crt0.S# @@ -0,0 +1,140 @@ +#define __ASSEMBLY__ +#include + + .section .init + +ENTRY(__crt_dummy__) +ENTRY(_start) +ENTRY(start) + leal SYMBOL_NAME(_stack),%esp + pushl %eax + pushl %ebx + + /* initialize vector for exception 6 */ + movl $trap6_entry,%eax + movw %ax, _idt_offset_low + shrl $16, %eax + movw %ax, _idt_offset_high + movw %cs, %ax + movw %ax, _idt_selector + + /* load tiny interrupt descriptor table to catch exception 6 */ + lidtl SYMBOL_NAME(_idtdesc) + + pushl $SYMBOL_NAME(_exit) + jmp SYMBOL_NAME(startup) + +ENTRY(__main) + ret + + /* Show an error message and wait for keypress to reboot. */ +trap6_entry: + pusha + + cld + + /* print out warning */ + movl $trap6_warning, %esi + movl $(0xb8000 + (24*80*2)), %edi + movb $0x0F, %ah + +tp60: /* read next character from string */ + lodsb + + /* check for end-of-string */ + cmpb $0, %al + je tp62 + + /* check for newline */ + cmpb $'\n', %al + jne tp61 + + pushl %eax + pushl %esi + + /* move screen upwards 1 line */ + movl $((24*80*2)/4), %ecx + movl $(0xb8000 + 1*80*2), %esi + movl $0xb8000, %edi + rep movsl + + /* clear last line of screen */ + movl $((1*80*2)/4), %ecx + movl $0x07200720, %eax + rep stosl + + popl %esi + popl %eax + + /* jump to new line */ + movl $(0xb8000 + (24*80*2)), %edi + jmp tp60 + +tp61: /* print character */ + stosw + jmp tp60 + +tp62: /* wait for keypress */ + inb $0x64, %al + testb $0x01, %al + je tp62 + + movb %al, %ah + + /* empty keyboard buffer */ + inb $0x60, %al + + /* ignore PS/2 mouse events */ + testb $0x20, %ah + jne tp62 + + jmp SYMBOL_NAME(my_pc_reset) + + + /* the warning text */ +trap6_warning: + .string "\nRMGR: Invalid opcode detected! Be sure that you don't use any CPU\n optimization flags like -march=i686 when compiling RMGR and\n the depending libraries from OSKit 0.6.\n\n Press any key to reboot..." + + /* MultiBoot header - see multiboot.h. */ +#ifdef __ELF__ + .align 4 +#else /* ! __ELF__, that mean a.out assembler */ + .align 2 +#endif + +ENTRY(_mb_header) + .long 0x1BADB002 /* magic */ + .long 0x00010000 /* flags: AOUT_KLUDGE */ + .long - 0x00010000 - 0x1BADB002 + .long SYMBOL_NAME(_mb_header) /* header_addr */ + .long SYMBOL_NAME(__crt_dummy__) /* load_addr */ + .long _edata /* load_end_addr */ + .long _end /* bss_end_addr */ + .long SYMBOL_NAME(_start) /* entry */ + + .word 0 +_idtdesc: + .word (7*8)-1 + .long _idt + +_idt: + .word 0,0,0,0 /* trap 0 */ + .word 0,0,0,0 /* trap 1 */ + .word 0,0,0,0 /* trap 2 */ + .word 0,0,0,0 /* trap 3 */ + .word 0,0,0,0 /* trap 4 */ + .word 0,0,0,0 /* trap 5 */ + +_idt_offset_low: + .word 0 +_idt_selector: + .word 0 + .byte 0 + .byte 0xee +_idt_offset_high: + .word 0 + + .bss + + .space 8192 +ENTRY(_stack) diff --git a/apps/rmgr/src/.cvsignore b/apps/rmgr/src/.cvsignore new file mode 100644 index 0000000..a1b9e40 --- /dev/null +++ b/apps/rmgr/src/.cvsignore @@ -0,0 +1,3 @@ +*.i *.s +cfg-parse.c cfg-scan.c +rmgr rmgr.stripped diff --git a/apps/rmgr/src/Makefile b/apps/rmgr/src/Makefile new file mode 100644 index 0000000..f6bb1c7 --- /dev/null +++ b/apps/rmgr/src/Makefile @@ -0,0 +1,61 @@ +# $Id: Makefile,v 1.5 2001/12/04 18:49:28 ud3 Exp $ +# +# Makefile for rmgr + +include ../../Makeconf + +OSKIT_LIB = ../lib +SIZE = size + +#SRCS = crt0-$(ARCH).S sigma0.c +SRCS = crt0.S startup.c rmgr.c oskit_support.c exec.c globals.c init.c memmap.c \ + trampoline.c irq.c cfg-parse.c cfg-mem.c pe.c +LIBS = -L$(OSKIT_LIB) -lkern -lexec -lmc -llmm +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES = ../include ../include/flux/c +LDFLAGS += -L../lib +DEFINES += USE_L4_TYPES +CFLAGS += -D__VERSION_X__ + +TARGET = rmgr + +LINK_ADDR=$(RMGR_LINK_ADDR) + +all: $(TARGET) + +$(TARGET): $(OBJS) Makefile + $(LD) $(LDFLAGS) -e_start -T rmgr.ld -o $@ $(OBJS) $(LIBS) + @cp -f $@ $@.stripped + $(STRIP) $@.stripped + @chmod a+r $@ $@.stripped + @echo ""; echo "Done with $@."; echo "" + +trampoline.o: trampoline.c + $(COMP_MESSAGE) + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< +# assert we don't need data + @data_size="`$(SIZE) --format=sysv $@ | grep ^.data | awk '{print $$2}'`"; \ + bss_size="`$(SIZE) --format=sysv $@ | grep ^.bss | awk '{print $$2}'`"; \ + if [ $$bss_size -gt 0 -o $$data_size -gt 0 ]; then \ + echo "ERROR: $@: data or bss size > 0"; \ + rm -f $@; \ + exit 1; \ + else \ + true; \ + fi + +.cfg-parse.d cfg-parse.o: cfg-scan.c + +cfg-parse.y: cfg-scan.c + +..PRECIOUS: cfg-parse.c + +# didn't think we need this rule, but somehow make want's +# to delete the c-file first, even if it's not there +%.c: %.l + flex -t $< > $@ + +clean:: + rm -f $(TARGET) $(TARGET).stripped cfg-scan.c cfg-parse.c + diff --git a/apps/rmgr/src/NOTES b/apps/rmgr/src/NOTES new file mode 100644 index 0000000..77d6829 --- /dev/null +++ b/apps/rmgr/src/NOTES @@ -0,0 +1,44 @@ +Debug Directives + +The following directives only affect the resource-manager thread +(lthread 1), not the pager thread (lthread 0) of the Rmgr server task. + +verbose + + Log all request and response messages for *failed* requests + (that is, for request to which RMGR responds with first_dword == -1). + +debug + + As "verbose", but additionally enter the L4 kernel debugger every + time a request fails. + +debug_log MASK TYPES + + MASK is a bit vector containing a bit for each Rmgr protocol (bit + 0 -> RMGR_RMGR, bit 1 -> RMGR_MEM, bit 2 -> RMGR_TASK, 3 -> + RMGR_IRQ; see . + + "debug_log" never does anything for a protocol whose bit has not + been set in MASK. If bit 1 of TYPES has also been set, action is + further constrained to the request number specified in bits 31..16 + of TYPES. + + Apart from further constraining action to particular requests, + TYPES also defines the kind of action to be taken. In particular, + the bits of TYPES have the following meanings: + + TYPES bit meaning + + 31..16 Specifies a request number action should be limited + to; for example, 1 means RMGR_TASK_ALLOC. See + . + This value is only meaningful when bit 1 is also set. + + 2 enter the kernel debugger. + + 1 Limit action to the request number specified by bits + 31..16. If not set, logging is enabled for all + request numbers. + + 0 Log request and response message. diff --git a/apps/rmgr/src/cfg-mem.c b/apps/rmgr/src/cfg-mem.c new file mode 100644 index 0000000..f14d4c0 --- /dev/null +++ b/apps/rmgr/src/cfg-mem.c @@ -0,0 +1,23 @@ +#include +#include +#include "cfg.h" + +/* this file implements a static malloc pool for the flex-generated + config file scanner */ + +#define POOL_SIZE 0x10000 +static char pool[POOL_SIZE]; + +static lmm_region_t region; + +void __cfg_setup_mem(void) +{ + lmm_init(&malloc_lmm); + lmm_add_region(&malloc_lmm, ®ion, (void*)0, (vm_size_t)-1, 0, 0); + lmm_add_free(&malloc_lmm, pool, POOL_SIZE); +} + +void __cfg_destroy_mem(void) +{ + lmm_init(&malloc_lmm); /* reset the malloc_lmm */ +} diff --git a/apps/rmgr/src/cfg-parse.y b/apps/rmgr/src/cfg-parse.y new file mode 100644 index 0000000..e9a8094 --- /dev/null +++ b/apps/rmgr/src/cfg-parse.y @@ -0,0 +1,332 @@ +/* -*- indented-text -*- */ + +%{ +#include + +#include + +#include "quota.h" +#include "init.h" +#include "rmgr.h" +#include "cfg.h" + +#define yyparse __cfg_parse + +int yylex(void); +static void yyerror(const char *s); + +unsigned __cfg_task; +static unsigned ctask; + +static int assert_mod = -1; + +static unsigned c_max = -1, c_low = 0, c_high = -1, c_mask = 0xffffffff; + +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef max +#define max(x,y) ((x)>(y)?(x):(y)) +#endif + +#define minset(x, y) ((x) = min((x),(y))) +#define maxset(x, y) ((x) = max((x),(y))) + +#define SET_DEBUG_OPT(proto, action) \ + do { \ + debug_log_mask |= (1L << proto); \ + if (action) \ + debug_log_types = (2L | (action << 16) | \ + (debug_log_types & 7)); \ + } while(0); +%} + +%union { + char *string; + unsigned number; + struct { + unsigned low, high; + } interval; +} + +%token TASK MODNAME CHILD IRQ MAX IN MASK MEMORY HIMEM LOGMCP BOOTMCP BOOTPRIO +%token BOOTWAIT RMGR SIGMA0 DEBUGFLAG VERBOSE LOG +%token SMALLSIZE SMALL BOOTSMALL MODULE +%token TASK_PROTO TASK_ALLOC TASK_GET TASK_FREE +%token TASK_CREATE TASK_DELETE TASK_SMALL +%token TASK_GET_ID TASK_CREATE_WITH_PRIO +%token MEM_PROTO MEM_FREE MEM_FREE_FP +%token IRQ_PROTO IRQ_GET IRQ_FREE +%token RMGR_PROTO RMGR_PING +%token LOG_IT KDEBUG +%token UNSIGNED STRING +%type number +%type setspec +%type string + +/* grammer rules follow */ +%% + +file : rules + ; + +rules : rule rules + | + ; + +rule : taskspec constraints modules + { + if (ctask) + { + quota_t *q = & quota[ctask]; + bootquota_t *b = &bootquota[ctask]; + printf( + "RMGR: configured task 0x%x: [ m:%x,%x,%x hm:%x,%x,%x\n" + " t:%x,%x,%x i:%x lmcp:%x s:%x,%x,%x\n" + " mcp:%x prio:%x small:%x ]\n", + ctask, q->mem.low, q->mem.high, q->mem.max, + q->himem.low, q->himem.high, q->himem.max, + q->task.low, q->task.high, q->task.max, + q->irq.max, q->log_mcp, + q->small.low, q->small.high, q->small.max, + b->mcp, b->prio, b->small_space); + } + assert_mod = -1; + } + + | smallsizerule + | flag + ; + +smallsizerule : SMALLSIZE number{ small_space_size = $2; }; + +numerical_options: number number{ debug_log_mask = $1; + debug_log_types = $2; }; + +verbose_option: TASK_PROTO { SET_DEBUG_OPT(RMGR_TASK, 0); } + | TASK_ALLOC { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_ALLOC); } + | TASK_GET { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_GET); } + | TASK_FREE { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_FREE); } + | TASK_CREATE { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_CREATE); } + | TASK_DELETE { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_DELETE); } + | TASK_SMALL { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_SET_SMALL); } + | TASK_GET_ID { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_GET_ID); } + | TASK_CREATE_WITH_PRIO { SET_DEBUG_OPT(RMGR_TASK, RMGR_TASK_CREATE_WITH_PRIO); } + | MEM_PROTO { SET_DEBUG_OPT(RMGR_MEM, 0); } + | MEM_FREE { SET_DEBUG_OPT(RMGR_MEM, RMGR_MEM_FREE); } + | MEM_FREE_FP { SET_DEBUG_OPT(RMGR_MEM, RMGR_MEM_FREE_FP); } + | IRQ_PROTO { SET_DEBUG_OPT(RMGR_IRQ, 0); } + | IRQ_GET { SET_DEBUG_OPT(RMGR_IRQ, RMGR_IRQ_GET); } + | IRQ_FREE { SET_DEBUG_OPT(RMGR_IRQ, RMGR_IRQ_FREE); } + | RMGR_PROTO { SET_DEBUG_OPT(RMGR_IRQ, 0); } + | RMGR_PING { SET_DEBUG_OPT(RMGR_IRQ, RMGR_RMGR_PING); } + | LOG_IT { debug_log_types |= 1; } + | KDEBUG { debug_log_types |= 4; } + ; + +verbose_options: verbose_option verbose_options + | verbose_option + ; + +log_options: numerical_options + | verbose_options + ; + +flag : BOOTWAIT { boot_wait++; } + | VERBOSE { verbose++; } + | DEBUGFLAG { debug++; } + | LOG log_options + ; + +modules : module modules + | + ; + +module : nextmod asserts { bootquota[ctask].mods++; } + ; + +nextmod : MODULE { assert_mod++; } + ; + +taskspec : TASK { ctask = ++__cfg_task; } + | TASK taskname + | TASK RMGR { ctask = __cfg_task = myself.id.task;} + | TASK SIGMA0 { ctask = __cfg_task = my_pager.id.task; } + | TASK number { ctask = __cfg_task = $2; } + ; + +taskname: MODNAME string + { + char *n; + int i; + for (i = first_task_module; i < mb_info.mods_count; i++) + { + if (!(n = (char *) mb_mod[i].string)) + { + ctask = ++__cfg_task; + printf("RMGR: WARNING: cmdlines unsupported, can't "\ + "find modname %s; assuming task %d\n", $2,\ + ctask); + goto taskname_end; + } + if (strstr(n, $2)) + { + ctask = __cfg_task + = myself.id.task + 1 + (i - first_task_module); + assert_mod = i; + goto taskname_end; + } + } + if (first_not_bmod_free_modnr >= MODS_MAX) + { + printf("RMGR: Could not configure more "\ + "than %d tasks\n", MODS_MAX); + boot_error(); + ctask = 0; + goto taskname_end; + } + + ctask = __cfg_task = first_not_bmod_free_task++; + check(task_alloc(ctask, myself.id.task)); + printf("RMGR: WARNING: couldn't find modname %s, "\ + "only storing it's quota\n", $2); + strncpy(mb_mod_names[first_not_bmod_free_modnr], $2,\ + MOD_NAME_MAX); + mb_mod_names[first_not_bmod_free_modnr][MOD_NAME_MAX-1] = 0; + first_not_bmod_free_modnr++; + + taskname_end: + free($2); + }; + +asserts : assert asserts + | + ; + +assert : MODNAME string + { + char *n; + if (assert_mod < 1) + { + printf("RMGR: ERROR: no boot module "\ + "associated with modname %s\n", $2); + boot_error(); + goto assert_end; + } + if (!(n = (char *)mb_mod[assert_mod].string)) + { + printf("RMGR: WARNING: cmdlines "\ + "unsupported, can't verify modname %s\n", $2); + } + else if (! strstr(n, $2)) + { + printf("RMGR: ERROR: modname %s doesn't "\ + "match cmdline %s\n", $2, n); + boot_error(); + } + assert_end: + free($2); + } + ; + +constraints : constraint constraints + | + ; + +constraint : CHILD childconstraints { maxset(quota[ctask].task.low, c_low); + minset(quota[ctask].task.high, c_high); + minset(quota[ctask].task.max, c_max); + c_low = 0; c_high = -1; c_max = -1; } + | MEMORY memoryconstraints { maxset(quota[ctask].mem.low, c_low); + minset(quota[ctask].mem.high, c_high); + minset(quota[ctask].mem.max, c_max); + c_low = 0; c_high = -1; c_max = -1; } + | HIMEM memoryconstraints { maxset(quota[ctask].himem.low, c_low); + minset(quota[ctask].himem.high, c_high); + minset(quota[ctask].himem.max, c_max); + c_low = 0; c_high = -1; c_max = -1; } + | IRQ irqconstraints { unsigned mask = 0, i; + for (i = max(0, c_low); + i <= min(15, c_max); + i++) + { + mask |= 1L << i; + } + quota[ctask].irq.max &= + c_mask & mask; + c_low = 0; c_high = -1; c_max = -1; + c_mask = 0xffffffff; } + | SMALL smallconstraints { maxset(quota[ctask].small.low, c_low); + minset(quota[ctask].small.high, c_high); + minset(quota[ctask].small.max, c_max); + c_low = 0; c_high = -1; c_max = -1; } + | LOGMCP number { quota[ctask].log_mcp = $2; } + | BOOTMCP number { bootquota[ctask].mcp = $2; } + | BOOTPRIO number { bootquota[ctask].prio = $2; } + | BOOTSMALL number { bootquota[ctask].small_space = $2; } + ; + +childconstraints : numconstraints + ; + +smallconstraints : numconstraints + ; + +memoryconstraints : numconstraints + ; + +irqconstraints : numconstraints + | maskconstraints + ; + +numconstraints : numconstraint numconstraints + | numconstraint + ; + +numconstraint : MAX number { c_max = min(c_max, $2); } + | IN setspec { c_low = max(c_low, $2.low); + c_high = min(c_high, $2.high); } + ; + +setspec : '[' number ',' number ']' { $$.low = $2; $$.high = $4; } + ; + +maskconstraints : maskconstraint + ; + +maskconstraint : MASK number { c_mask &= $2; } + ; + +number : UNSIGNED { $$ = strtoul($1, 0, 0); } + ; + +string : STRING { $$ = strdup($1 + 1); + $$[strlen($$) - 1] = 0; }; + +%% +/* end of grammer -- misc C source code follows */ + +#include "cfg-scan.c" + +static void yyerror(const char *s) +{ + printf("RMGR: ERROR: while parsing config file: %s\n", + s); +// " at line %d, col %d\n", s, line, col); +} + + +#ifdef TEST + +char cfg[] = "task modname 'foo'\n" + "#a comment\n" + "child in [10,30] max 100\n"; + +int main(void) +{ + cfg_setup_input(cfg, cfg + sizeof(cfg)); + + return cfg_parse(); +} + +#endif /* TEST */ diff --git a/apps/rmgr/src/cfg-scan.l b/apps/rmgr/src/cfg-scan.l new file mode 100644 index 0000000..8728e2f --- /dev/null +++ b/apps/rmgr/src/cfg-scan.l @@ -0,0 +1,128 @@ +/* -*- indented-text -*- */ + +%{ +#include + +#include "cfg.h" + +int yylex(void); +static int yywrap(void); + +/* we use a memory-based input buffer */ + +static int my_yyinput(char *buf, int max_size); + +#undef YY_INPUT +#define YY_INPUT(b, r, ms) (r = my_yyinput(b, ms)) + +#define YY_NEVER_INTERACTIVE 1 + +static unsigned line = 1, col = 1; + +/* make sure we don't use file I/O */ + +#undef ECHO +#define ECHO + +#undef fprintf +#define fprintf(stream, args...) printf(args) + +%} + +%start COMMENT + +/* shortcut definitions */ + +DIGIT [0-9] +HEXDIGIT [a-fA-F0-9] +SPACE [\f\r\t\032 ] +NEWLINE \n + +/* lexing rules follow */ +/* ^#.*$ ; */ +%% + +# BEGIN COMMENT; +.*$ BEGIN 0; +rmgr { col += 4; return RMGR; } +sigma0 { col += 6; return SIGMA0; } +task { col += 4; return TASK; } +module { col += 6; return MODULE; } +end { col += 3; return 0; } /* end token */ +modname { col += 7; return MODNAME; } +child { col += 5; return CHILD; } +irq { col += 3; return IRQ; } +max { col += 3; return MAX; } +in { col += 2; return IN; } +mask { col += 4; return MASK; } +memory { col += 6; return MEMORY; } +high_memory { col += 11; return HIMEM; } +log_mcp { col += 7; return LOGMCP; } +boot_mcp { col += 8; return BOOTMCP; } +boot_priority { col += 13; return BOOTPRIO; } +small { col += 5; return SMALL; } +boot_small { col += 10; return BOOTSMALL; } +bootwait { col += 8; return BOOTWAIT; } +small_space_size { col += 16; return SMALLSIZE; } +debug { col += 5; return DEBUGFLAG; } +debug_log { col += 9; return LOG; } +verbose { col += 7; return VERBOSE; } +task_proto { col += 10; return TASK_PROTO; } +task_alloc { col += 10; return TASK_ALLOC; } +task_get { col += 8; return TASK_GET; } +task_free { col += 9; return TASK_FREE; } +task_create { col += 11; return TASK_CREATE; } +task_delete { col += 11; return TASK_DELETE; } +task_create_with_prio { col += 21 ; return TASK_CREATE_WITH_PRIO; } +mem_proto { col += 9 ; return MEM_PROTO; } +mem_free { col += 8 ; return MEM_FREE; } +mem_free_fp { col += 11 ; return MEM_FREE_FP; } +irq_proto { col += 9 ; return IRQ_PROTO; } +irq_get { col += 7; return IRQ_GET; } +irq_free { col += 8; return IRQ_FREE; } +rmgr_proto { col += 10; return RMGR_PROTO; } +rmgr_rmgr_ping { col += 14; return RMGR_RMGR_PING; } +log { col += 3; return LOG_IT; } +kdebug { col += 6; return KDEBUG; } +(0[xX]{HEXDIGIT}+|{DIGIT}+) { col += strlen(yytext); + yylval.string = yytext; return UNSIGNED; } +('[^']*'|\"[^\"]*\") { col += strlen(yytext); + yylval.string = yytext; return STRING; } +{SPACE} { col++; } +{NEWLINE} { line++; col = 1; } +. { col++; return yytext[0]; } + +%% +/* end of lexing rules -- general C stuff follows */ + +/* from John R. Levine, Tony Mason, Doug Brown; Lex&Yacc; UNIX + Programming Tools; O'Reilly&Associates, Inc; Second Edition; + October 1992; ISBN 1-56592-000-7., "Input from Strings" pp. 156: */ + +static const char *myinput, *myinputptr, *myinputlim; + +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + +static int my_yyinput(char *buf, int max_size) +{ + int n = min(max_size, myinputlim - myinputptr); + + if (n > 0) { + memcpy(buf, myinputptr, n); + myinputptr += n; + } + return n; +} + +void cfg_setup_input(const char *cfg_buffer, const char *cfg_buffer_end) +{ + myinput = myinputptr = cfg_buffer; + myinputlim = cfg_buffer_end; +} + +static int yywrap(void) /* called when lexing is finished */ +{ + return 1; +} diff --git a/apps/rmgr/src/cfg.h b/apps/rmgr/src/cfg.h new file mode 100644 index 0000000..3c51df1 --- /dev/null +++ b/apps/rmgr/src/cfg.h @@ -0,0 +1,35 @@ +#ifndef CFG_H +#define CFG_H + +#include + +#include "globals.h" + +void cfg_setup_input(const char *cfg_buffer, const char *cfg_buffer_end); + +int __cfg_parse(void); +void __cfg_setup_mem(void); +void __cfg_destroy_mem(void); + +extern unsigned __cfg_task; + +L4_INLINE void cfg_init(void); +L4_INLINE int cfg_parse(void); + +L4_INLINE void cfg_init(void) +{ + /* first task the config file configures */ + /* XXX the task number should be possible to specify in the config file */ + __cfg_task = myself.id.task; +} + +L4_INLINE int cfg_parse(void) +{ + int r; + __cfg_setup_mem(); + r = __cfg_parse(); + __cfg_destroy_mem(); + return r; +} + +#endif diff --git a/apps/rmgr/src/coff-i386.h b/apps/rmgr/src/coff-i386.h new file mode 100644 index 0000000..5060866 --- /dev/null +++ b/apps/rmgr/src/coff-i386.h @@ -0,0 +1,294 @@ +/*** coff information for Intel 386/486. */ +#define __u16 unsigned short +#define __u32 unsigned int + +typedef struct external_doshdr { + __u16 f_magic; + __u16 f_cblp; + __u16 f_cp; + __u16 f_crlc; + __u16 f_cparhdr; + __u16 f_minalloc; + __u16 f_maxalloc; + __u16 f_ss; + __u16 f_sp; + __u16 f_csum; + __u16 f_ip; + __u16 f_cs; + __u16 f_lfarlc; + __u16 f_ovno; + __u16 f_res[4]; + __u16 f_oemid; + __u16 f_oeminfo; + __u16 f_res2[10]; + __u32 f_lfanew; +} DOSHDR; + +#define DOSMAGIC 0x5a4d + +/********************** FILE HEADER **********************/ + +struct external_filehdr { + __u16 f_magic; /* magic number */ + __u16 f_nscns; /* number of sections */ + __u32 f_timdat; /* time & date stamp */ + __u32 f_symptr; /* file pointer to symtab */ + __u32 f_nsyms; /* number of symtab entries */ + __u16 f_opthdr; /* sizeof(optional hdr) */ + __u16 f_flags; /* flags */ +}; + +/* Bits for f_flags: + * F_RELFLG relocation info stripped from file + * F_EXEC file is executable (no unresolved external references) + * F_LNNO line numbers stripped from file + * F_LSYMS local symbols stripped from file + * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax) + */ + +#define F_RELFLG (0x0001) +#define F_EXEC (0x0002) +#define F_LNNO (0x0004) +#define F_LSYMS (0x0008) + + + +#define I386MAGIC 0x14c +#define I386PTXMAGIC 0x154 +#define I386AIXMAGIC 0x175 + +/* This is Lynx's all-platform magic number for executables. */ + +#define LYNXCOFFMAGIC 0415 + +#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \ + && (x).f_magic != I386AIXMAGIC \ + && (x).f_magic != I386PTXMAGIC \ + && (x).f_magic != LYNXCOFFMAGIC) + +#define FILHDR struct external_filehdr +#define FILHSZ 20 + + +/********************** AOUT "OPTIONAL HEADER" **********************/ + +typedef struct { + __u32 virtual_address; + __u32 size; +} IMAGE_DATA_DIR; + +typedef struct +{ + __u16 magic; /* type of file */ + __u16 vstamp; /* version stamp */ + __u32 tsize; /* text size in bytes, padded to FW bdry*/ + __u32 dsize; /* initialized data " " */ + __u32 bsize; /* uninitialized data " " */ + __u32 entry; /* entry pt. */ + __u32 text_start; /* base of text used for this file */ + __u32 data_start; /* base of data used for this file */ + union { + struct { + __u32 image_base; + __u32 section_alignement; + __u32 file_alignement; + __u16 major_os_version; + __u16 minor_os_version; + __u16 major_image_version; + __u16 minor_image_version; + __u16 major_subsys_version; + __u16 minor_subsys_version; + __u32 win32_version_value; + __u32 sizeof_image; + __u32 sizeof_header; + __u32 checksum; + __u16 subsystem; + __u16 dll_characteristics; + __u32 sizeof_stack_reserve; + __u32 sizeof_stack_commit; + __u32 sizeof_heap_reserve; + __u32 sizeof_heap_commit; + __u32 loader_flags; + __u32 number_of_rva_and_sizes; + IMAGE_DATA_DIR data_directory[16]; + } nt; + } u; +} +AOUTHDR; + + +#define AOUTSZ 28 +#define AOUTHDRSZ 28 +#define NT32_OHDRSIZE 224 + +#define OMAGIC 0404 /* object files, eg as output */ +#define ZMAGIC 0413 /* demand load format, eg normal ld output */ +#define STMAGIC 0401 /* target shlib */ +#define SHMAGIC 0443 /* host shlib */ + + +/* define some NT default values */ +/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */ +#define NT_SECTION_ALIGNMENT 0x1000 +#define NT_FILE_ALIGNMENT 0x200 +#define NT_DEF_RESERVE 0x100000 +#define NT_DEF_COMMIT 0x1000 + +/********************** SECTION HEADER **********************/ + + +struct external_scnhdr { + char s_name[8]; /* section name */ + union { + __u32 s_paddr; /* physical address, aliased s_nlib */ + __u32 s_vsize; /* virtual size */ + } misc; + __u32 s_vaddr; /* virtual address */ + __u32 s_size; /* section size */ + __u32 s_scnptr; /* file ptr to raw data for section */ + __u32 s_relptr; /* file ptr to relocation */ + __u32 s_lnnoptr; /* file ptr to line numbers */ + __u16 s_nreloc; /* number of relocation entries */ + __u16 s_nlnno; /* number of line number entries*/ + __u32 s_flags; /* flags */ +}; + +#define SCNHDR struct external_scnhdr +#define SCNHSZ 40 + +#define SECT_NOLOAD 0x00000002 +#define SECT_CODE 0x00000020 +#define SECT_INIT_DATA 0x00000040 +#define SECT_UNINIT_DATA 0x00000080 +#define SECT_DISCARDABLE 0x02000000 + +#define SECT_EXECUTE 0x20000000 +#define SECT_READ 0x40000000 +#define SECT_WRITE 0x80000000 +/* + * names of "special" sections + */ +#define _TEXT ".text" +#define _DATA ".data" +#define _BSS ".bss" +#define _COMMENT ".comment" +#define _LIB ".lib" + +/********************** LINE NUMBERS **********************/ + +/* 1 line number entry for every "breakpointable" source line in a section. + * Line numbers are grouped on a per function basis; first entry in a function + * grouping will have l_lnno = 0 and in place of physical address will be the + * symbol table index of the function name. + */ +struct external_lineno { + union { + char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ + char l_paddr[4]; /* (physical) address of line number */ + } l_addr; + char l_lnno[2]; /* line number */ +}; + + +#define LINENO struct external_lineno +#define LINESZ 6 + + +/********************** SYMBOLS **********************/ + +#define E_SYMNMLEN 8 /* # characters in a symbol name */ +#define E_FILNMLEN 14 /* # characters in a file name */ +#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +struct external_syment +{ + union { + char e_name[E_SYMNMLEN]; + struct { + char e_zeroes[4]; + char e_offset[4]; + } e; + } e; + char e_value[4]; + char e_scnum[2]; + char e_type[2]; + char e_sclass[1]; + char e_numaux[1]; +}; + +#define N_BTMASK (0xf) +#define N_TMASK (0x30) +#define N_BTSHFT (4) +#define N_TSHIFT (2) + +union external_auxent { + struct { + char x_tagndx[4]; /* str, un, or enum tag indx */ + union { + struct { + char x_lnno[2]; /* declaration line number */ + char x_size[2]; /* str/union/array size */ + } x_lnsz; + char x_fsize[4]; /* size of function */ + } x_misc; + union { + struct { /* if ISFCN, tag, or .bb */ + char x_lnnoptr[4]; /* ptr to fcn line # */ + char x_endndx[4]; /* entry ndx past block end */ + } x_fcn; + struct { /* if ISARY, up to 4 dimen. */ + char x_dimen[E_DIMNUM][2]; + } x_ary; + } x_fcnary; + char x_tvndx[2]; /* tv index */ + } x_sym; + + union { + char x_fname[E_FILNMLEN]; + struct { + char x_zeroes[4]; + char x_offset[4]; + } x_n; + } x_file; + + struct { + char x_scnlen[4]; /* section length */ + char x_nreloc[2]; /* # relocation entries */ + char x_nlinno[2]; /* # line numbers */ + char x_checksum[4]; /* section COMDAT checksum */ + char x_associated[2]; /* COMDAT associated section index */ + char x_comdat[1]; /* COMDAT selection number */ + } x_scn; + + struct { + char x_tvfill[4]; /* tv fill value */ + char x_tvlen[2]; /* length of .tv */ + char x_tvran[2][2]; /* tv range */ + } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ + + +}; + +#define SYMENT struct external_syment +#define SYMESZ 18 +#define AUXENT union external_auxent +#define AUXESZ 18 + + +# define _ETEXT "etext" + + +/********************** RELOCATION DIRECTIVES **********************/ + + + +struct external_reloc { + char r_vaddr[4]; + char r_symndx[4]; + char r_type[2]; +}; + + +#define RELOC struct external_reloc +#define RELSZ 10 + diff --git a/apps/rmgr/src/config.h b/apps/rmgr/src/config.h new file mode 100644 index 0000000..b4340c0 --- /dev/null +++ b/apps/rmgr/src/config.h @@ -0,0 +1,6 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define LTHREAD_NO_IRQ(x) (16 + (x)) /* x = 0..15 -> threadno 16..31*/ + +#endif diff --git a/apps/rmgr/src/crt0.S b/apps/rmgr/src/crt0.S new file mode 100644 index 0000000..c49d607 --- /dev/null +++ b/apps/rmgr/src/crt0.S @@ -0,0 +1,140 @@ +#define __ASSEMBLY__ +#include + + .section .init + +ENTRY(__crt_dummy__) +ENTRY(_start) +ENTRY(start) + leal SYMBOL_NAME(_stack),%esp + pushl %eax + pushl %ebx + + /* initialize vector for exception 6 */ + movl $trap6_entry,%eax + movw %ax, _idt_offset_low + shrl $16, %eax + movw %ax, _idt_offset_high + movw %cs, %ax + movw %ax, _idt_selector + + /* load tiny interrupt descriptor table to catch exception 6 */ + lidtl SYMBOL_NAME(_idtdesc) + + pushl $SYMBOL_NAME(_exit) + jmp SYMBOL_NAME(startup) + +ENTRY(__main) + ret + + /* Show an error message and wait for keypress to reboot. */ +trap6_entry: + pusha + + cld + + /* print out warning */ + movl $trap6_warning, %esi + movl $(0xb8000 + (24*80*2)), %edi + movb $0x0F, %ah + +tp60: /* read next character from string */ + lodsb + + /* check for end-of-string */ + cmpb $0, %al + je tp62 + + /* check for newline */ + cmpb $'\n', %al + jne tp61 + + pushl %eax + pushl %esi + + /* move screen upwards 1 line */ + movl $((24*80*2)/4), %ecx + movl $(0xb8000 + 1*80*2), %esi + movl $0xb8000, %edi + rep movsl + + /* clear last line of screen */ + movl $((1*80*2)/4), %ecx + movl $0x07200720, %eax + rep stosl + + popl %esi + popl %eax + + /* jump to new line */ + movl $(0xb8000 + (24*80*2)), %edi + jmp tp60 + +tp61: /* print character */ + stosw + jmp tp60 + +tp62: /* wait for keypress */ + inb $0x64, %al + testb $0x01, %al + je tp62 + + movb %al, %ah + + /* empty keyboard buffer */ + inb $0x60, %al + + /* ignore PS/2 mouse events */ + testb $0x20, %ah + jne tp62 + + jmp SYMBOL_NAME(my_pc_reset) + + + /* the warning text */ +trap6_warning: + .string "\nRMGR: Invalid opcode detected! Be sure that you don't use any CPU\n optimization flags like -march=i686 when compiling RMGR and\n the depending libraries from OSKit 0.6.\n\n Press any key to reboot..." + + /* MultiBoot header - see multiboot.h. */ +#ifdef __ELF__ + .align 4 +#else /* ! __ELF__, that mean a.out assembler */ + .align 2 +#endif + +ENTRY(_mb_header) + .long 0x1BADB002 /* magic */ + .long 0x00010000 /* flags: AOUT_KLUDGE */ + .long - 0x00010000 - 0x1BADB002 + .long SYMBOL_NAME(_mb_header) /* header_addr */ + .long SYMBOL_NAME(__crt_dummy__) /* load_addr */ + .long _edata /* load_end_addr */ + .long _end /* bss_end_addr */ + .long SYMBOL_NAME(_start) /* entry */ + + .word 0 +_idtdesc: + .word (7*8)-1 + .long _idt + +_idt: + .word 0,0,0,0 /* trap 0 */ + .word 0,0,0,0 /* trap 1 */ + .word 0,0,0,0 /* trap 2 */ + .word 0,0,0,0 /* trap 3 */ + .word 0,0,0,0 /* trap 4 */ + .word 0,0,0,0 /* trap 5 */ + +_idt_offset_low: + .word 0 +_idt_selector: + .word 0 + .byte 0 + .byte 0xee +_idt_offset_high: + .word 0 + + .bss + + .space 8192 +ENTRY(_stack) diff --git a/apps/rmgr/src/exec.c b/apps/rmgr/src/exec.c new file mode 100644 index 0000000..b6e6988 --- /dev/null +++ b/apps/rmgr/src/exec.c @@ -0,0 +1,40 @@ +#include +#include + +#include "globals.h" +#include "rmgr.h" + +/* the interface we implement */ + +#include "exec.h" + +/* header read functions */ + +int simple_exec_read(void *handle, vm_offset_t file_ofs, + void *buf, vm_size_t size, + vm_size_t *out_actual) +{ + struct exec_task *e = (struct exec_task *) handle; + memcpy(buf, (char*)(e->mod_start) + file_ofs, size); + + *out_actual = size; + return 0; +} + +/* read_exec functions */ + +int simple_exec_read_exec(void *handle, + vm_offset_t file_ofs, vm_size_t file_size, + vm_offset_t mem_addr, vm_size_t mem_size, + exec_sectype_t section_type) +{ + struct exec_task *e = (struct exec_task *) handle; + if (! (section_type & (EXEC_SECTYPE_ALLOC|EXEC_SECTYPE_LOAD))) + return 0; + + memcpy((void *) mem_addr, (char*)(e->mod_start) + file_ofs, file_size); + if (file_size < mem_size) + memset((void *) (mem_addr + file_size), 0, mem_size - file_size); + + return 0; +} diff --git a/apps/rmgr/src/exec.h b/apps/rmgr/src/exec.h new file mode 100644 index 0000000..8b71bd0 --- /dev/null +++ b/apps/rmgr/src/exec.h @@ -0,0 +1,25 @@ +#ifndef EXEC_H +#define EXEC_H + +#include +#include +#include + +#include "grub_mb_info.h" +#include "grub_vbe_info.h" + +/* services in exec.c */ +exec_read_func_t simple_exec_read; +exec_read_exec_func_t simple_exec_read_exec; + +/* pe-loader pe.c */ +int exec_load_pe(exec_read_func_t *read, exec_read_exec_func_t *read_exec, + void *handle, exec_info_t *out_info); + +/* trampoline.c */ +void task_trampoline(vm_offset_t entry, struct grub_multiboot_info *mbi); + +extern char _task_trampoline_end; +#define task_trampoline_end ((void *) &_task_trampoline_end) + +#endif diff --git a/apps/rmgr/src/globals.c b/apps/rmgr/src/globals.c new file mode 100644 index 0000000..46c21f0 --- /dev/null +++ b/apps/rmgr/src/globals.c @@ -0,0 +1,3 @@ +#define DEFINE_GLOBALS + +#include "globals.h" diff --git a/apps/rmgr/src/globals.h b/apps/rmgr/src/globals.h new file mode 100644 index 0000000..efe04c8 --- /dev/null +++ b/apps/rmgr/src/globals.h @@ -0,0 +1,61 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include +#include +#include + +/* globals defined here (when included from globals.c) */ + +#ifdef DEFINE_GLOBALS +# define __EXTERN +#else +# define __EXTERN extern +#endif + +/* thread ids of global importance */ +__EXTERN l4_threadid_t my_pager, my_preempter, myself; +__EXTERN l4_threadid_t rmgr_pager_id, rmgr_super_id; + +/* RAM memory size */ +__EXTERN vm_offset_t mem_lower, mem_upper; + +/* number of small address spaces configured at boot */ +__EXTERN unsigned small_space_size; + +__EXTERN int debug, debug_log_mask, debug_log_types, verbose, no_pentium; +__EXTERN int no_checkdpf; + +#undef __EXTERN + +/* more global stuff */ + +typedef byte_t owner_t; /* an owner is a task number < 256 */ +#define O_MAX (255) +#define O_FREE (0) +#define O_RESERVED (1) + +#ifndef __VERSION_X__ +#define TASK_MAX (1L << 11) +#else /* __X_ADAPTION__ */ +#define TASK_MAX (1L << 8) +#endif /* __X_ADAPTION__ */ + +extern int _start; /* begin of RMGR memory -- defined in crt0.S */ +extern int _stext; /* begin of RGMR text -- defined by rmgr.ld */ +extern int _stack; /* end of RMGR stack -- defined in crt0.S */ +extern int _end; /* end of RGMR memory -- defined by rmgr.ld */ +extern int _etext; /* begin of data memory -- defined by crt0.S */ + +/* the check macro is like assert(), but also evaluates its argument + if NCHECK is defined */ +#ifdef NCHECK +# define check(expression) ((void)(expression)) +#else /* ! NCHECK */ +# define check(expression) \ + ((void)((expression) ? 0 : \ + (panic("RMGR: "__FILE__":%u: failed check `"#expression"'", \ + __LINE__), 0))) +#endif /* ! NCHECK */ + +#endif diff --git a/apps/rmgr/src/grub_mb_info.h b/apps/rmgr/src/grub_mb_info.h new file mode 100644 index 0000000..57a7f48 --- /dev/null +++ b/apps/rmgr/src/grub_mb_info.h @@ -0,0 +1,215 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1996 Erich Boleyn + * Copyright (C) 2000 Free Software Foundation, Inc. + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * The structure type "mod_list" is used by the "multiboot_info" structure. + */ + +struct grub_mod_list +{ + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + unsigned long mod_start; + unsigned long mod_end; + + /* Module command line */ + unsigned long cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + unsigned long pad; +}; + + +/* + * INT-15, AX=E820 style "AddressRangeDescriptor" + * ...with a "size" parameter on the front which is the structure size - 4, + * pointing to the next one, up until the full buffer length of the memory + * map has been reached. + */ + +struct grub_AddrRangeDesc +{ + unsigned long size; + unsigned long long BaseAddr; + unsigned long long Length; + unsigned long Type; + + /* unspecified optional padding... */ +}; + +/* usable memory "Type", all others are reserved. */ +#define MB_ARD_MEMORY 1 + + +/* Drive Info structure. */ +struct grub_drive_info +{ + /* The size of this structure. */ + unsigned long size; + + /* The BIOS drive number. */ + unsigned char drive_number; + + /* The access mode (see below). */ + unsigned char drive_mode; + + /* The BIOS geometry. */ + unsigned short drive_cylinders; + unsigned char drive_heads; + unsigned char drive_sectors; + + /* The array of I/O ports used for the drive. */ + unsigned short drive_ports[0]; +}; + +/* Drive Mode. */ +#define MB_DI_CHS_MODE 0 +#define MB_DI_LBA_MODE 1 + + +/* APM BIOS info. */ +struct grub_apm_info +{ + unsigned short version; + unsigned short cseg; + unsigned long offset; + unsigned short cseg_16; + unsigned short dseg_16; + unsigned short cseg_len; + unsigned short cseg_16_len; + unsigned short dseg_16_len; +}; + + +/* + * MultiBoot Info description + * + * This is the struct passed to the boot image. This is done by placing + * its address in the EAX register. + */ + +struct grub_multiboot_info +{ + /* MultiBoot info version number */ + unsigned long flags; + + /* Available memory from BIOS */ + unsigned long mem_lower; + unsigned long mem_upper; + + /* "root" partition */ + unsigned long boot_device; + + /* Kernel command line */ + unsigned long cmdline; + + /* Boot-Module list */ + unsigned long mods_count; + unsigned long mods_addr; + + union + { + struct + { + /* (a.out) Kernel symbol table info */ + unsigned long tabsize; + unsigned long strsize; + unsigned long addr; + unsigned long pad; + } + a; + + struct + { + /* (ELF) Kernel section header table */ + unsigned long num; + unsigned long size; + unsigned long addr; + unsigned long shndx; + } + e; + } + syms; + + /* Memory Mapping buffer */ + unsigned long mmap_length; + unsigned long mmap_addr; + + /* Drive Info buffer */ + unsigned long drives_length; + unsigned long drives_addr; + + /* ROM configuration table */ + unsigned long config_table; + + /* Boot Loader Name */ + unsigned long boot_loader_name; + + /* APM table */ + unsigned long apm_table; + + /* Video */ + unsigned long vbe_control_info; + unsigned long vbe_mode_info; + unsigned short vbe_mode; + unsigned short vbe_interface_seg; + unsigned short vbe_interface_off; + unsigned short vbe_interface_len; +}; + +/* + * Flags to be set in the 'flags' parameter above + */ + +/* is there basic lower/upper memory information? */ +#define MB_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MB_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MB_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MB_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MB_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MB_INFO_ELF_SHDR 0x00000020 + +/* is there a full memory map? */ +#define MB_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MB_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MB_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MB_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MB_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MB_INFO_VIDEO_INFO 0x00000800 + +extern struct grub_multiboot_info grub_boot_info; + diff --git a/apps/rmgr/src/grub_vbe_info.h b/apps/rmgr/src/grub_vbe_info.h new file mode 100644 index 0000000..507c962 --- /dev/null +++ b/apps/rmgr/src/grub_vbe_info.h @@ -0,0 +1,77 @@ + +/* VBE controller information. */ +struct vbe_controller +{ + unsigned char signature[4]; + unsigned short version; + unsigned long oem_string; + unsigned long capabilities; + unsigned long video_mode; + unsigned short total_memory; + unsigned short oem_software_rev; + unsigned long oem_vendor_name; + unsigned long oem_product_name; + unsigned long oem_product_rev; + unsigned char reserved[222]; + unsigned char oem_data[256]; +} __attribute__ ((packed)); + +/* VBE mode information. */ +struct vbe_mode +{ + unsigned short mode_attributes; + unsigned char win_a_attributes; + unsigned char win_b_attributes; + unsigned short win_granularity; + unsigned short win_size; + unsigned short win_a_segment; + unsigned short win_b_segment; + unsigned long win_func; + unsigned short bytes_per_scanline; + + /* >=1.2 */ + unsigned short x_resolution; + unsigned short y_resolution; + unsigned char x_char_size; + unsigned char y_char_size; + unsigned char number_of_planes; + unsigned char bits_per_pixel; + unsigned char number_of_banks; + unsigned char memory_model; + unsigned char bank_size; + unsigned char number_of_image_pages; + unsigned char reserved0; + + /* direct color */ + unsigned char red_mask_size; + unsigned char red_field_position; + unsigned char green_mask_size; + unsigned char green_field_position; + unsigned char blue_mask_size; + unsigned char blue_field_position; + unsigned char reserved_mask_size; + unsigned char reserved_field_position; + unsigned char direct_color_mode_info; + + /* >=2.0 */ + unsigned long phys_base; + unsigned long reserved1; + unsigned short reversed2; + + /* >=3.0 */ + unsigned short linear_bytes_per_scanline; + unsigned char banked_number_of_image_pages; + unsigned char linear_number_of_image_pages; + unsigned char linear_red_mask_size; + unsigned char linear_red_field_position; + unsigned char linear_green_mask_size; + unsigned char linear_green_field_position; + unsigned char linear_blue_mask_size; + unsigned char linear_blue_field_position; + unsigned char linear_reserved_mask_size; + unsigned char linear_reserved_field_position; + unsigned long max_pixel_clock; + + unsigned char reserved3[189]; +} __attribute__ ((packed)); + diff --git a/apps/rmgr/src/init.c b/apps/rmgr/src/init.c new file mode 100644 index 0000000..3c4b6b8 --- /dev/null +++ b/apps/rmgr/src/init.c @@ -0,0 +1,1278 @@ +/* startup stuff */ + +/* it should be possible to throw away the text/data/bss of the object + file resulting from this source -- so, we don't define here + anything we could still use at a later time. instead, globals are + defined in globals.c */ + +#include +#include +#include +#include +#include + +#include + +#include "config.h" +#include "memmap.h" +#include "globals.h" +#include "exec.h" +#include "rmgr.h" +#include "cfg.h" + +#include +#include "init.h" + +struct multiboot_module mb_mod[MODS_MAX]; +struct vbe_controller mb_vbe_cont; +struct vbe_mode mb_vbe_mode; + +static void init_globals(void); +static void init_memmap(void); +#if defined(CONFIG_IO_FLEXPAGES) +static void init_iospace(void); +#endif +static void init_irq(void); +static void init_task(void); +static void init_small(void); +static void configure(void); +static void start_tasks(void); + +static void setup_task(l4_threadid_t t); +static int overlaps_myself(vm_offset_t begin, vm_offset_t end); +static int alloc_exec_read_exec(void *handle, + vm_offset_t file_ofs, vm_size_t file_size, + vm_offset_t mem_addr, vm_size_t mem_size, + exec_sectype_t section_type); +static int alloc_exec_read(void *handle, vm_offset_t file_ofs, + void *buf, vm_size_t size, + vm_size_t *out_actual); +static int set_small(l4_threadid_t t, int num); +static int set_prio(l4_threadid_t t, int num); + + +int boot_errors = 0; /* no of boot errors */ +int boot_wait = 0; /* wait after boot? */ +int error_stop = 0; /* wait for keypress on boot error? */ +int hercules = 0; /* startup output on hercules? */ +int boot_mem_dump = 0; /* dump memory at startup time? */ +int kernel_running = 0; /* kernel already running? if yes, we use outchar */ +int last_task_module = 0; /* idx of last module to be booted - can be + controlled via the '-mods=' command + line parameter */ +int l4_version = 0; + +bootquota_t bootquota[TASK_MAX]; + + +const char* +mb_mod_name(int i) +{ + return (i<0 || i>=MODS_MAX || !mb_mod[i].string) + ? "[unknown]" + : (char *)mb_mod[i].string; +} + +const char* +owner_name(owner_t owner) +{ + return mb_mod_name(owner-myself.id.task-1+first_task_module); +} + +/* a boot error occured */ +void +boot_error(void) +{ + if (error_stop) + { + char c; + printf("\r\nRMGR: boot error. " + "Return continues, Esc panics, \"m\" shows memory map"); + c = getchar(); + printf("\r%60s\r",""); + switch (c) + { + case 0x1B: + panic("RMGR: boot error"); + case 'm': + case 'M': + show_mem_info(); + break; + } + } + boot_errors++; +} + +/* a fatal boot error occured, don't allow to continue */ +void +boot_fatal(void) +{ + for (;;) + { + char c; + printf("\r\nRMGR: Fatal boot error. " + "Esc panics, \"m\" shows memory map"); + for (;;) + { + c = getchar(); + switch (c) + { + case 0x1B: + printf("\r%70s\r",""); + panic("RMGR: fatal boot error"); + case 'm': + case 'M': + printf("\r%70s\r",""); + show_mem_info(); + break; + default: + continue; + } + break; + } + } +} + +static void +boot_panic(const char *fmt, ...) +{ + for (;;) + { + char c; + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\r\nRMGR: Return panics, \"m\" shows memory map"); + c = getchar(); + printf("\r%60s\r",""); + switch (c) + { + case 0x0D: + panic("RMGR: panic"); + case 'm': + case 'M': + show_mem_info(); + break; + } + } +} + +/* started as the L4 booter task through startup() in startup.c */ +void init(void) +{ + vm_offset_t address; + + printf("RMGR: Hi there!\n"); + + init_globals(); + + init_memmap(); + +#if defined(CONFIG_IO_FLEXPAGES) + /* Request I/O Space from sigma0 */ + init_iospace(); +#endif + init_irq(); + + init_task(); + + init_small(); + + configure(); + + setup_task(myself); + setup_task(my_pager); + + /* start the tasks loaded as modules */ + start_tasks(); + + /* add the memory used by this module and not any longer required + (the ".init" section) to the free memory pool */ + for (address = (vm_offset_t) &_start & L4_PAGEMASK; + address < ((vm_offset_t) &_stext & L4_PAGEMASK); + address += L4_PAGESIZE) + { + check(memmap_free_page(address, O_RESERVED)); + } + + if (boot_errors || boot_wait) + { + char c; + + if (boot_errors) + printf("RMGR: WARNING: there were %d boot errors -- continue?\n" + " Return continues, Esc panics, " + "\"k\" enters L4 kernel debugger...\n", + boot_errors); + else + printf("RMGR: bootwait option was set -- please press a key\n" + " Return continues, Esc panics, " + "\"k\" enters L4 kernel debugger...\n"); + c = getchar(); + + if (c == 27) + panic("RMGR: boot error"); + else if (c == 'k' || c == 'K') + enter_kdebug("boot error"); + } + + + /* now start the resource manager */ + rmgr(); +} + +/* support functions for init() */ + +static void configure(void) +{ + char *config, *config_end; + + cfg_init(); + + /* find the config data */ + if (! (mb_info.flags & MULTIBOOT_CMDLINE)) + return; + + config = strchr((char *) mb_info.cmdline, ' '); + if (! config) + return; + + config++; /* skip ' ' character */ + if (!strstr(config, "-configfile")) + { + /* not using a configfile -- use the cmdline */ + config_end = config + strlen(config); + + /* skip options */ + while (config < config_end) + { + if (*config == ' ') /* skip spaces */ + { + config++; + continue; + } + + if (*config != '-') /* end of options found */ + break; + + config = strchr(config, ' '); /* find end of this option */ + if (!config) + return; + } + } + else + { + /* the configfile is in the first module... */ + + /* make sure the config file is not the last module */ + check(mb_info.mods_count >= first_task_module + 2); + + config = (char *) mb_mod[first_task_module].mod_start; + config_end = (char *) mb_mod[first_task_module].mod_end; + + /* is it really a config file? */ + if (strncmp(config, "#!rmgr", 6) != 0) + { + printf("RMGR: ERROR: 2nd module is not a config file " + "(doesn't start with \"#!rmgr\")\n"); + boot_error(); + return; + } + + first_task_module++; + } + + cfg_setup_input(config, config_end); + + if (cfg_parse() != 0) + boot_error(); + + printf("RMGR: log_mask: %x, log_types: %x\n", + debug_log_mask, debug_log_types); + + /* a few post-parsing actions follow... */ + if (small_space_size) + { + vm_offset_t s = small_space_size; + + small_space_size /= 0x400000; /* divide by 4MB */ + if (s > small_space_size * 0x400000 /* did we delete any size bits? */ + || (small_space_size & (small_space_size - 1))) /* > 1 bit set? */ + { + /* use next largest legal size */ + int count; + for (count = 0; small_space_size; count++) + { + small_space_size >>= 1; + } + + small_space_size = 1L << count; + } + + if (small_space_size > 64) + { + printf("RMGR: ERROR: small_space_size 0x%08x too large\n", s); + small_space_size = 0; + boot_error(); + } + + else + { + unsigned i; + + for (i = 1; i < 128/small_space_size; i++) + check(small_free(i, O_RESERVED)); + + printf("RMGR: configured small_space_size = %d MB\n", + small_space_size * 4); + } + } +} + +static void setup_task(l4_threadid_t t) +{ + unsigned me = t.id.task; + bootquota_t *b = & bootquota[me]; + + if (b->small_space != 0xff) + { + if (small_space_size) + set_small(t, b->small_space); + else + b->small_space = 0xFF; + } + + set_prio(t, b->prio); +} + +static void init_globals(void) +{ + dword_t dummy; + + /* set some globals */ + + /* set myself (my thread id) */ + myself = rmgr_pager_id = rmgr_super_id = l4_myself(); + rmgr_pager_id.id.lthread = RMGR_LTHREAD_PAGER; + rmgr_super_id.id.lthread = RMGR_LTHREAD_SUPER; + + /* set my_pager */ + my_preempter = my_pager = L4_INVALID_ID; + l4_thread_ex_regs(myself, (dword_t) -1, (dword_t) -1, + &my_preempter, &my_pager, &dummy, &dummy, &dummy); + + /* set mem size */ + mem_upper = mb_info.mem_upper; + mem_lower = mb_info.mem_lower & ~3; /* round down to next 4k boundary */ + + /* more global initialization stuff */ + small_space_size = 0; + + debug = verbose = debug_log_mask = debug_log_types = 0; + +#if 0 + if (no_pentium == 1) + printf("RMGR: running on L4/486\n"); + else if (no_pentium == 0) + printf("RMGR: running on L4/Pentium\n"); + else { + printf("RMGR: unknown L4 version, assuming L4/486\n"); + no_pentium = 1; + } +#else + printf("RMGR: running on %s\n", KERNEL_NAMES[l4_version]); +#endif + + + if (mb_info.flags & MULTIBOOT_CMDLINE) + { + /* check for -nopentium option */ + if (strstr((char *) mb_info.cmdline, "-nopentium")) + { + no_pentium=1; + printf("no l4/pentium\n"); + } + /* check for -nocheckdpf option */ + if (strstr((char *) mb_info.cmdline, "-nocheckdpf")) + { + no_checkdpf=1; + printf("don't check double page faults\n"); + } + /* check for -errorstop */ + if (strstr((char *) mb_info.cmdline, "-errorstop")) + { + error_stop=1; + } + /* check for -memdump */ + if (strstr((char *) mb_info.cmdline, "-memdump")) + { + boot_mem_dump=1; + } + } + quota_init(); +} +#if defined(CONFIG_IO_FLEXPAGES) +/* Request I/O Space from sigma0 */ +static void init_iospace(void){ + + l4_fpage_t foo_fp; + l4_msgdope_t res; + dword_t dw0; + + /* the address of the receive window doesn't matter actually, but should not be 0 */ + foo_fp = l4_fpage((int) 0xF0000000, 0, 1, 0); + + dw0 = 0xF0000040; + + l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + dw0, dw0, + (void *) foo_fp.fpage, + &dw0, &dw0, + L4_IPC_NEVER, &res); + + +} +#endif + +static void init_irq(void) +{ + int err, i; + unsigned *sp; + dword_t code, dummy; + l4_msgdope_t result; + l4_threadid_t t, preempter, pager; + + /* initialize to "reserved" */ + irq_init(); + + printf("RMGR: attached irqs = [ "); + + /* start a thread for each irq */ + t = myself; + + for (i = 0; i < IRQ_MAX; i++) + { + t.id.lthread = LTHREAD_NO_IRQ(i); + sp = (unsigned *)(__irq_stacks + (i + 1) * __IRQ_STACKSIZE); + + *--sp = i; /* pass irq number as argument to thr func */ + *--sp = 0; /* faked return address */ + preempter = my_preempter; pager = my_pager; + l4_thread_ex_regs(t, (dword_t) __irq_thread, (dword_t) sp, + &preempter, &pager, &dummy, &dummy, &dummy); + + /* handshake and status check */ + err = l4_i386_ipc_receive(t, L4_IPC_SHORT_MSG, &code, &dummy, + L4_IPC_NEVER, &result); + + assert(err == 0); + + if (i == 2) + { + /* enable IRQ2 */ + __asm__("inb $0x21,%al\n"\ + "jmp 1f\n"\ + "1:\tjmp 1f\n"\ + "1:\tandb $0xfb,%al\n"\ + "outb %al,$0x21\n"); + } + + if (code == 0) + { + if (i != 2) + irq_free(i, O_RESERVED); /* free irq, except if irq2 */ + printf("%x ", i); + } + else + printf(" ", i); + } + printf("]\n"); +} + +static void init_task(void) +{ + unsigned i; + + task_init(); + + for (i = myself.id.task + 1; i < TASK_MAX; i++) + __task[i] = O_FREE; + + first_not_bmod_free_modnr = mb_info.mods_count; + first_not_bmod_free_task = first_not_bmod_task + = myself.id.task + 1 + + (mb_info.mods_count-first_task_module); +} + +static void init_small(void) +{ + small_init(); +} + + +static void init_memmap(void) +{ + l4_msgdope_t result; + l4_snd_fpage_t sfpage; + vm_offset_t address, a; + vm_size_t free_size = 0, reserved_size = 0; + int error; + int ignore_high_pages = 0; + + /* initialize to "reserved" */ + memmap_init(); + + /* invalidate the ``last page fault'' array */ + for (a = 0; a < TASK_MAX; a++) + { + last_pf[a].pfa = -1; + last_pf[a].eip = -1; + } + + mem_high = 0; + + if (!no_pentium) + { + /* get as much super (4MB) pages as possible, starting with + superpage 1 (0x400000) */ + for (address = L4_SUPERPAGESIZE; address < MEM_MAX; + address += L4_SUPERPAGESIZE) + { + error = l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + address | 1, L4_LOG2_SUPERPAGESIZE << 2, + L4_IPC_MAPMSG(0, L4_WHOLE_ADDRESS_SPACE), + &sfpage.snd_base, &sfpage.fpage.fpage, + L4_IPC_NEVER, &result); + /* XXX should i check for errors? */ + + if (! (l4_ipc_fpage_received(result) + && l4_ipc_is_fpage_writable(sfpage.fpage) + && sfpage.fpage.fp.size == L4_LOG2_SUPERPAGESIZE)) + { + vm_size_t size; + + if (!l4_ipc_fpage_received(result)) + break; + + size = 1L << sfpage.fpage.fp.size; + assert(size == (size & L4_PAGEMASK)); + + for (; size > 0; size -= L4_PAGESIZE, address += L4_PAGESIZE) + { + free_size += L4_PAGESIZE; + memmap_free_page(address, O_RESERVED); + } + + break; + } + + /* kewl, we've received an super awsum page */ + free_size += L4_SUPERPAGESIZE; + + for (a = address; a < address + L4_SUPERPAGESIZE; a += L4_PAGESIZE) + { + memmap_free_page(a, O_RESERVED); + } + + if (mem_high < (a - L4_PAGESIZE)) /* a == end of superpage */ + mem_high = a; + + assert(memmap_owner_superpage(address) == O_FREE); + } + } + /* page in BIOS data area page explicitly. like adapter space it will be + marked "reserved" and special-cased in the pager() in memmap.c */ + error = l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + 0, 0, + L4_IPC_MAPMSG(0, L4_WHOLE_ADDRESS_SPACE), + &sfpage.snd_base, &sfpage.fpage.fpage, + L4_IPC_NEVER, &result); + /* XXX should i check for errors? */ + + /* now add all memory we can get from L4 to the memory map as free + memory */ + for (;;) + { + error = l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + 0xfffffffc, 0, + L4_IPC_MAPMSG(0, L4_WHOLE_ADDRESS_SPACE), + &sfpage.snd_base, &sfpage.fpage.fpage, + L4_IPC_NEVER, &result); + /* XXX should i check for errors? */ + + if (! sfpage.fpage.fpage) + break; /* out of memory */ + + if (sfpage.snd_base >= MEM_MAX) + { + if (!ignore_high_pages) + { + ignore_high_pages = 1; + printf("RMGR: WARNING: all memory above %ld MB is wasted!\n", + MEM_MAX/(1024*1024)); + boot_error(); + } + continue; + } + + if (mem_high < sfpage.snd_base + L4_PAGESIZE) + mem_high = sfpage.snd_base + L4_PAGESIZE; + + if (memmap_owner_page(sfpage.snd_base) == O_FREE) + { + printf("RMGR: WARNING: we've been given page 0x%08x twice!\n", + sfpage.snd_base); + continue; + } + + free_size += L4_PAGESIZE; + memmap_free_page(sfpage.snd_base, O_RESERVED); + } + + assert(mem_high > 0x200000); /* 2MB is the minimum for any useful work */ + + /* page in memory we own and we reserved before booting; we need to + do this explicitly as the L4 kernel won't hand it out voluntarily + (see L4 rerefence manual, sec. 2.7). + don't care for overlaps with our own area here because we will + reserve our memory below */ + for (address = mod_range_start & L4_PAGEMASK; + address <= mod_range_end; + address += L4_PAGESIZE) + { + /* check if we really can touch the memory */ + if (address > mem_high) + { + printf("RMGR: Can't touch memory at %08x for boot modules. ", + address); + if (address > mem_phys) + printf("There is no RAM\n" + " at this address.\n"); + else + { + printf("This error occurs because\n" + " the RAM at this address is owned by the kernel."); + if (l4_version == VERSION_FIASCO) + printf(" Fiasco occupies 20%% of the\n" + " physical memory per default."); + printf("\n"); + } + boot_fatal(); + break; + } + + /* force write page fault */ + /* * (volatile int *) address |= 0; */ + asm volatile ("orl $0, (%0)" + : /* nothing out */ + : "r" (address) + ); + if (memmap_owner_page(address) != O_FREE) + { + memmap_free_page(address, O_RESERVED); + free_size += L4_PAGESIZE; + } + } + + /* page in adapter space explicitly. the adapter space will be + marked "reserved" and special-cased in the pager() in memmap.c */ + for (address = mem_lower * 1024L; + address < 0x100000L; + address += L4_PAGESIZE) + { + error = l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + address, 0, + L4_IPC_MAPMSG(0, L4_WHOLE_ADDRESS_SPACE), + &sfpage.snd_base, &sfpage.fpage.fpage, + L4_IPC_NEVER, &result); + /* XXX should i check for errors? */ + } + + /* reserve memory for ourselves; page in our own memory en-passant */ + for (address = ((vm_offset_t) (&_start)) & L4_PAGEMASK; + address <= (vm_offset_t) &_end; + address += L4_PAGESIZE) + { + memmap_alloc_page(address, O_RESERVED); + reserved_size += L4_PAGESIZE; + + /* force write page fault */ + /* * (volatile int *) address |= 0; */ + asm volatile ("orl $0, (%0)" + : /* nothing out */ + : "r" (address) + ); + } + + /* Reserve memory for Fiasco symbols. + * Move it to the upper memory limit to prevent memory fragmentation */ + if (fiasco_symbols) + { + vm_size_t size = fiasco_symbols_end - fiasco_symbols; + int i = 0, pages = size / L4_PAGESIZE; + + for (address = mem_high; address > 0 && i < pages; address -= L4_PAGESIZE) + { + if (memmap_owner_page(address) != O_FREE) + i=0; + else + if (++i >= pages) + break; + } + + if (!address) + { + printf("No space for symbols found, disabling Fiasco symbols\n"); + fiasco_symbols = 0; + } + else + { + memcpy((void*)address, (void*)fiasco_symbols, size); + fiasco_symbols = address; + fiasco_symbols_end = address+size; + for (i=0; imagic == L4_KERNEL_INFO_MAGIC); + + /* the non-RAM high-memory superpages are all free for allocation */ + for (address = 0x8000; address < 0x10000; + address += L4_SUPERPAGESIZE/0x10000) /* scaled by 0x10000**-1 to + prevent overflow */ + { + memmap_free_superpage(address * 0x10000, O_RESERVED); + } + + + printf("RMGR: total RAM size = %6ld KB (reported by bootloader)\n" + " received %6ld KB RAM from sigma0\n" + " %6ld KB reserved for RMGR\n", + mb_info.mem_upper + mb_info.mem_lower, + free_size/1024L, reserved_size/1024L); + + return; +} + +#define alloc_from_page(pageptr, size) \ +({ \ + vm_offset_t ret; \ + vm_offset_t new_pageptr = ((pageptr) + (size) + 3) & ~3; \ + if (((pageptr) & L4_PAGEMASK) != (new_pageptr & L4_PAGEMASK)) \ + ret = 0; \ + else \ + { \ + ret = (pageptr); \ + (pageptr) = new_pageptr; \ + } \ + ret; \ +}) + +static void start_tasks(void) +{ + unsigned i,i2; + l4_threadid_t t; + exec_info_t exec_info; + int exec_ret; + struct exec_task e; + const char *name; + vm_offset_t address; + struct grub_multiboot_info *mbi; + struct vbe_mode *mbi_vbe_mode; + struct vbe_controller *mbi_vbe_cont; + dword_t *sp, entry; + + t = myself; +/* t.id.nest++; */ + t.id.chief = t.id.task; + + if (last_task_module == 0) + last_task_module = mb_info.mods_count; + + printf ("RMGR: will load modules %d to %d (can be limited via '-mods=')\n", first_task_module, (last_task_module - 1)); + + i2 = first_task_module; + for (i = first_task_module; i < last_task_module; i++, i2++) + { + t.id.task = myself.id.task + 1 + (i - first_task_module); + check(task_alloc(t.id.task, myself.id.task)); + + mod_exec_init(mb_mod, i, mb_info.mods_count); + + e.mod_start = (void *)(mb_mod[i].mod_start); + e.task_no = t.id.task; + e.mod_no = i; + + name = mb_mod_name(i); + + /* register name and id for the RMGR_TASK_GET_ID function */ + mb_mod_ids[i2] = t; + + printf("RMGR: loading task %s from 0x%08x-0x%08x\n to [ ", + name, mb_mod[i].mod_start, mb_mod[i].mod_end); + exec_ret = exec_load(alloc_exec_read, alloc_exec_read_exec, + &e, &exec_info); + if (exec_ret) + /* if it failed, try loading it as an PE file */ + exec_ret = exec_load_pe(alloc_exec_read, alloc_exec_read_exec, &e, &exec_info); + + printf("]\n"); + + if (exec_ret) + { + printf("RMGR: ERROR: exec_load() failed with code %d\n", exec_ret); + boot_error(); + continue; + } + + /* pass multiboot info to new task in extra page */ + for (address = 0x3000; /* skip page 0, 1 and 2 */ + address < mem_high; + address += L4_PAGESIZE) + { + if (! quota_check_mem(t.id.task, address, L4_PAGESIZE)) + continue; + if (memmap_owner_page(address) != O_FREE) + continue; + if (memmap_alloc_page(address, t.id.task)) + break; + } + assert(address < mem_high); + + /* copy mb_info */ + check((mbi = (struct grub_multiboot_info *) + alloc_from_page(address, sizeof(struct grub_multiboot_info)))); + + *mbi = mb_info; + mbi->flags &= MULTIBOOT_MEMORY|MULTIBOOT_BOOT_DEVICE|MB_INFO_VIDEO_INFO; + + /* copy mb_info->vbe_mode and mb_info->vbe_controller */ + if (mb_info.flags & MB_INFO_VIDEO_INFO) + { + vm_offset_t old_address = address; + if (mb_info.vbe_mode_info) + { + if ((mbi_vbe_mode = (struct vbe_mode*) + alloc_from_page(address, sizeof(struct vbe_mode))) && + (mbi_vbe_cont = (struct vbe_controller*) + alloc_from_page(address, sizeof(struct vbe_controller)))) + { + *mbi_vbe_mode = mb_vbe_mode; + *mbi_vbe_cont = mb_vbe_cont; + mbi->vbe_mode_info = (vm_offset_t)mbi_vbe_mode; + mbi->vbe_control_info = (vm_offset_t)mbi_vbe_cont; + } + else + { + printf("RMGR: ERROR: can't pass VBE video info " + "(needs %d bytes)\n", + sizeof(struct vbe_controller)+ + sizeof(struct vbe_mode)); + boot_error(); + /* remove video information from multiboot info */ + address = old_address; + mbi->flags &= ~MB_INFO_VIDEO_INFO; + } + } + } + + /* copy mb_info->cmdline */ + if (mb_mod[i].string) + { + char *string; + vm_size_t len = strlen(name) + 1; + + if (! (string = (char *) alloc_from_page(address, len))) + { + printf("RMGR: ERROR: command line too long -- truncating\n"); + boot_error(); + + len = L4_PAGESIZE - 0x120; + check(string = (char *) alloc_from_page(address, len)); + } + + mbi->flags |= MULTIBOOT_CMDLINE; + mbi->cmdline = (vm_offset_t) string; + strncpy(string, name, len); + *(string + len - 1) = 0; /* zero-terminate string */ + } + + /* before we start allocating extra mem, first allocate stack space */ + check((sp = (dword_t *) alloc_from_page(address, 0x100))); + + sp = (dword_t *) (0x100 + (vm_offset_t) sp); + + /* if any modules have been passed on to this task, copy module info */ + if (bootquota[t.id.task].mods) + { + struct multiboot_module *m; + unsigned mod_i = i + 1; + unsigned j = bootquota[t.id.task].mods; + + i += j; + if (i >= mb_info.mods_count) + { + printf("RMGR: ERROR: task configured to use %d modules, " + "but there are only %ld modules\n" + " left for loading -- not starting %s\n", + j, mb_info.mods_count - (i - j) - 1, name); + boot_error(); + break; + } + + if (! (m = (struct multiboot_module *) + alloc_from_page(address, + j * sizeof(struct multiboot_module)))) + { + printf("RMGR: ERROR: out of boot-info memory space --\n" + " won't start %s", + name); + boot_error(); + continue; + } + + mbi->mods_addr = (vm_offset_t) m; + mbi->mods_count = j; + + for (; j--; m++, mod_i++) + { + vm_offset_t mod_mem; + *m = mb_mod[mod_i]; + + if (m->string) + { + vm_size_t len = strlen((char *) (m->string)) + 1; + char *string = (char *) alloc_from_page(address, len); + + if (! string) + { + printf("RMGR: ERROR: not enough room for module string" + " --\n" + " not passing string \"%s\"\n", + (char *) (m->string)); + boot_error(); + + m->string = 0; + continue; + } + + strcpy(string, (char *) (m->string)); + m->string = (vm_offset_t) string; + } + + printf("RMGR: passing module %s [ 0x%x-0x%x ]\n", + mb_mod_name(mod_i), m->mod_start, m->mod_end); + + for (mod_mem = m->mod_start & L4_PAGEMASK; + mod_mem < m->mod_end; + mod_mem += L4_PAGESIZE) + { + if (! quota_check_mem(t.id.task, address, L4_PAGESIZE)) + { + printf("RMGR: ERROR: cannot allocate page at 0x%08x " + "for this task (not in quota)\n" + " skipping rest of module\n", + mod_mem); + m->mod_end = mod_mem; + boot_error(); + break; + } + + if ( ! memmap_alloc_page(mod_mem, t.id.task)) + { + printf("RMGR: ERROR: cannot allocate page at 0x%08x " + "for this task (owned by 0x%x)\n" + " skipping rest of module\n", + mod_mem, memmap_owner_page(mod_mem)); + m->mod_end = mod_mem; + boot_error(); + break; + } + } + + i2++; + mb_mod_ids[i2].lh.low = 0; + mb_mod_ids[i2].lh.high = 0; + } + + mbi->flags |= MULTIBOOT_MODS; + } + + /* copy task_trampoline PIC code to new task's stack */ + sp -= 1 + ((vm_offset_t) task_trampoline_end + - (vm_offset_t) task_trampoline) / sizeof(*sp); + memcpy(sp, task_trampoline, + (vm_offset_t) task_trampoline_end + - (vm_offset_t) task_trampoline); + entry = (dword_t) sp; + + /* setup stack for task_trampoline() */ + *--sp = (dword_t) mbi; + *--sp = exec_info.entry; + *--sp = 0; /* fake return address */ + + printf("RMGR: starting task %s (#0x%x)\n" + " at entry 0x%x via trampoline page code 0x%x\n", + name, + t.id.task, + exec_info.entry, entry); + + t = l4_task_new(t, bootquota[t.id.task].mcp, + (dword_t) sp, entry, myself); + + setup_task(t); + } +} + +/* support for loading tasks from boot modules and allocating memory + for them */ + +static int alloc_exec_read_exec(void *handle, + vm_offset_t file_ofs, vm_size_t file_size, + vm_offset_t mem_addr, vm_size_t mem_size, + exec_sectype_t section_type) +{ + vm_offset_t address; + struct exec_task *e = (struct exec_task *) handle; + + if (! (section_type & EXEC_SECTYPE_ALLOC)) + return 0; + + assert(e->task_no <= O_MAX); + + printf("0x%08x-0x%08x ", mem_addr, mem_addr + mem_size); + + for (address = mem_addr & L4_PAGEMASK; + address <= mem_addr + mem_size; + address += L4_PAGESIZE) + { + if (! quota_check_mem(e->task_no, address, L4_PAGESIZE)) + { + boot_panic("\r\nRMGR: cannot allocate page at 0x%08x: not in quota", + address); + } + + if (! memmap_alloc_page(address, e->task_no)) + { + boot_panic("\r\nRMGR: cannot allocate page at 0x%08x: owned by 0x%x", + address, memmap_owner_page(address)); + } + } + + return mod_exec_read_exec(handle, file_ofs, file_size, + mem_addr, mem_size, section_type); +} + +static int alloc_exec_read(void *handle, vm_offset_t file_ofs, + void *buf, vm_size_t size, + vm_size_t *out_actual) +{ + return mod_exec_read(handle, file_ofs, buf, size, out_actual); +} + +/* module loading support -- also used by startup.c to load the L4 + kernel -- therefore exported from here */ + +vm_offset_t mod_range_start, mod_range_end; +struct multiboot_module *mod_range_start_mod, *mod_range_end_mod; + +void mod_exec_init(struct multiboot_module *mod, + unsigned mod_first, unsigned mod_count) +{ + unsigned i; + + assert(mod_first < mod_count); + + /* compute range for modules which we must not overwrite during + booting the startup tasks */ + mod_range_start = mod[mod_first].mod_start; + mod_range_end = mod[mod_first].mod_end; + for (i = mod_first + 1; i < mod_count; i++) + { + if (mod[i].mod_start < mod_range_start) + mod_range_start = mod[i].mod_start; + if (mod[i].mod_end > mod_range_end) + mod_range_end = mod[i].mod_end; + } + + mod_range_start_mod = mod + mod_first; + mod_range_end_mod = mod + mod_count; +} + +static void +check_inside_myself(void *handle, vm_offset_t begin, vm_offset_t end) +{ + struct exec_task *e = (struct exec_task *) handle; + + if (!(begin >= (vm_offset_t)&_etext && begin <= (vm_offset_t)&_end && + end >= (vm_offset_t)&_etext && end <= (vm_offset_t)&_end)) + { + char *name; + char namebuf[40]; + + namebuf[sizeof(namebuf)-1] = 0; + name = strncpy(namebuf, mb_mod_name(e->mod_no), sizeof(namebuf)-1); + + boot_panic("\r\n" + "RMGR: not inside: %08x - %08x: %s\n" + " RMGR: %08x - %08x\n", + begin, end, name, + (vm_offset_t) &_start, (vm_offset_t) &_end); + } +} + +static inline +int overlaps_range(vm_offset_t tst_begin, vm_offset_t tst_end, + vm_offset_t mem_begin, vm_offset_t mem_end) +{ + return !((tst_begin <= mem_begin && tst_end <= mem_begin) + || (tst_begin >= mem_end && tst_end >= mem_end)); +} + +static int +overlaps_myself(vm_offset_t begin, vm_offset_t end) +{ + struct multiboot_module *mod; + + if (overlaps_range(begin, end, (vm_offset_t)&_start, (vm_offset_t)&_end)) + return 1; + + for (mod = mod_range_start_mod; mod != mod_range_end_mod; mod++) + if (overlaps_range(begin, end, mod->mod_start, mod->mod_end)) + return 1; + + return 0; +} + +static void +check_overlaps_myself(void *handle, vm_offset_t begin, vm_offset_t end) +{ + struct exec_task *e = (struct exec_task *) handle; + int overlaps; + + if ((overlaps=overlaps_myself(begin, end)) + || (begin >= mem_high) || (end >= mem_high)) + { + int i; + char *name, *errstr; + char namebuf[45]; + + namebuf[sizeof(namebuf)-1] = 0; + name = strncpy(namebuf, mb_mod_name(e->mod_no), sizeof(namebuf)-1); + + errstr = (overlaps) ? "overlaps" : "> memory"; + printf("\nRMGR: %s: %08x-%08x: %s\n" + " RMGR: %08x-%08x\n", + errstr, begin, end, name, + (vm_offset_t) &_start, (vm_offset_t) &_end); + + for (i=first_task_module; i + +#include "exec.h" + +#define INIT_SECTION __attribute__((section (".init"))) + +void init(void) L4_NORETURN; +int have_hercules(void); + +/* the following variables may only by used during boot -- their + storage is freed after initialization in init.c */ + +extern int boot_errors, boot_wait; +void boot_error(void); +void boot_fatal(void); +const char *mb_mod_name(int i); +const char *owner_name(owner_t owner); + +#define MODS_MAX 20 +extern struct multiboot_module mb_mod[MODS_MAX]; +extern struct vbe_controller mb_vbe_cont; +extern struct vbe_mode mb_vbe_mode; + +extern vm_offset_t mod_range_start, mod_range_end; + +void mod_exec_init(struct multiboot_module *mod, + unsigned mod_first, unsigned mod_count); + +exec_read_func_t mod_exec_read; +exec_read_exec_func_t mod_exec_read_exec; + +struct exec_task +{ + void *mod_start; + unsigned mod_no; + unsigned task_no; +}; + +extern int boot_errors; +extern int boot_wait; +extern int error_stop; +extern int hercules; +extern int boot_mem_dump; +extern int kernel_running; +extern int last_task_module; + +extern int l4_version; +#define VERSION_L4_V2 0 +#define VERSION_L4_IBM 1 +#define VERSION_FIASCO 2 +#define VERSION_L4_KA 3 +#define VERSION_PISTACHIO 4 + +#define KERNEL_NAMES ((char*[5]) { "L4/GMD", "LN/IBM", "FIASCO", "L4/Ka", "L4Ka/Pistachio" }) + +#endif + diff --git a/apps/rmgr/src/irq.c b/apps/rmgr/src/irq.c new file mode 100644 index 0000000..3abf4a3 --- /dev/null +++ b/apps/rmgr/src/irq.c @@ -0,0 +1,119 @@ +#include + +#include "globals.h" + +#include "irq.h" + +owner_t __irq[IRQ_MAX]; +char __irq_stacks[IRQ_MAX * __IRQ_STACKSIZE]; + +static int irq_attach(unsigned irq); +static int irq_detach(unsigned irq); + +void __irq_thread(unsigned irq) +{ + dword_t d1, d2; + l4_msgdope_t result; + int err; + l4_threadid_t t; + + int is_failure = 1, is_attached = 0; + + /* first, register to the irq */ + if (irq_attach(irq)) + { + /* success! */ + is_failure = 0; + is_attached = 1; + } + + /* shake hands with the main thread who started and initialized us */ + err = l4_i386_ipc_reply_and_wait(myself, L4_IPC_SHORT_MSG, is_failure, 0, + &t, L4_IPC_SHORT_MSG, &d1, &d2, + L4_IPC_NEVER, &result); + + for (;;) + { + while (! err) + { + if (t.id.task != myself.id.task) + break; /* silently drop the request */ + + d1 = d2 = (dword_t) -1; + + if (is_failure && d1) + { + /* we couldn't attach previous time -- try again */ + if (irq_attach(irq)) + { + is_failure = 0; + is_attached = 1; + } + } + + if (! is_failure) + { + if (is_attached && d1) + { + d1 = irq_detach(irq) ? 0 : 1; + } + else if (!is_attached && !d1) + { + d1 = irq_attach(irq) ? 0 : 1; + if (d1) + is_failure = 1; + } + } + + err = l4_i386_ipc_reply_and_wait(t, L4_IPC_SHORT_MSG, d1, d2, + &t, L4_IPC_SHORT_MSG, &d1, &d2, + L4_IPC_NEVER, &result); + } + + err = l4_i386_ipc_wait(&t, L4_IPC_SHORT_MSG, &d1, &d2, + L4_IPC_NEVER, &result); + + } +} + +static int irq_attach(unsigned irq) +{ + dword_t dummy; + int err; + l4_msgdope_t result; + l4_threadid_t irq_th; + + /* first, register to the irq */ +#ifdef __L4_STANDARD__ + irq_th.lh.low = irq + 1; + irq_th.lh.high = 0; +#else +# ifdef __L4_VERSION_X__ + irq_th.raw = irq + 1; +# else +# warning undefined L4 version +# endif +#endif + + err = l4_i386_ipc_receive(irq_th, L4_IPC_SHORT_MSG, + &dummy, &dummy, + L4_IPC_TIMEOUT(0,0,0,1,0,0), /* rcv = 0, + snd = inf */ + &result); + + return (err == L4_IPC_RETIMEOUT); +} + +static int irq_detach(unsigned irq) +{ + dword_t dummy; + l4_msgdope_t result; + + l4_i386_ipc_receive(L4_NIL_ID, + L4_IPC_SHORT_MSG, &dummy, &dummy, + L4_IPC_TIMEOUT(0,0,0,1,0,0), /* rcv = 0, + snd = inf */ + &result); + + return 1; +} diff --git a/apps/rmgr/src/irq.h b/apps/rmgr/src/irq.h new file mode 100644 index 0000000..857ebec --- /dev/null +++ b/apps/rmgr/src/irq.h @@ -0,0 +1,57 @@ +#ifndef IRQ_H +#define IRQ_H + +#include + +#include + +#include "globals.h" +#include "quota.h" + +L4_INLINE void irq_init(void); +L4_INLINE int irq_alloc(unsigned irqno, owner_t owner); +L4_INLINE int irq_free(unsigned irqno, owner_t owner); + +#define IRQ_MAX (16) + +extern owner_t __irq[IRQ_MAX]; + +#define __IRQ_STACKSIZE (256) +extern char __irq_stacks[IRQ_MAX * __IRQ_STACKSIZE]; +void __irq_thread(unsigned irq) L4_NORETURN; + + +L4_INLINE void irq_init(void) +{ + memset(__irq, O_RESERVED, IRQ_MAX); +} + +L4_INLINE int irq_alloc(unsigned irqno, owner_t owner) +{ + if (__irq[irqno] == owner) + return 1; + if (__irq[irqno] != O_FREE) + return 0; + + if (! quota_alloc_irq(owner, irqno)) + return 0; + + __irq[irqno] = owner; + return 1; +} + +L4_INLINE int irq_free(unsigned irqno, owner_t owner) +{ + if (__irq[irqno] != owner && __irq[irqno] != O_FREE) + return 0; + + if (__irq[irqno] != O_FREE) + { + quota_free_irq(owner, irqno); + __irq[irqno] = O_FREE; + } + + return 1; +} + +#endif diff --git a/apps/rmgr/src/libpci-compat.c b/apps/rmgr/src/libpci-compat.c new file mode 100644 index 0000000..a876e3c --- /dev/null +++ b/apps/rmgr/src/libpci-compat.c @@ -0,0 +1,24 @@ +#define __KERNEL__ +#define __L4__ +#define CONFIG_PCI +#define CONFIG_PCI_BIOS + +#include "libpci-compat.h" + +static int libpci_compat_pcidev = 0; +static int libpci_compat_pcibus = 0; + +static struct pci_dev libpci_compat_pcidevs[libpci_compat_MAX_DEV]; +static struct pci_bus libpci_compat_pcibuss[libpci_compat_MAX_BUS]; +void* libpci_compat_kmalloc(int size) +{ + if ((size == sizeof(struct pci_dev)) && + (libpci_compat_pcidev < libpci_compat_MAX_DEV)) + return &libpci_compat_pcidevs[libpci_compat_pcidev++]; + if ((size == sizeof(struct pci_bus)) && + (libpci_compat_pcibus < libpci_compat_MAX_BUS)) + return &libpci_compat_pcibuss[libpci_compat_pcibus++]; + printf(__FUNCTION__" failed\n"); + return 0; +}; + diff --git a/apps/rmgr/src/libpci-compat.h b/apps/rmgr/src/libpci-compat.h new file mode 100644 index 0000000..4ccb868 --- /dev/null +++ b/apps/rmgr/src/libpci-compat.h @@ -0,0 +1,41 @@ +#define __KERNEL__ +#define __L4__ +#define CONFIG_PCI +#define CONFIG_PCI_BIOS + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#if 0 +#include "l4/pci/libpci.h" +#else /* 0 */ +#include "libpci.h" +#endif /* 0 */ +#include + +#define printk(args...) printf(args) +#define pcilock() +#define spin_lock_irqsave(a,b) +#define spin_unlock_irqrestore(a,b) +#define __initfunc(a) a +#define __initdata +#define __save_flags(x) +#define __restore_flags(x) +#define __cli() +#define __sti() +#define PAGE_OFFSET 0 +#define KERN_ERR +#define GFP_KERNEL 0 +#define GFP_ATOMIC 0 +#define NR_IRQS 224 +#define __va(a) a +#define pcibios_fixup() +#define pcibios_fixup_bus(x) + +#define kmalloc(x,y) libpci_compat_kmalloc(x) + +#define libpci_compat_MAX_DEV 16 +#define libpci_compat_MAX_BUS 2 + +extern void* libpci_compat_kmalloc(int size); diff --git a/apps/rmgr/src/libpci.c b/apps/rmgr/src/libpci.c new file mode 100644 index 0000000..a794aca --- /dev/null +++ b/apps/rmgr/src/libpci.c @@ -0,0 +1,439 @@ +#define __KERNEL__ +#define __L4__ +#define CONFIG_PCI +#define CONFIG_PCI_BIOS + +/* + * $Id: libpci.c,v 1.1 2000/02/21 19:16:58 uhlig Exp $ + * + * PCI Bus Services, see include/linux/pci.h for further explanation. + * + * Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter, + * David Mosberger-Tang + * + * Copyright 1997 -- 1998 Martin Mares + */ + +#if 0 + +#include +#include +#include +#include +#include +#include +#include + +#include + +#else + +#include "libpci-compat.h" +#include +#endif + +#define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +struct pci_bus pci_root; +#ifdef CONFIG_VISWS +struct pci_bus pci_other; +#endif +struct pci_dev *pci_devices = NULL; +static struct pci_dev **pci_last_dev_p = &pci_devices; +static int pci_reverse __initdata = 0; + +struct pci_dev * +pci_find_slot(unsigned int bus, unsigned int devfn) +{ + struct pci_dev *dev; + + for(dev=pci_devices; dev; dev=dev->next) + if (dev->bus->number == bus && dev->devfn == devfn) + break; + return dev; +} + + +struct pci_dev * +pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from) +{ + if (!from) + from = pci_devices; + else + from = from->next; + while (from && (from->vendor != vendor || from->device != device)) + from = from->next; + return from; +} + + +struct pci_dev * +pci_find_class(unsigned int class, struct pci_dev *from) +{ + if (!from) + from = pci_devices; + else + from = from->next; + while (from && from->class != class) + from = from->next; + return from; +} + + +int +pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val) +{ + return pcibios_read_config_byte(dev->bus->number, dev->devfn, where, val); +} + +int +pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val) +{ + return pcibios_read_config_word(dev->bus->number, dev->devfn, where, val); +} + +int +pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val) +{ + return pcibios_read_config_dword(dev->bus->number, dev->devfn, where, val); +} + +int +pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val) +{ + return pcibios_write_config_byte(dev->bus->number, dev->devfn, where, val); +} + +int +pci_write_config_word(struct pci_dev *dev, u8 where, u16 val) +{ + return pcibios_write_config_word(dev->bus->number, dev->devfn, where, val); +} + +int +pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val) +{ + return pcibios_write_config_dword(dev->bus->number, dev->devfn, where, val); +} + + +void +pci_set_master(struct pci_dev *dev) +{ + u16 cmd; + u8 lat; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (! (cmd & PCI_COMMAND_MASTER)) { + printk("PCI: Enabling bus mastering for device %02x:%02x\n", + dev->bus->number, dev->devfn); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) { + printk("PCI: Increasing latency timer of device %02x:%02x to 64\n", + dev->bus->number, dev->devfn); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + } +} + +__initfunc(void pci_read_bases(struct pci_dev *dev, unsigned int howmany)) +{ + unsigned int reg; + u32 l; + + for(reg=0; regbase_address[reg] = l; + if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) + == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { + reg++; + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l); + if (l) { +#if BITS_PER_LONG == 64 + dev->base_address[reg-1] |= ((unsigned long) l) << 32; +#else + printk("PCI: Unable to handle 64-bit address for device %02x:%02x\n", + dev->bus->number, dev->devfn); + dev->base_address[reg-1] = 0; +#endif + } + } + } +} + + +__initfunc(unsigned int pci_scan_bus(struct pci_bus *bus)) +{ + unsigned int devfn, l, max, class; + unsigned char cmd, irq, tmp, hdr_type, is_multi = 0; + struct pci_dev *dev, **bus_last; + struct pci_bus *child; + + DBG("pci_scan_bus for bus %d\n", bus->number); + bus_last = &bus->devices; + max = bus->secondary; + for (devfn = 0; devfn < 0xff; ++devfn) { + if (PCI_FUNC(devfn) && !is_multi) { + /* not a multi-function device */ + continue; + } + if (pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type)) + continue; + if (!PCI_FUNC(devfn)) + is_multi = hdr_type & 0x80; + + if (pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l) || + /* some broken boards return 0 if a slot is empty: */ + l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) { + is_multi = 0; + continue; + } + + dev = kmalloc(sizeof(*dev), GFP_ATOMIC); + memset(dev, 0, sizeof(*dev)); + dev->bus = bus; + dev->devfn = devfn; + dev->vendor = l & 0xffff; + dev->device = (l >> 16) & 0xffff; + + /* non-destructively determine if device can be a master: */ + pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &cmd); + pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND, &tmp); + dev->master = ((tmp & PCI_COMMAND_MASTER) != 0); + pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND, cmd); + + pcibios_read_config_dword(bus->number, devfn, PCI_CLASS_REVISION, &class); + class >>= 8; /* upper 3 bytes */ + dev->class = class; + class >>= 8; + dev->hdr_type = hdr_type; + + switch (hdr_type & 0x7f) { /* header type */ + case PCI_HEADER_TYPE_NORMAL: /* standard header */ + if (class == PCI_CLASS_BRIDGE_PCI) + goto bad; + /* + * If the card generates interrupts, read IRQ number + * (some architectures change it during pcibios_fixup()) + */ + pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_PIN, &irq); + if (irq) + pcibios_read_config_byte(bus->number, dev->devfn, PCI_INTERRUPT_LINE, &irq); + dev->irq = irq; + /* + * read base address registers, again pcibios_fixup() can + * tweak these + */ + pci_read_bases(dev, 6); + pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS, &l); + dev->rom_address = (l == 0xffffffff) ? 0 : l; + break; + case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ + if (class != PCI_CLASS_BRIDGE_PCI) + goto bad; + pci_read_bases(dev, 2); + pcibios_read_config_dword(bus->number, devfn, PCI_ROM_ADDRESS1, &l); + dev->rom_address = (l == 0xffffffff) ? 0 : l; + break; + case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ + if (class != PCI_CLASS_BRIDGE_CARDBUS) + goto bad; + pci_read_bases(dev, 1); + break; + default: /* unknown header */ + bad: + printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n", + bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type); + continue; + } + + DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device); + + /* + * Put it into the global PCI device chain. It's used to + * find devices once everything is set up. + */ + if (!pci_reverse) { + *pci_last_dev_p = dev; + pci_last_dev_p = &dev->next; + } else { + dev->next = pci_devices; + pci_devices = dev; + } + + /* + * Now insert it into the list of devices held + * by the parent bus. + */ + *bus_last = dev; + bus_last = &dev->sibling; + +#if 0 + /* + * Setting of latency timer in case it was less than 32 was + * a great idea, but it confused several broken devices. Grrr. + */ + pcibios_read_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, &tmp); + if (tmp < 32) + pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, 32); +#endif + } + + /* + * After performing arch-dependent fixup of the bus, look behind + * all PCI-to-PCI bridges on this bus. + */ + pcibios_fixup_bus(bus); + for(dev=bus->devices; dev; dev=dev->sibling) + /* + * If it's a bridge, scan the bus behind it. + */ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + unsigned int buses; + unsigned int devfn = dev->devfn; + unsigned short cr; + + /* + * Insert it into the tree of buses. + */ + child = kmalloc(sizeof(*child), GFP_ATOMIC); + memset(child, 0, sizeof(*child)); + child->next = bus->children; + bus->children = child; + child->self = dev; + child->parent = bus; + + /* + * Set up the primary, secondary and subordinate + * bus numbers. + */ + child->number = child->secondary = ++max; + child->primary = bus->secondary; + child->subordinate = 0xff; + /* + * Clear all status bits and turn off memory, + * I/O and master enables. + */ + pcibios_read_config_word(bus->number, devfn, PCI_COMMAND, &cr); + pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000); + pcibios_write_config_word(bus->number, devfn, PCI_STATUS, 0xffff); + /* + * Read the existing primary/secondary/subordinate bus + * number configuration to determine if the PCI bridge + * has already been configured by the system. If so, + * do not modify the configuration, merely note it. + */ + pcibios_read_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, &buses); + if ((buses & 0xFFFFFF) != 0) + { + unsigned int cmax; + + child->primary = buses & 0xFF; + child->secondary = (buses >> 8) & 0xFF; + child->subordinate = (buses >> 16) & 0xFF; + child->number = child->secondary; + cmax = pci_scan_bus(child); + if (cmax > max) max = cmax; + } + else + { + /* + * Configure the bus numbers for this bridge: + */ + buses &= 0xff000000; + buses |= + (((unsigned int)(child->primary) << 0) | + ((unsigned int)(child->secondary) << 8) | + ((unsigned int)(child->subordinate) << 16)); + pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses); + /* + * Now we can scan all subordinate buses: + */ + max = pci_scan_bus(child); + /* + * Set the subordinate bus number to its real + * value: + */ + child->subordinate = max; + buses = (buses & 0xff00ffff) + | ((unsigned int)(child->subordinate) << 16); + pcibios_write_config_dword(bus->number, devfn, PCI_PRIMARY_BUS, buses); + } + pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr); + } + + /* + * We've scanned the bus and so we know all about what's on + * the other side of any bridges that may be on this bus plus + * any devices. + * + * Return how far we've got finding sub-buses. + */ + DBG("PCI: pci_scan_bus returning with max=%02x\n", max); + return max; +} + + +static int _pci_is_initialized = 0; +__initfunc(void pci_init(void)) +{ + if (_pci_is_initialized++) + return; + + pcibios_init(); + + if (!pci_present()) { + printk("PCI: No PCI bus detected\n"); + return; + } + + printk("PCI: Probing PCI hardware\n"); + + memset(&pci_root, 0, sizeof(pci_root)); + pci_root.subordinate = pci_scan_bus(&pci_root); +#ifdef CONFIG_VISWS + pci_other.number = 1; /* XXX unless bridge(s) on pci_root */ + pci_other.subordinate = pci_scan_bus(&pci_other); + pci_root.next = &pci_other; +#endif + + /* give BIOS a chance to apply platform specific fixes: */ + pcibios_fixup(); + +#ifdef CONFIG_PCI_QUIRKS + pci_quirks_init(); +#endif + +#ifdef CONFIG_PROC_FS + pci_proc_init(); +#endif +} + + +#if !defined(__L4__) +__initfunc(void pci_setup (char *str, int *ints)) +{ + while (str) { + char *k = strchr(str, ','); + if (k) + *k++ = 0; + if (*str && (str = pcibios_setup(str)) && *str) { + if (!strcmp(str, "reverse")) + pci_reverse = 1; + else printk(KERN_ERR "PCI: Unknown option `%s'\n", str); + } + str = k; + } +} +#endif diff --git a/apps/rmgr/src/libpci.h b/apps/rmgr/src/libpci.h new file mode 100644 index 0000000..df75c52 --- /dev/null +++ b/apps/rmgr/src/libpci.h @@ -0,0 +1,1325 @@ +/* + * $Id: libpci.h,v 1.1 2000/02/21 19:16:58 uhlig Exp $ + * + * PCI defines and function prototypes + * Copyright 1994, Drew Eckhardt + * Copyright 1997, 1998 Martin Mares + * + * For more information, please consult the following manuals (look at + * http://www.pcisig.com/ for how to get them): + * + * PCI BIOS Specification + * PCI Local Bus Specification + * PCI to PCI Bridge Specification + * PCI System Design Guide + */ + +#if !defined(__KERNEL__) +#define _WASNOTDEFINED___KERNEL__ +#define __KERNEL__ +#define u8 unsigned char +#define u16 unsigned short +#define u32 unsigned int +#endif + +#if !defined(__L4__) +#define _WASNOTDEFINED___L4__ +#define __L4__ +#endif + +#if !defined(CONFIG_PCI) +#define _WASNOTDEFINED_CONFIG_PCI +#define CONFIG_PCI +#endif + +#if !defined(CONFIG_PCI_GOANY) +#define _WASNOTDEFINED_CONFIG_PCI_GOANY +#define CONFIG_PCI_GOANY +#endif + +#if !defined(CONFIG_PCI_BIOS) +#define _WASNOTDEFINED_CONFIG_PCI_BIOS +#define CONFIG_PCI_BIOS +#endif + + +#ifndef LINUX_PCI_H +#define LINUX_PCI_H + +/* + * Under PCI, each device has 256 bytes of configuration address space, + * of which the first 64 bytes are standardized as follows: + */ +#define PCI_VENDOR_ID 0x00 /* 16 bits */ +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_COMMAND 0x04 /* 16 bits */ +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ + +#define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features */ + +#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ +#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ +#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ +#define PCI_STATUS_DEVSEL_FAST 0x000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define PCI_STATUS_DEVSEL_SLOW 0x400 +#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ +#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ +#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ +#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ +#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ + +#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 + revision */ +#define PCI_REVISION_ID 0x08 /* Revision ID */ +#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ +#define PCI_CLASS_DEVICE 0x0a /* Device class */ + +#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ +#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ +#define PCI_HEADER_TYPE 0x0e /* 8 bits */ +#define PCI_HEADER_TYPE_NORMAL 0 +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_CARDBUS 2 + +#define PCI_BIST 0x0f /* 8 bits */ +#define PCI_BIST_CODE_MASK 0x0f /* Return result */ +#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ +#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ + +/* + * Base addresses specify locations in memory or I/O space. + * Decoded size can be determined by writing a value of + * 0xffffffff to the register, and reading it back. Only + * 1 bits are decoded. + */ +#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ +#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ +#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */ +#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ +#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ +#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +/* bit 1 is reserved if address_space = 1 */ + +/* Header type 0 (normal devices) */ +#define PCI_CARDBUS_CIS 0x28 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define PCI_SUBSYSTEM_ID 0x2e +#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved +*/ +#define PCI_ROM_ADDRESS_ENABLE 0x01 +#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) + +/* 0x34-0x3b are reserved */ +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ +#define PCI_MIN_GNT 0x3e /* 8 bits */ +#define PCI_MAX_LAT 0x3f /* 8 bits */ + +/* Header type 1 (PCI-to-PCI bridges) */ +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ +#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ +#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ +#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */ +#define PCI_IO_RANGE_TYPE_16 0x00 +#define PCI_IO_RANGE_TYPE_32 0x01 +#define PCI_IO_RANGE_MASK ~0x0f +#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 +used */ +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f +#define PCI_MEMORY_RANGE_MASK ~0x0f +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ +#define PCI_PREF_MEMORY_LIMIT 0x26 +#define PCI_PREF_RANGE_TYPE_MASK 0x0f +#define PCI_PREF_RANGE_TYPE_32 0x00 +#define PCI_PREF_RANGE_TYPE_64 0x01 +#define PCI_PREF_RANGE_MASK ~0x0f +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ +#define PCI_PREF_LIMIT_UPPER32 0x2c +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ +#define PCI_IO_LIMIT_UPPER16 0x32 +/* 0x34-0x3b is reserved */ +#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */ +/* 0x3c-0x3d are same as for htype 0 */ +#define PCI_BRIDGE_CONTROL 0x3e +#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary +interface */ +#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */ +#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */ +#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */ +#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */ +#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */ +#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface +*/ + +/* Header type 2 (CardBus bridges) */ +/* 0x14-0x15 reserved */ +#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */ +#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */ +#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */ +#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */ +#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */ +#define PCI_CB_MEMORY_BASE_0 0x1c +#define PCI_CB_MEMORY_LIMIT_0 0x20 +#define PCI_CB_MEMORY_BASE_1 0x24 +#define PCI_CB_MEMORY_LIMIT_1 0x28 +#define PCI_CB_IO_BASE_0 0x2c +#define PCI_CB_IO_BASE_0_HI 0x2e +#define PCI_CB_IO_LIMIT_0 0x30 +#define PCI_CB_IO_LIMIT_0_HI 0x32 +#define PCI_CB_IO_BASE_1 0x34 +#define PCI_CB_IO_BASE_1_HI 0x36 +#define PCI_CB_IO_LIMIT_1 0x38 +#define PCI_CB_IO_LIMIT_1_HI 0x3a +#define PCI_CB_IO_RANGE_MASK ~0x03 +/* 0x3c-0x3d are same as for htype 0 */ +#define PCI_CB_BRIDGE_CONTROL 0x3e +#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control +register */ +#define PCI_CB_BRIDGE_CTL_SERR 0x02 +#define PCI_CB_BRIDGE_CTL_ISA 0x04 +#define PCI_CB_BRIDGE_CTL_VGA 0x08 +#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20 +#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */ +#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */ +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory +regions */ +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 +#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 +#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40 +#define PCI_CB_SUBSYSTEM_ID 0x42 +#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address +(ExCa) */ +/* 0x48-0x7f reserved */ + +/* Device classes and subclasses */ + +#define PCI_CLASS_NOT_DEFINED 0x0000 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_CLASS_STORAGE_SCSI 0x0100 +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102 +#define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_OTHER 0x0180 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 +#define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 +#define PCI_CLASS_NETWORK_OTHER 0x0280 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_XGA 0x0301 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_CLASS_MEMORY_RAM 0x0500 +#define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_OTHER 0x0580 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_BRIDGE_EISA 0x0602 +#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 +#define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_CLASS_DOCKING_GENERIC 0x0a00 +#define PCI_CLASS_DOCKING_OTHER 0x0a01 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_PROCESSOR_386 0x0b00 +#define PCI_CLASS_PROCESSOR_486 0x0b01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 +#define PCI_CLASS_PROCESSOR_CO 0x0b40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01 +#define PCI_CLASS_SERIAL_SSA 0x0c02 +#define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_FIBER 0x0c04 + +#define PCI_CLASS_OTHERS 0xff + +/* + * Vendor and card ID's: sort these numerically according to vendor + * (and according to card ID within vendor). Send all updates to + * . + */ +#define PCI_VENDOR_ID_COMPAQ 0x0e11 +#define PCI_DEVICE_ID_COMPAQ_1280 0x3033 +#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000 +#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 +#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 +#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35 +#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40 +#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43 +#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011 +#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150 + +#define PCI_VENDOR_ID_NCR 0x1000 +#define PCI_DEVICE_ID_NCR_53C810 0x0001 +#define PCI_DEVICE_ID_NCR_53C820 0x0002 +#define PCI_DEVICE_ID_NCR_53C825 0x0003 +#define PCI_DEVICE_ID_NCR_53C815 0x0004 +#define PCI_DEVICE_ID_NCR_53C860 0x0006 +#define PCI_DEVICE_ID_NCR_53C896 0x000b +#define PCI_DEVICE_ID_NCR_53C895 0x000c +#define PCI_DEVICE_ID_NCR_53C885 0x000d +#define PCI_DEVICE_ID_NCR_53C875 0x000f +#define PCI_DEVICE_ID_NCR_53C875J 0x008f + +#define PCI_VENDOR_ID_ATI 0x1002 +#define PCI_DEVICE_ID_ATI_68800 0x4158 +#define PCI_DEVICE_ID_ATI_215CT222 0x4354 +#define PCI_DEVICE_ID_ATI_210888CX 0x4358 +#define PCI_DEVICE_ID_ATI_215GB 0x4742 +#define PCI_DEVICE_ID_ATI_215GD 0x4744 +#define PCI_DEVICE_ID_ATI_215GI 0x4749 +#define PCI_DEVICE_ID_ATI_215GP 0x4750 +#define PCI_DEVICE_ID_ATI_215GQ 0x4751 +#define PCI_DEVICE_ID_ATI_215GT 0x4754 +#define PCI_DEVICE_ID_ATI_215GTB 0x4755 +#define PCI_DEVICE_ID_ATI_210888GX 0x4758 +#define PCI_DEVICE_ID_ATI_215LG 0x4c47 +#define PCI_DEVICE_ID_ATI_264LT 0x4c54 +#define PCI_DEVICE_ID_ATI_264VT 0x5654 + +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_DEVICE_ID_VLSI_82C592 0x0005 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006 +#define PCI_DEVICE_ID_VLSI_82C594 0x0007 +#define PCI_DEVICE_ID_VLSI_82C597 0x0009 +#define PCI_DEVICE_ID_VLSI_82C541 0x000c +#define PCI_DEVICE_ID_VLSI_82C543 0x000d +#define PCI_DEVICE_ID_VLSI_82C532 0x0101 +#define PCI_DEVICE_ID_VLSI_82C534 0x0102 +#define PCI_DEVICE_ID_VLSI_82C535 0x0104 +#define PCI_DEVICE_ID_VLSI_82C147 0x0105 +#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 + +#define PCI_VENDOR_ID_ADL 0x1005 +#define PCI_DEVICE_ID_ADL_2301 0x2301 + +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_87415 0x0002 +#define PCI_DEVICE_ID_NS_87410 0xd001 + +#define PCI_VENDOR_ID_TSENG 0x100c +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 +#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 +#define PCI_DEVICE_ID_TSENG_ET6000 0x3208 + +#define PCI_VENDOR_ID_WEITEK 0x100e +#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 +#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 + +#define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_BRD 0x0001 +#define PCI_DEVICE_ID_DEC_TULIP 0x0002 +#define PCI_DEVICE_ID_DEC_TGA 0x0004 +#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 +#define PCI_DEVICE_ID_DEC_TGA2 0x000D +#define PCI_DEVICE_ID_DEC_FDDI 0x000F +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21142 0x0019 +#define PCI_DEVICE_ID_DEC_21052 0x0021 +#define PCI_DEVICE_ID_DEC_21150 0x0022 +#define PCI_DEVICE_ID_DEC_21152 0x0024 + +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#define PCI_DEVICE_ID_CIRRUS_7548 0x0038 +#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 +#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac +#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8 +#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc +#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4 +#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#define PCI_DEVICE_ID_CIRRUS_6832 0x1110 +#define PCI_DEVICE_ID_CIRRUS_7542 0x1200 +#define PCI_DEVICE_ID_CIRRUS_7543 0x1202 +#define PCI_DEVICE_ID_CIRRUS_7541 0x1204 + +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a +#define PCI_DEVICE_ID_IBM_TR 0x0018 +#define PCI_DEVICE_ID_IBM_82G2675 0x001d +#define PCI_DEVICE_ID_IBM_MCA 0x0020 +#define PCI_DEVICE_ID_IBM_82351 0x0022 +#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e +#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e +#define PCI_DEVICE_ID_IBM_MPIC 0x0046 +#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d +#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff + +#define PCI_VENDOR_ID_WD 0x101c +#define PCI_DEVICE_ID_WD_7197 0x3296 + +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020 + +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_DEVICE_ID_TRIDENT_9397 0x9397 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 +#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 +#define PCI_DEVICE_ID_TRIDENT_9660 0x9660 +#define PCI_DEVICE_ID_TRIDENT_9750 0x9750 + +#define PCI_VENDOR_ID_AI 0x1025 +#define PCI_DEVICE_ID_AI_M1435 0x1435 + +#define PCI_VENDOR_ID_MATROX 0x102B +#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 +#define PCI_DEVICE_ID_MATROX_MIL 0x0519 +#define PCI_DEVICE_ID_MATROX_MYS 0x051A +#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b +#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f +#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 +#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 +#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 +#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000 +#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001 + +#define PCI_VENDOR_ID_CT 0x102c +#define PCI_DEVICE_ID_CT_65545 0x00d8 +#define PCI_DEVICE_ID_CT_65548 0x00dc +#define PCI_DEVICE_ID_CT_65550 0x00e0 +#define PCI_DEVICE_ID_CT_65554 0x00e4 +#define PCI_DEVICE_ID_CT_65555 0x00e5 + +#define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_DEVICE_ID_MIRO_36050 0x5601 + +#define PCI_VENDOR_ID_NEC 0x1033 +#define PCI_DEVICE_ID_NEC_PCX2 0x0046 + +#define PCI_VENDOR_ID_FD 0x1036 +#define PCI_DEVICE_ID_FD_36C70 0x0000 + +#define PCI_VENDOR_ID_SI 0x1039 +#define PCI_DEVICE_ID_SI_5591_AGP 0x0001 +#define PCI_DEVICE_ID_SI_6202 0x0002 +#define PCI_DEVICE_ID_SI_503 0x0008 +#define PCI_DEVICE_ID_SI_ACPI 0x0009 +#define PCI_DEVICE_ID_SI_5597_VGA 0x0200 +#define PCI_DEVICE_ID_SI_6205 0x0205 +#define PCI_DEVICE_ID_SI_501 0x0406 +#define PCI_DEVICE_ID_SI_496 0x0496 +#define PCI_DEVICE_ID_SI_601 0x0601 +#define PCI_DEVICE_ID_SI_5107 0x5107 +#define PCI_DEVICE_ID_SI_5511 0x5511 +#define PCI_DEVICE_ID_SI_5513 0x5513 +#define PCI_DEVICE_ID_SI_5571 0x5571 +#define PCI_DEVICE_ID_SI_5591 0x5591 +#define PCI_DEVICE_ID_SI_5597 0x5597 +#define PCI_DEVICE_ID_SI_7001 0x7001 + +#define PCI_VENDOR_ID_HP 0x103c +#define PCI_DEVICE_ID_HP_J2585A 0x1030 +#define PCI_DEVICE_ID_HP_J2585B 0x1031 + +#define PCI_VENDOR_ID_PCTECH 0x1042 +#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 +#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 + +#define PCI_VENDOR_ID_DPT 0x1044 +#define PCI_DEVICE_ID_DPT 0xa400 + +#define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_DEVICE_ID_OPTI_92C178 0xc178 +#define PCI_DEVICE_ID_OPTI_82C557 0xc557 +#define PCI_DEVICE_ID_OPTI_82C558 0xc558 +#define PCI_DEVICE_ID_OPTI_82C621 0xc621 +#define PCI_DEVICE_ID_OPTI_82C700 0xc700 +#define PCI_DEVICE_ID_OPTI_82C701 0xc701 +#define PCI_DEVICE_ID_OPTI_82C814 0xc814 +#define PCI_DEVICE_ID_OPTI_82C822 0xc822 +#define PCI_DEVICE_ID_OPTI_82C861 0xc861 +#define PCI_DEVICE_ID_OPTI_82C825 0xd568 + +#define PCI_VENDOR_ID_SGS 0x104a +#define PCI_DEVICE_ID_SGS_2000 0x0008 +#define PCI_DEVICE_ID_SGS_1764 0x0009 + +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 + +#define PCI_VENDOR_ID_TI 0x104c +#define PCI_DEVICE_ID_TI_TVP4010 0x3d04 +#define PCI_DEVICE_ID_TI_TVP4020 0x3d07 +#define PCI_DEVICE_ID_TI_PCI1130 0xac12 +#define PCI_DEVICE_ID_TI_PCI1031 0xac13 +#define PCI_DEVICE_ID_TI_PCI1131 0xac15 +#define PCI_DEVICE_ID_TI_PCI1250 0xac16 +#define PCI_DEVICE_ID_TI_PCI1220 0xac17 + +#define PCI_VENDOR_ID_OAK 0x104e +#define PCI_DEVICE_ID_OAK_OTI107 0x0107 + +/* Winbond have two vendor IDs! See 0x10ad as well */ +#define PCI_VENDOR_ID_WINBOND2 0x1050 +#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940 + +#define PCI_VENDOR_ID_MOTOROLA 0x1057 +#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 +#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 +#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 + +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_DEVICE_ID_PROMISE_20246 0x4d33 +#define PCI_DEVICE_ID_PROMISE_5300 0x5300 + +#define PCI_VENDOR_ID_N9 0x105d +#define PCI_DEVICE_ID_N9_I128 0x2309 +#define PCI_DEVICE_ID_N9_I128_2 0x2339 +#define PCI_DEVICE_ID_N9_I128_T2R 0x493d + +#define PCI_VENDOR_ID_UMC 0x1060 +#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 +#define PCI_DEVICE_ID_UMC_UM8891A 0x0891 +#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a +#define PCI_DEVICE_ID_UMC_UM8886A 0x886a +#define PCI_DEVICE_ID_UMC_UM8881F 0x8881 +#define PCI_DEVICE_ID_UMC_UM8886F 0x8886 +#define PCI_DEVICE_ID_UMC_UM9017F 0x9017 +#define PCI_DEVICE_ID_UMC_UM8886N 0xe886 +#define PCI_DEVICE_ID_UMC_UM8891N 0xe891 + +#define PCI_VENDOR_ID_X 0x1061 +#define PCI_DEVICE_ID_X_AGX016 0x0001 + +#define PCI_VENDOR_ID_PICOP 0x1066 +#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 +#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002 + +#define PCI_VENDOR_ID_APPLE 0x106b +#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 +#define PCI_DEVICE_ID_APPLE_GC 0x0002 +#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e + +#define PCI_VENDOR_ID_NEXGEN 0x1074 +#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78 + +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 +#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022 +#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 + +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_DEVICE_ID_CYRIX_5510 0x0000 +#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 +#define PCI_DEVICE_ID_CYRIX_5520 0x0002 +#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 +#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101 +#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 +#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 +#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 + +#define PCI_VENDOR_ID_LEADTEK 0x107d +#define PCI_DEVICE_ID_LEADTEK_805 0x0000 + +#define PCI_VENDOR_ID_CONTAQ 0x1080 +#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600 +#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 + +#define PCI_VENDOR_ID_FOREX 0x1083 + +#define PCI_VENDOR_ID_OLICOM 0x108d +#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001 +#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011 +#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 +#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 +#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 +#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021 + +#define PCI_VENDOR_ID_SUN 0x108e +#define PCI_DEVICE_ID_SUN_EBUS 0x1000 +#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001 +#define PCI_DEVICE_ID_SUN_SIMBA 0x5000 +#define PCI_DEVICE_ID_SUN_PBM 0x8000 +#define PCI_DEVICE_ID_SUN_SABRE 0xa000 + +#define PCI_VENDOR_ID_CMD 0x1095 +#define PCI_DEVICE_ID_CMD_640 0x0640 +#define PCI_DEVICE_ID_CMD_643 0x0643 +#define PCI_DEVICE_ID_CMD_646 0x0646 +#define PCI_DEVICE_ID_CMD_647 0x0647 +#define PCI_DEVICE_ID_CMD_670 0x0670 + +#define PCI_VENDOR_ID_VISION 0x1098 +#define PCI_DEVICE_ID_VISION_QD8500 0x0001 +#define PCI_DEVICE_ID_VISION_QD8580 0x0002 + +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#define PCI_DEVICE_ID_BROOKTREE_848 0x0350 +#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351 +#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e +#define PCI_DEVICE_ID_BROOKTREE_878 0x0878 +#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474 + +#define PCI_VENDOR_ID_SIERRA 0x10a8 +#define PCI_DEVICE_ID_SIERRA_STB 0x0000 + +#define PCI_VENDOR_ID_ACC 0x10aa +#define PCI_DEVICE_ID_ACC_2056 0x0000 + +#define PCI_VENDOR_ID_WINBOND 0x10ad +#define PCI_DEVICE_ID_WINBOND_83769 0x0001 +#define PCI_DEVICE_ID_WINBOND_82C105 0x0105 +#define PCI_DEVICE_ID_WINBOND_83C553 0x0565 + +#define PCI_VENDOR_ID_DATABOOK 0x10b3 +#define PCI_DEVICE_ID_DATABOOK_87144 0xb106 + +#define PCI_VENDOR_ID_PLX 0x10b5 +#define PCI_DEVICE_ID_PLX_9050 0x9050 +#define PCI_DEVICE_ID_PLX_9060 0x9060 +#define PCI_DEVICE_ID_PLX_9060ES 0x906E +#define PCI_DEVICE_ID_PLX_9060SD 0x906D +#define PCI_DEVICE_ID_PLX_9080 0x9080 + +#define PCI_VENDOR_ID_MADGE 0x10b6 +#define PCI_DEVICE_ID_MADGE_MK2 0x0002 +#define PCI_DEVICE_ID_MADGE_C155S 0x1001 + +#define PCI_VENDOR_ID_3COM 0x10b7 +#define PCI_DEVICE_ID_3COM_3C985 0x0001 +#define PCI_DEVICE_ID_3COM_3C339 0x3390 +#define PCI_DEVICE_ID_3COM_3C590 0x5900 +#define PCI_DEVICE_ID_3COM_3C595TX 0x5950 +#define PCI_DEVICE_ID_3COM_3C595T4 0x5951 +#define PCI_DEVICE_ID_3COM_3C595MII 0x5952 +#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000 +#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001 +#define PCI_DEVICE_ID_3COM_3C905TX 0x9050 +#define PCI_DEVICE_ID_3COM_3C905T4 0x9051 +#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 + +#define PCI_VENDOR_ID_SMC 0x10b8 +#define PCI_DEVICE_ID_SMC_EPIC100 0x0005 + +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_DEVICE_ID_AL_M1445 0x1445 +#define PCI_DEVICE_ID_AL_M1449 0x1449 +#define PCI_DEVICE_ID_AL_M1451 0x1451 +#define PCI_DEVICE_ID_AL_M1461 0x1461 +#define PCI_DEVICE_ID_AL_M1489 0x1489 +#define PCI_DEVICE_ID_AL_M1511 0x1511 +#define PCI_DEVICE_ID_AL_M1513 0x1513 +#define PCI_DEVICE_ID_AL_M1521 0x1521 +#define PCI_DEVICE_ID_AL_M1523 0x1523 +#define PCI_DEVICE_ID_AL_M1531 0x1531 +#define PCI_DEVICE_ID_AL_M1533 0x1533 +#define PCI_DEVICE_ID_AL_M3307 0x3307 +#define PCI_DEVICE_ID_AL_M4803 0x5215 +#define PCI_DEVICE_ID_AL_M5219 0x5219 +#define PCI_DEVICE_ID_AL_M5229 0x5229 +#define PCI_DEVICE_ID_AL_M5237 0x5237 +#define PCI_DEVICE_ID_AL_M7101 0x7101 + +#define PCI_VENDOR_ID_MITSUBISHI 0x10ba + +#define PCI_VENDOR_ID_SURECOM 0x10bd +#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34 + +#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004 + +#define PCI_VENDOR_ID_ASP 0x10cd +#define PCI_DEVICE_ID_ASP_ABP940 0x1200 +#define PCI_DEVICE_ID_ASP_ABP940U 0x1300 +#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300 + +#define PCI_VENDOR_ID_MACRONIX 0x10d9 +#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512 +#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531 + +#define PCI_VENDOR_ID_CERN 0x10dc +#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001 +#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002 +#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021 +#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022 + +#define PCI_VENDOR_ID_NVIDIA 0x10de + +#define PCI_VENDOR_ID_IMS 0x10e0 +#define PCI_DEVICE_ID_IMS_8849 0x8849 + +#define PCI_VENDOR_ID_TEKRAM2 0x10e1 +#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c + +#define PCI_VENDOR_ID_TUNDRA 0x10e3 +#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000 + +#define PCI_VENDOR_ID_AMCC 0x10e8 +#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043 +#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062 +#define PCI_DEVICE_ID_AMCC_S5933 0x807d +#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c + +#define PCI_VENDOR_ID_INTERG 0x10ea +#define PCI_DEVICE_ID_INTERG_1680 0x1680 +#define PCI_DEVICE_ID_INTERG_1682 0x1682 + +#define PCI_VENDOR_ID_REALTEK 0x10ec +#define PCI_DEVICE_ID_REALTEK_8029 0x8029 +#define PCI_DEVICE_ID_REALTEK_8129 0x8129 +#define PCI_DEVICE_ID_REALTEK_8139 0x8139 + +#define PCI_VENDOR_ID_TRUEVISION 0x10fa +#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c + +#define PCI_VENDOR_ID_INIT 0x1101 +#define PCI_DEVICE_ID_INIT_320P 0x9100 +#define PCI_DEVICE_ID_INIT_360P 0x9500 + +#define PCI_VENDOR_ID_TTI 0x1103 +#define PCI_DEVICE_ID_TTI_HPT343 0x0003 + +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_DEVICE_ID_VIA_82C505 0x0505 +#define PCI_DEVICE_ID_VIA_82C561 0x0561 +#define PCI_DEVICE_ID_VIA_82C586_1 0x0571 +#define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_82C585 0x0585 +#define PCI_DEVICE_ID_VIA_82C586_0 0x0586 +#define PCI_DEVICE_ID_VIA_82C595 0x0595 +#define PCI_DEVICE_ID_VIA_82C597_0 0x0597 +#define PCI_DEVICE_ID_VIA_82C598_0 0x0598 +#define PCI_DEVICE_ID_VIA_82C926 0x0926 +#define PCI_DEVICE_ID_VIA_82C416 0x1571 +#define PCI_DEVICE_ID_VIA_82C595_97 0x1595 +#define PCI_DEVICE_ID_VIA_82C586_2 0x3038 +#define PCI_DEVICE_ID_VIA_82C586_3 0x3040 +#define PCI_DEVICE_ID_VIA_86C100A 0x6100 +#define PCI_DEVICE_ID_VIA_82C597_1 0x8597 +#define PCI_DEVICE_ID_VIA_82C598_1 0x8598 + +#define PCI_VENDOR_ID_SMC2 0x1113 +#define PCI_DEVICE_ID_SMC2_1211TX 0x1211 + +#define PCI_VENDOR_ID_VORTEX 0x1119 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125 + +#define PCI_VENDOR_ID_EF 0x111a +#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 +#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002 + +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 + +#define PCI_VENDOR_ID_IMAGINGTECH 0x112f +#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000 + +#define PCI_VENDOR_ID_PHILIPS 0x1131 +#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145 +#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 + +#define PCI_VENDOR_ID_CYCLONE 0x113c +#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001 + +#define PCI_VENDOR_ID_ALLIANCE 0x1142 +#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210 +#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422 +#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424 +#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d + +#define PCI_VENDOR_ID_SK 0x1148 +#define PCI_DEVICE_ID_SK_FP 0x4000 +#define PCI_DEVICE_ID_SK_TR 0x4200 +#define PCI_DEVICE_ID_SK_GE 0x4300 + +#define PCI_VENDOR_ID_VMIC 0x114a +#define PCI_DEVICE_ID_VMIC_VME 0x7587 + +#define PCI_VENDOR_ID_DIGI 0x114f +#define PCI_DEVICE_ID_DIGI_EPC 0x0002 +#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003 +#define PCI_DEVICE_ID_DIGI_XEM 0x0004 +#define PCI_DEVICE_ID_DIGI_XR 0x0005 +#define PCI_DEVICE_ID_DIGI_CX 0x0006 +#define PCI_DEVICE_ID_DIGI_XRJ 0x0009 +#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a +#define PCI_DEVICE_ID_DIGI_XR_920 0x0027 + +#define PCI_VENDOR_ID_MUTECH 0x1159 +#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001 + +#define PCI_VENDOR_ID_RENDITION 0x1163 +#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001 +#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000 + +#define PCI_VENDOR_ID_TOSHIBA 0x1179 +#define PCI_DEVICE_ID_TOSHIBA_601 0x0601 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a +#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f + +#define PCI_VENDOR_ID_RICOH 0x1180 +#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 +#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 +#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475 +#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 + +#define PCI_VENDOR_ID_ARTOP 0x1191 +#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004 +#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 + +#define PCI_VENDOR_ID_ZEITNET 0x1193 +#define PCI_DEVICE_ID_ZEITNET_1221 0x0001 +#define PCI_DEVICE_ID_ZEITNET_1225 0x0002 + +#define PCI_VENDOR_ID_OMEGA 0x119b +#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221 + +#define PCI_VENDOR_ID_GALILEO 0x11ab +#define PCI_DEVICE_ID_GALILEO_GT64011 0x4146 + +#define PCI_VENDOR_ID_LITEON 0x11ad +#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002 + +#define PCI_VENDOR_ID_NP 0x11bc +#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001 + +#define PCI_VENDOR_ID_ATT 0x11c1 +#define PCI_DEVICE_ID_ATT_L56XMF 0x0440 + +#define PCI_VENDOR_ID_SPECIALIX 0x11cb +#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 +#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000 +#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 + +#define PCI_VENDOR_ID_AURAVISION 0x11d1 +#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7 + +#define PCI_VENDOR_ID_IKON 0x11d5 +#define PCI_DEVICE_ID_IKON_10115 0x0115 +#define PCI_DEVICE_ID_IKON_10117 0x0117 + +#define PCI_VENDOR_ID_ZORAN 0x11de +#define PCI_DEVICE_ID_ZORAN_36057 0x6057 +#define PCI_DEVICE_ID_ZORAN_36120 0x6120 + +#define PCI_VENDOR_ID_KINETIC 0x11f4 +#define PCI_DEVICE_ID_KINETIC_2915 0x2915 + +#define PCI_VENDOR_ID_COMPEX 0x11f6 +#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 +#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401 + +#define PCI_VENDOR_ID_RP 0x11fe +#define PCI_DEVICE_ID_RP32INTF 0x0001 +#define PCI_DEVICE_ID_RP8INTF 0x0002 +#define PCI_DEVICE_ID_RP16INTF 0x0003 +#define PCI_DEVICE_ID_RP4QUAD 0x0004 +#define PCI_DEVICE_ID_RP8OCTA 0x0005 +#define PCI_DEVICE_ID_RP8J 0x0006 +#define PCI_DEVICE_ID_RPP4 0x000A +#define PCI_DEVICE_ID_RPP8 0x000B +#define PCI_DEVICE_ID_RP8M 0x000C + +#define PCI_VENDOR_ID_CYCLADES 0x120e +#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 +#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101 +#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200 +#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201 + +#define PCI_VENDOR_ID_ESSENTIAL 0x120f +#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 + +#define PCI_VENDOR_ID_O2 0x1217 +#define PCI_DEVICE_ID_O2_6729 0x6729 +#define PCI_DEVICE_ID_O2_6730 0x673a +#define PCI_DEVICE_ID_O2_6832 0x6832 +#define PCI_DEVICE_ID_O2_6836 0x6836 + +#define PCI_VENDOR_ID_3DFX 0x121a +#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 +#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002 +#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 + +#define PCI_VENDOR_ID_SIGMADES 0x1236 +#define PCI_DEVICE_ID_SIGMADES_6425 0x6401 + +#define PCI_VENDOR_ID_CCUBE 0x123f + +#define PCI_VENDOR_ID_DIPIX 0x1246 + +#define PCI_VENDOR_ID_STALLION 0x124d +#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000 +#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002 +#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003 + +#define PCI_VENDOR_ID_OPTIBASE 0x1255 +#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110 +#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210 +#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110 +#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120 +#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130 + +#define PCI_VENDOR_ID_SATSAGEM 0x1267 +#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352 +#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b + +#define PCI_VENDOR_ID_HUGHES 0x1273 +#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002 + +#define PCI_VENDOR_ID_ENSONIQ 0x1274 +#define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000 + +#define PCI_VENDOR_ID_ALTEON 0x12ae +#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001 + +#define PCI_VENDOR_ID_PICTUREL 0x12c5 +#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081 + +#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 +#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 + +#define PCI_VENDOR_ID_CBOARDS 0x1307 +#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001 + +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c +#define PCI_DEVICE_ID_SYMPHONY_101 0x0001 + +#define PCI_VENDOR_ID_TEKRAM 0x1de1 +#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 + +#define PCI_VENDOR_ID_3DLABS 0x3d3d +#define PCI_DEVICE_ID_3DLABS_300SX 0x0001 +#define PCI_DEVICE_ID_3DLABS_500TX 0x0002 +#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004 +#define PCI_DEVICE_ID_3DLABS_MX 0x0006 + +#define PCI_VENDOR_ID_AVANCE 0x4005 +#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064 +#define PCI_DEVICE_ID_AVANCE_2302 0x2302 + +#define PCI_VENDOR_ID_NETVIN 0x4a14 +#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000 + +#define PCI_VENDOR_ID_S3 0x5333 +#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551 +#define PCI_DEVICE_ID_S3_ViRGE 0x5631 +#define PCI_DEVICE_ID_S3_TRIO 0x8811 +#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812 +#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814 +#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d +#define PCI_DEVICE_ID_S3_868 0x8880 +#define PCI_DEVICE_ID_S3_928 0x88b0 +#define PCI_DEVICE_ID_S3_864_1 0x88c0 +#define PCI_DEVICE_ID_S3_864_2 0x88c1 +#define PCI_DEVICE_ID_S3_964_1 0x88d0 +#define PCI_DEVICE_ID_S3_964_2 0x88d1 +#define PCI_DEVICE_ID_S3_968 0x88f0 +#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901 +#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902 +#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01 +#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10 +#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01 +#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02 +#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03 +#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 + +#define PCI_VENDOR_ID_DCI 0x6666 +#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 + +#define PCI_VENDOR_ID_GENROCO 0x5555 +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003 + +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82375 0x0482 +#define PCI_DEVICE_ID_INTEL_82424 0x0483 +#define PCI_DEVICE_ID_INTEL_82378 0x0484 +#define PCI_DEVICE_ID_INTEL_82430 0x0486 +#define PCI_DEVICE_ID_INTEL_82434 0x04a3 +#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 +#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222 +#define PCI_DEVICE_ID_INTEL_7116 0x1223 +#define PCI_DEVICE_ID_INTEL_82596 0x1226 +#define PCI_DEVICE_ID_INTEL_82865 0x1227 +#define PCI_DEVICE_ID_INTEL_82557 0x1229 +#define PCI_DEVICE_ID_INTEL_82437 0x122d +#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e +#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 +#define PCI_DEVICE_ID_INTEL_82371MX 0x1234 +#define PCI_DEVICE_ID_INTEL_82437MX 0x1235 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_82380FB 0x124b +#define PCI_DEVICE_ID_INTEL_82439 0x1250 +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_82439TX 0x7100 +#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 +#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 +#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 +#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180 +#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181 +#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190 +#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191 +#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 +#define PCI_DEVICE_ID_INTEL_P6 0x84c4 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 + +#define PCI_VENDOR_ID_KTI 0x8e2e +#define PCI_DEVICE_ID_KTI_ET32P2 0x3000 + +#define PCI_VENDOR_ID_ADAPTEC 0x9004 +#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 +#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 +#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 +#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800 +#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 +#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 +#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178 +#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078 +#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178 +#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278 +#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378 +#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478 +#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895 +#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078 +#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178 +#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278 +#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378 +#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478 +#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78 + +#define PCI_VENDOR_ID_ADAPTEC2 0x9005 +#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 +#define PCI_DEVICE_ID_ADAPTEC2_78902 0x0013 +#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f +#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050 +#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051 +#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f + +#define PCI_VENDOR_ID_ATRONICS 0x907f +#define PCI_DEVICE_ID_ATRONICS_2015 0x2015 + +#define PCI_VENDOR_ID_HOLTEK 0x9412 +#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 + +#define PCI_VENDOR_ID_TIGERJET 0xe159 +#define PCI_DEVICE_ID_TIGERJET_300 0x0001 + +#define PCI_VENDOR_ID_ARK 0xedd8 +#define PCI_DEVICE_ID_ARK_STING 0xa091 +#define PCI_DEVICE_ID_ARK_STINGARK 0xa099 +#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1 + +/* + * The PCI interface treats multi-function devices as independent + * devices. The slot/function address of each device is encoded + * in a single byte as follows: + * + * 7:3 = slot + * 2:0 = function + */ +#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define PCI_FUNC(devfn) ((devfn) & 0x07) + +#ifdef __KERNEL__ + +#if defined(__L4__) +#else /* !defined(__L4__) */ +#include +#include +#endif /* !defined(__L4__) */ + +/* + * There is one pci_dev structure for each slot-number/function-number + * combination: + */ +struct pci_dev { + struct pci_bus *bus; /* bus this device is on */ + struct pci_dev *sibling; /* next device on this bus */ + struct pci_dev *next; /* chain of all devices */ + + void *sysdata; /* hook for sys-specific extension */ + struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */ + + unsigned int devfn; /* encoded device & function index */ + unsigned short vendor; + unsigned short device; + unsigned int class; /* 3 bytes: (base,sub,prog-if) */ + unsigned int hdr_type; /* PCI header type */ + unsigned int master : 1; /* set if device is master capable */ + /* + * In theory, the irq level can be read from configuration + * space and all would be fine. However, old PCI chips don't + * support these registers and return 0 instead. For example, + * the Vision864-P rev 0 chip can uses INTA, but returns 0 in + * the interrupt line and pin registers. pci_init() + * initializes this field with the value at PCI_INTERRUPT_LINE + * and it is the job of pcibios_fixup() to change it if + * necessary. The field must not be 0 unless the device + * cannot generate interrupts at all. + */ + unsigned int irq; /* irq generated by this device */ + + /* Base registers for this device, can be adjusted by + * pcibios_fixup() as necessary. + */ + unsigned long base_address[6]; + unsigned long rom_address; +}; + +struct pci_bus { + struct pci_bus *parent; /* parent bus this bridge is on */ + struct pci_bus *children; /* chain of P2P bridges on this bus */ + struct pci_bus *next; /* chain of all PCI buses */ + + struct pci_dev *self; /* bridge device as seen by parent */ + struct pci_dev *devices; /* devices behind this bridge */ + + void *sysdata; /* hook for sys-specific extension */ + struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */ + + unsigned char number; /* bus number */ + unsigned char primary; /* number of primary bridge */ + unsigned char secondary; /* number of secondary bridge */ + unsigned char subordinate; /* max number of subordinate buses */ +}; + +extern struct pci_bus pci_root; /* root bus */ +extern struct pci_dev *pci_devices; /* list of all devices */ + +/* + * Error values that may be returned by the PCI bios. + */ +#define PCIBIOS_SUCCESSFUL 0x00 +#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 +#define PCIBIOS_BAD_VENDOR_ID 0x83 +#define PCIBIOS_DEVICE_NOT_FOUND 0x86 +#define PCIBIOS_BAD_REGISTER_NUMBER 0x87 +#define PCIBIOS_SET_FAILED 0x88 +#define PCIBIOS_BUFFER_TOO_SMALL 0x89 + +/* Low-level architecture-dependent routines */ + +int pcibios_present (void); +void pcibios_init(void); +void pcibios_fixup(void); +void pcibios_fixup_bus(struct pci_bus *); +char *pcibios_setup (char *str); +int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char *val); +int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short *val); +int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int *val); +int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char val); +int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short val); +int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int val); + +/* Don't use these in new code, use pci_find_... instead */ + +int pcibios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, +unsigned char *dev_fn); +int pcibios_find_device (unsigned short vendor, unsigned short dev_id, + unsigned short index, unsigned char *bus, + unsigned char *dev_fn); + +/* Generic PCI interface functions */ + +void pci_init(void); +void pci_setup(char *str, int *ints); +void pci_quirks_init(void); +unsigned int pci_scan_bus(struct pci_bus *bus); +void pci_proc_init(void); +void proc_old_pci_init(void); +int get_pci_list(char *buf); +int pci_proc_attach_device(struct pci_dev *dev); +int pci_proc_detach_device(struct pci_dev *dev); + +struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev +*from); +struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from); +struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); + +#define pci_present pcibios_present +int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 *val); +int pci_read_config_word(struct pci_dev *dev, u8 where, u16 *val); +int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 *val); +int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val); +int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val); +int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val); +void pci_set_master(struct pci_dev *dev); + +#ifndef CONFIG_PCI +/* If the system does not have PCI, clearly these return errors. Define + these as simple inline functions to avoid hair in drivers. */ +extern inline int pcibios_present(void) { return 0; } + +#define _PCI_NOP(o,s,t) \ + extern inline int pcibios_##o##_config_##s## (u8 bus, u8 dfn, u8 where, t val) \ + { return PCIBIOS_FUNC_NOT_SUPPORTED; } \ + extern inline int pci_##o##_config_##s## (struct pci_dev *dev, u8 where, t val) \ + { return PCIBIOS_FUNC_NOT_SUPPORTED; } +#define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \ + _PCI_NOP(o,word,u16 x) \ + _PCI_NOP(o,dword,u32 x) +_PCI_NOP_ALL(read, *) +_PCI_NOP_ALL(write,) + +extern inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, struct +pci_dev *from) +{ return NULL; } + +extern inline struct pci_dev *pci_find_class(unsigned int class, struct pci_dev *from) +{ return NULL; } + +extern inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) +{ return NULL; } + +#endif /* !CONFIG_PCI */ + +#endif /* __KERNEL__ */ + +#if defined(_WASNOTDEFINED___KERNEL__) +#undef __KERNEL__ +#undef u8 +#undef u16 +#undef u32 +#endif +#undef _WASNOTDEFINED___KERNEL__ + +#if defined(_WASNOTDEFINED___L4__) +#undef __L4__ +#endif +#undef _WASNOTDEFINED___L4__ + +#if defined(_WASNOTDEFINED_CONFIG_PCI) +#undef CONFIG_PCI +#endif +#undef _WASNOTDEFINED_CONFIG_PCI + +#if defined(_WASNOTDEFINED_CONFIG_PCI_GOANY) +#undef CONFIG_PCI_GOANY +#endif +#undef _WASNOTDEFINED_CONFIG_PCI_GOANY + +#if defined(_WASNOTDEFINED_CONFIG_PCI_BIOS) +#undef CONFIG_PCI_BIOS +#endif +#undef _WASNOTDEFINED_CONFIG_PCI_BIOS + +#endif /* LINUX_PCI_H */ + diff --git a/apps/rmgr/src/memmap.c b/apps/rmgr/src/memmap.c new file mode 100644 index 0000000..0b928cb --- /dev/null +++ b/apps/rmgr/src/memmap.c @@ -0,0 +1,453 @@ +#include +#include + +#include + +#include "globals.h" + +#include +#include "init.h" +#include "memmap.h" +#include "memmap_lock.h" + +owner_t __memmap[MEM_MAX/L4_PAGESIZE]; +__superpage_t __memmap4mb[SUPERPAGE_MAX]; + +vm_offset_t mem_high; +vm_offset_t mem_phys; + +l4_kernel_info_t *l4_info; + +last_pf_t last_pf[TASK_MAX]; + +int memmap_lock = -1; + +static void find_free(dword_t *d1, dword_t *d2, owner_t owner); + +void +pager(void) +{ + dword_t d1, d2, pfa; + void *desc; + int err; + l4_threadid_t t; + l4_msgdope_t result; + + /* we (the main thread of this task) will serve as a pager for our + children. */ + + /* now start serving the subtasks */ + for (;;) + { + err = l4_i386_ipc_wait(&t, 0, &d1, &d2, L4_IPC_NEVER, &result); + + while (!err) + { + /* we must synchronise the access to memmap functions */ + enter_memmap_functions(RMGR_LTHREAD_PAGER, rmgr_super_id); + + /* we received a paging request here */ + /* handle the sigma0 protocol */ + + desc = L4_IPC_SHORT_MSG; + + if (t.id.task > O_MAX) + { + /* OOPS.. can't map to this sender. */ + d1 = d2 = 0; + } + else /* valid requester */ + { + pfa = d1 & 0xfffffffc; + + if (d1 == 0xfffffffc) + { + /* map any free page back to sender */ + find_free(&d1, &d2, t.id.task); + + if ((d2 != 0) && memmap_alloc_page(d1, t.id.task)) + desc = L4_IPC_SHORT_FPAGE; + else d1 = d2 = 0; + } + else if (d1 == 1 && (d2 & 0xff) == 1) + { + /* kernel info page requested */ + d1 = 0; + d2 = l4_fpage((dword_t) l4_info, L4_LOG2_PAGESIZE, + L4_FPAGE_RO, L4_FPAGE_MAP).fpage; + desc = L4_IPC_SHORT_FPAGE; + } + else if (pfa < 0x40000000) + { + /* check if address lays inside our memory. we do that + * here because the memmap_* functions do not check + * about that */ + if (pfa >= mem_high) + /* yes, ugly, but easy... */ + goto access_violation; + + if (pfa < L4_PAGESIZE) + /* from now on, we do not implicit map page 0. To + * map page 0, do it explicit by rmgr_get_page0() */ + goto access_violation; + + /* map a specific page */ + if ((d1 & 1) && (d2 == (L4_LOG2_SUPERPAGESIZE << 2))) + { + /* superpage request */ + if (!no_pentium && + memmap_alloc_superpage(pfa, t.id.task)) + { + d1 &= L4_SUPERPAGEMASK; + d2 = l4_fpage(d1, L4_LOG2_SUPERPAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage; + desc = L4_IPC_SHORT_FPAGE; + + /* flush the superpage first so that + contained 4K pages which already have + been mapped to the task don't disturb the + 4MB mapping */ + l4_fpage_unmap(l4_fpage(d1, L4_LOG2_SUPERPAGESIZE, + 0, 0), + L4_FP_FLUSH_PAGE|L4_FP_OTHER_SPACES); + + goto reply; + } + } + /* failing a superpage allocation, try a single page + allocation */ + if (memmap_alloc_page(d1, t.id.task)) + { + d1 &= L4_PAGEMASK; + d2 = l4_fpage(d1, L4_LOG2_PAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage; + desc = L4_IPC_SHORT_FPAGE; + } + else if (pfa >= mem_lower * 1024L && pfa < 0x100000L) + { + /* adapter area, page faults are OK */ + d1 &= L4_PAGEMASK; + d2 = l4_fpage(d1, L4_LOG2_PAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage; + desc = L4_IPC_SHORT_FPAGE; + } + else + + access_violation: + if ((d2!=(L4_LOG2_SUPERPAGESIZE<<2)) && !no_checkdpf) + { + /* check for double page fault */ + last_pf_t *last_pfp = last_pf + t.id.task; + if ((d1==last_pfp->pfa) && (d2==last_pfp->eip)) + { + static char errmsg[100]; + d1 &= L4_PAGEMASK; + sprintf(errmsg,"\r\n" + "RMGR: thread 0x%x at 0x%x is trying " + "to get page 0x%x", + t.raw, d2, d1); + outstring(errmsg); + + if (d1 < mem_high) + { + owner_t owner = memmap_owner_page(d1); + if (owner == O_RESERVED) + sprintf(errmsg, " which is reserved"); + else + sprintf(errmsg," allocated by task %x", owner); + outstring(errmsg); + + if (!quota_alloc_mem(t.id.task, d1, L4_PAGESIZE)) + outstring("\r\n (Cause: quota exceeded)"); + } + else + { + sprintf(errmsg," (memhigh=%08x)", mem_high); + outstring(errmsg); + } + + outstring("\r\n"); + + enter_kdebug("double page fault"); + } + last_pfp->pfa = d1; + last_pfp->eip = d2; + d1 = d2 = 0; + } + } + else if (pfa >= 0x40000000 && pfa < 0xC0000000 && !(d1 & 1)) + { + /* request physical 4 MB area at pfa + 0x40000000 */ + + /* XXX UGLY HACK! */ + + static vm_offset_t scratch = 0x40000000; /* XXX hardcoded */ + + pfa = (pfa & L4_SUPERPAGEMASK); + + if (memmap_alloc_superpage(pfa + 0x40000000, t.id.task)) + { + /* map the superpage into a scratch area */ + l4_fpage_unmap(l4_fpage(scratch, L4_LOG2_SUPERPAGESIZE, + 0,0), + L4_FP_FLUSH_PAGE|L4_FP_ALL_SPACES); + l4_i386_ipc_call(my_pager, L4_IPC_SHORT_MSG, + pfa, 0, + L4_IPC_MAPMSG(scratch, + L4_LOG2_SUPERPAGESIZE), + &d1, &d2, L4_IPC_NEVER, &result); + + /* grant the superpage to the subtask */ + d1 = pfa; + d2 = l4_fpage(scratch, L4_LOG2_SUPERPAGESIZE, + L4_FPAGE_RW, L4_FPAGE_GRANT).fpage; + desc = L4_IPC_SHORT_FPAGE; + } + } +#if defined(CONFIG_IO_FLEXPAGES) + else if (pfa >= 0xF0000000 && pfa < 0xFFFFF043){ + /* Map the whole IO Space */ + d1 = d2 = pfa; + desc = L4_IPC_SHORT_FPAGE; + } + +#endif + else + { + /* unknown request */ + d1 = d2 = 0; + } + } + + reply: + + leave_memmap_functions(RMGR_LTHREAD_PAGER, rmgr_super_id); + + /* send reply and wait for next message */ + err = l4_i386_ipc_reply_and_wait(t, desc, d1, d2, + &t, 0, &d1, &d2, + L4_IPC_TIMEOUT(0,1,0,0,0,0), + /* snd timeout = 0 */ + &result); + + /* send error while granting? flush fpage! */ + if (err == L4_IPC_SETIMEOUT + && desc == L4_IPC_SHORT_FPAGE + && (d2 & 1)) + { + l4_fpage_unmap((l4_fpage_t) d2, + L4_FP_FLUSH_PAGE|L4_FP_ALL_SPACES); + } + } + } +} + +static void +find_free(dword_t *d1, dword_t *d2, owner_t owner) +{ + /* XXX this routine should be in the memmap_*() interface because we + don't know about quotas here. we can easily select a free page + which we later can't allocate because we're out of quota. */ + + vm_offset_t address; + + for (address = 0; address < mem_high; address += L4_SUPERPAGESIZE) + { + if (memmap_nrfree_superpage(address) == 0) + continue; + + for (;address < mem_high; address += L4_PAGESIZE) + { + if (! quota_check_mem(owner, address, L4_PAGESIZE)) + continue; + if (memmap_owner_page(address) != O_FREE) + continue; + + /* found! */ + *d1 = address; + *d2 = l4_fpage(address, L4_LOG2_PAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage; + + return; + } + } + + /* nothing found! */ + *d1 = *d2 = 0; +} + + +vm_offset_t +reserve_range(unsigned int size_and_align, owner_t owner, + vm_offset_t range_low, vm_offset_t range_high) +{ +#ifndef min +#define min(x,y) ((x)<(y)?(x):(y)) +#endif + vm_offset_t address, min_address, max_address; + unsigned int have_pages; + unsigned int size = size_and_align & L4_PAGEMASK; + unsigned int align = size_and_align & ~L4_PAGEMASK & ~RMGR_MEM_RES_FLAGS_MASK; + unsigned int flags = size_and_align & ~L4_PAGEMASK & RMGR_MEM_RES_FLAGS_MASK; + unsigned int need_pages = size / L4_PAGESIZE; + + /* suggestive round alignment */ + if (align < L4_LOG2_PAGESIZE) + align = L4_LOG2_PAGESIZE; + else if (align > 28) + align = 28; + align = ~((1 << align) - 1); + + max_address = mem_high; + + if (range_high != 0) + max_address = min(max_address, range_high); + + if (flags & RMGR_MEM_RES_DMA_ABLE) + max_address = min(max_address, 16*1024*1024); + + /* round down to next L4 page */ + max_address &= L4_PAGEMASK; + + /* round up to next L4 page */ + min_address = (range_low + ~L4_PAGEMASK) & L4_PAGEMASK; + + /* some sanity checks */ + if (max_address-min_address < size) + return -1; + + if (flags & RMGR_MEM_RES_UPWARDS) + { + /* search upwards min_address til max_address */ + max_address -= size; + + for (address = min_address; ; ) + { + /* round up to next proper alignend chunk */ + address = (address + ~align) & align; + + if (address > max_address) + return -1; + + for (have_pages = 0; ; address += L4_PAGESIZE) + { + if (!quota_check_mem(owner, address, L4_PAGESIZE) + || memmap_owner_page(address) != O_FREE) + break; + + if (++have_pages >= need_pages) + { + address -= size - L4_PAGESIZE; + goto found; + } + } + + address += L4_PAGESIZE; + } + } + else + { + /* search downwards mem_high-0 */ + for (address = max_address; address >= min_address + size; ) + { + /* round down to next proper aligned chunk */ + address = ((address-size) & align) + size; + + for (have_pages = 0;; ) + { + address -= L4_PAGESIZE; + + if (!quota_check_mem(owner, address, L4_PAGESIZE) + || memmap_owner_page(address) != O_FREE) + break; + + if (++have_pages >= need_pages) + { + /* we have found a chunk which is big enough */ + int ret, a; + found: + + for (a=address; areserved0.high); + unsigned long eor_sigma0 = ROUND_PAGE(l4_info->sigma0_memory.high); + static char ownerstr[44]; + + printf("RMGR: Memory Dump (%ldkB total RAM, %ldkB reserved for L4 kernel)\n", + mb_info.mem_upper + 1024, mb_info.mem_upper+1024-mem_high/1024); + for (bor=0, eor=0; eor<=mem_high; eor+=L4_PAGESIZE) + { + if ((memmap_owner_page(eor) != owner) + || (eor >= mem_high) + || (eor == 0x00001000) + || (eor == 0x00002000) + || (eor == eor_reserved0) + || (eor == eor_sigma0)) + { + if (bor != eor) + { + switch (owner) + { + case O_RESERVED: + if (eor == 0x00100000) + sprintf(ownerstr, "[BIOS adapter area]"); + else if (bor==(unsigned)&_stext) + strcpy(ownerstr, "[rmgr]"); + else if (eor==0x00001000) + strcpy(ownerstr, "[BIOS data area]"); + else if (eor==0x00002000) + strcpy(ownerstr, "[kernel info page]"); + else if (eor==eor_reserved0) + strcpy(ownerstr, "[L4 kernel]"); + else if (eor==eor_sigma0) + strcpy(ownerstr, "[sigma0]"); + else if (eor==fiasco_symbols_end) + strcpy(ownerstr, "[Fiasco symbols]"); + else + strcpy(ownerstr, "reserved"); + break; + case O_FREE: + strcpy(ownerstr, "free"); + break; + default: + { + int i, j; + i = sizeof(ownerstr); + sprintf(ownerstr, "0x%x ", owner); + j = strlen(ownerstr); + i-=j; + strncpy(ownerstr+j, owner_name(owner), i); + } + break; + } + ownerstr[sizeof(ownerstr)-1]='\0'; + printf(" %08x-%08x (%7dkB): %s\n", + bor, eor, (eor-bor)/1024, ownerstr); + bor = eor; + } + owner = memmap_owner_page(eor); + } + } +} + diff --git a/apps/rmgr/src/memmap.h b/apps/rmgr/src/memmap.h new file mode 100644 index 0000000..84a9024 --- /dev/null +++ b/apps/rmgr/src/memmap.h @@ -0,0 +1,214 @@ +#ifndef MEMMAP_H +#define MEMMAP_H + +#include +#include +#include + +#include + +#include "globals.h" +#include "quota.h" + +#define MEM_MAX (256L*1024L*1024L) /* max RAM we handle */ +#define SUPERPAGE_MAX (1024) /* no of superpages in the system */ + +typedef struct { + word_t free_pages; + owner_t owner; + byte_t padding; +} __attribute__((packed)) __superpage_t; + +typedef struct { + dword_t pfa; + dword_t eip; +} __attribute__((packed)) last_pf_t; + +extern owner_t __memmap[MEM_MAX/L4_PAGESIZE]; +extern __superpage_t __memmap4mb[SUPERPAGE_MAX]; +extern last_pf_t last_pf[]; +extern vm_offset_t mem_high; +extern vm_offset_t mem_phys; + +extern l4_kernel_info_t *l4_info; + +void pager(void) L4_NORETURN; +vm_offset_t reserve_range(unsigned int size_and_align, owner_t owner, + vm_offset_t range_low, vm_offset_t range_high); +void show_mem_info(void); + +L4_INLINE void memmap_init(void); +L4_INLINE int memmap_free_page(vm_offset_t address, owner_t owner); +L4_INLINE int memmap_alloc_page(vm_offset_t address, owner_t owner); +L4_INLINE owner_t memmap_owner_page(vm_offset_t address); +L4_INLINE int memmap_free_superpage(vm_offset_t address, owner_t owner); +L4_INLINE int memmap_alloc_superpage(vm_offset_t address, owner_t owner); +L4_INLINE owner_t memmap_owner_superpage(vm_offset_t address); +L4_INLINE unsigned memmap_nrfree_superpage(vm_offset_t address); + +L4_INLINE void memmap_init(void) +{ + unsigned i; + __superpage_t *s; + + memset(__memmap, O_RESERVED, MEM_MAX/L4_PAGESIZE); + for (s = __memmap4mb, i = 0; i < SUPERPAGE_MAX; i++, s++) + *s = (__superpage_t) { 0, O_RESERVED, 0 }; +} + +L4_INLINE int memmap_free_page(vm_offset_t address, owner_t owner) +{ + owner_t *m = __memmap + address/L4_PAGESIZE; + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + if (s->owner == O_FREE) + return 1; /* already free */ + if (s->owner != O_RESERVED) + return 0; + if (*m == O_FREE) + return 1; /* already free */ + if (*m != owner) + return 0; + + quota_free_mem(owner, address, L4_PAGESIZE); + + *m = O_FREE; + s->free_pages++; + + if (s->free_pages == L4_SUPERPAGESIZE/L4_PAGESIZE) + s->owner = O_FREE; + return 1; +} + +L4_INLINE int memmap_alloc_page(vm_offset_t address, owner_t owner) +{ + owner_t *m = __memmap + address/L4_PAGESIZE; + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + if (*m == owner) + return 1; /* already allocated */ + if (*m != O_FREE) + return 0; + + if (s->owner == O_FREE) + s->owner = O_RESERVED; + else if (s->owner != O_RESERVED) + return 0; + + if (! quota_alloc_mem(owner, address, L4_PAGESIZE)) + return 0; + + s->free_pages--; + + *m = owner; + return 1; +} + +L4_INLINE owner_t memmap_owner_page(vm_offset_t address) +{ + owner_t *m = __memmap + address/L4_PAGESIZE; + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + return s->owner == O_RESERVED ? *m : s->owner; +} + +L4_INLINE int memmap_free_superpage(vm_offset_t address, owner_t owner) +{ + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + if (s->owner == O_FREE) + return 1; /* already free */ + if (s->owner != owner) + return 0; + + quota_free_mem(owner, address, L4_SUPERPAGESIZE); + + s->owner = O_FREE; + s->free_pages = L4_SUPERPAGESIZE/L4_PAGESIZE; + + /* assume __memmap[] is correctly set up here (all single pages + marked free) */ + return 1; +} + +L4_INLINE int memmap_alloc_superpage(vm_offset_t address, owner_t owner) +{ + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + if (s->owner == owner) + return 1; /* already allocated */ + if (s->owner != O_FREE) + { + /* check if all pages inside belong to the new owner already */ + + owner_t *m, *sm; + vm_size_t already_have = 0; + + if (s->owner != O_RESERVED) + return 0; + + address &= L4_SUPERPAGEMASK; + if (address >= MEM_MAX) + return 0; + + for (sm = m = __memmap + address/L4_PAGESIZE; + m < sm + L4_SUPERPAGESIZE/L4_PAGESIZE; + m++) + { + if (! (*m == O_FREE || *m == owner)) + return 0; /* don't own superpage exclusively */ + + if (*m == owner) + already_have += L4_PAGESIZE; + } + + if (already_have) + { + /* XXX we're sloppy with the exact addresses we free here, + knowing that the address doesn't really matter to + quota_free_mem() */ + quota_free_mem(owner, address, already_have); + } + + if (! quota_alloc_mem(owner, address, L4_SUPERPAGESIZE)) + { + if (already_have) + /* XXX we deal with the quota's private values here... :-( */ + quota[owner].mem.current += already_have; /* reset */ + + return 0; + } + + /* ok, we're the exclusive owner of this superpage */ + memset(sm, O_FREE, L4_SUPERPAGESIZE/L4_PAGESIZE); + + } + else + { + if (! quota_alloc_mem(owner, address & L4_SUPERPAGEMASK, L4_SUPERPAGESIZE)) + return 0; + } + + s->owner = owner; + return 1; +} + +L4_INLINE owner_t memmap_owner_superpage(vm_offset_t address) +{ + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + return s->owner; +} + +L4_INLINE unsigned memmap_nrfree_superpage(vm_offset_t address) +{ + __superpage_t *s = __memmap4mb + address/L4_SUPERPAGESIZE; + + if (s->owner == O_FREE || s->owner == O_RESERVED) + return s->free_pages; + + return 0; +} + + +#endif diff --git a/apps/rmgr/src/memmap_lock.h b/apps/rmgr/src/memmap_lock.h new file mode 100644 index 0000000..e660da2 --- /dev/null +++ b/apps/rmgr/src/memmap_lock.h @@ -0,0 +1,63 @@ +#ifndef MEMMAP_LOCK_H +#define MEMMAP_LOCK_H + +extern int memmap_lock; + +static inline dword_t +i386_xchg(dword_t *addr, dword_t newval) +{ + dword_t oldval; + __asm__ __volatile__ ("xchg %0, (%2)\n\t" + : "=r" (oldval) + : "0" (newval), "r" (addr) + : "memory" + ); + return oldval; +} + +static inline dword_t +i386_cmpxchg(dword_t *addr, dword_t oldval, dword_t newval) +{ + char ret; + __asm__ __volatile__ ("cmpxchg %1,(%2) ; sete %b0" + : "=a" (ret) + : "q" (newval), "q" (addr), "0" (oldval) + : "memory" + ); + return ret; +} + +static inline void +enter_memmap_functions(int me, l4_threadid_t locker) +{ + if (i386_xchg(&memmap_lock, me) != -1) + { + int error; + dword_t d; + l4_msgdope_t result; + if ((error = l4_i386_ipc_receive(locker, L4_IPC_SHORT_MSG, &d, &d, + L4_IPC_NEVER, &result)) || + (error = l4_i386_ipc_send (locker, L4_IPC_SHORT_MSG, 0, 0, + L4_IPC_NEVER, &result))) + panic("Error 0x%02x woken up\n", error); + } +} + +static inline void +leave_memmap_functions(int me, l4_threadid_t candidate) +{ + if (!i386_cmpxchg(&memmap_lock, me, -1)) + { + int error; + dword_t d; + l4_msgdope_t result; + if ((error = l4_i386_ipc_call(candidate, + L4_IPC_SHORT_MSG, 0, 0, + L4_IPC_SHORT_MSG, &d, &d, + L4_IPC_NEVER, &result))) + panic("Error 0x%02x waking up\n", error); + } +} + +#endif + diff --git a/apps/rmgr/src/oskit_support.c b/apps/rmgr/src/oskit_support.c new file mode 100644 index 0000000..543f3d2 --- /dev/null +++ b/apps/rmgr/src/oskit_support.c @@ -0,0 +1,171 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +extern int hercules; +extern int kernel_running; + +static void herc_direct_cons_putchar(unsigned char c); +static void kern_putchar(unsigned char c); +int have_hercules(void); +void my_pc_reset(void); + +int +putchar(int c) +{ + (kernel_running) + ? kern_putchar(c) + : (hercules) + ? herc_direct_cons_putchar(c) + : direct_cons_putchar(c); + + return c; +} + +int +getchar(void) +{ + return direct_cons_getchar(); +} + +void +my_pc_reset(void) +{ + outb_p(0x70, 0x80); + inb_p (0x71); + + while (inb(0x64) & 0x02) + ; + + outb_p(0x70, 0x8F); + outb_p(0x71, 0x00); + + outb_p(0x64, 0xFE); + + for (;;) + ; +} + +void +_exit(int fd) +{ + char c; + + if (kernel_running) + { + printf("\nReturn reboots, \"k\" enters L4 kernel debugger...\n"); + c = getchar(); + if (c == 'k' || c == 'K') + enter_kdebug("before reboot"); + } + else + { + printf("\nReturn reboots...\n"); + getchar(); + } + + my_pc_reset(); +} + +/* modified direct_cons_putchar from oskit/libkern */ +#define HERC_VIDBASE ((unsigned char *)0xb0000) +void +herc_direct_cons_putchar(unsigned char c) +{ + static int ofs = -1; + + base_critical_enter(); + + if (ofs < 0) + { + /* Called for the first time - initialize. */ + ofs = 0; + herc_direct_cons_putchar('\n'); + } + + switch (c) + { + case '\n': + bcopy(HERC_VIDBASE+80*2, HERC_VIDBASE, 80*2*24); + bzero(HERC_VIDBASE+80*2*24, 80*2); + /* fall through... */ + case '\r': + ofs = 0; + break; + + case '\t': + ofs = (ofs + 8) & ~7; + break; + + default: + /* Wrap if we reach the end of a line. */ + if (ofs >= 80) { + herc_direct_cons_putchar('\n'); + } + + /* Stuff the character into the video buffer. */ + { + volatile unsigned char *p = HERC_VIDBASE + + 80*2*24 + ofs*2; + p[0] = c; + p[1] = 0x0f; + ofs++; + } + break; + } + + base_critical_leave(); +} + +static void +kern_putchar(unsigned char c) +{ + outchar(c); + if (c == '\n') + outchar('\r'); +} + +int +have_hercules(void) +{ + unsigned short *p, p_save; + int count = 0; + unsigned long delay; + + /* check for video memory */ + p = (unsigned short*)0xb0000; + p_save = *p; + *p = 0xaa55; if (*p == 0xaa55) count++; + *p = 0x55aa; if (*p == 0x55aa) count++; + *p = p_save; + if (count != 2) + return 0; + + /* check for I/O ports (HW cursor) */ + outb_p(0x3b4, 0x0f); + outb (0x3b5, 0x66); + for (delay=0; delay<0x100000UL; delay++) + asm volatile ("nop" : :); + if (inb_p(0x3b5) != 0x66) + return 0; + + outb_p(0x3b4, 0x0f); + outb (0x3b5, 0x99); + for (delay=0; delay<0x100000UL; delay++) + asm volatile ("nop" : :); + if (inb_p(0x3b5) != 0x99) + return 0; + + /* reset position */ + outb_p(0x3b4, 0x0f); + outb (0x3b5, 0x0); + + return 1; +} diff --git a/apps/rmgr/src/pe.c b/apps/rmgr/src/pe.c new file mode 100644 index 0000000..0762551 --- /dev/null +++ b/apps/rmgr/src/pe.c @@ -0,0 +1,106 @@ +/*********************************************************************** + * pe-loader (c) 2000 University of Karlsruhe + * author: Volkmar Uhlig + * + * $Log: pe.c,v $ + * Revision 1.1 2000/05/16 14:56:55 uhlig + * added coff/pe-file loading support to rmgr. + * currently only tested on pe-files generated by MSDEV-Studio but should work with "normal" coff files too. + * + */ +#include +#include +#include +#include "coff-i386.h" +#include + +int exec_load_pe(exec_read_func_t *read, exec_read_exec_func_t *read_exec, + void *handle, exec_info_t *out_info) +{ + vm_size_t actual; + FILHDR x; + DOSHDR dhdr; + AOUTHDR ohdr; + SCNHDR * phdr; + __u32 foffset = 0; + __u32 image_offset = 0; + + vm_size_t phsize; + int i; + int result; + + /* read the header of the file - could have DOS header */ + if ((result = (*read)(handle, 0, &dhdr, sizeof(dhdr), &actual)) != 0) + return result; + if (actual < sizeof(dhdr)) + return EX_NOT_EXECUTABLE; + + //printf("dos header: %x, %x\n", dhdr.f_magic, dhdr.f_lfanew); + + if (dhdr.f_magic == DOSMAGIC) { + //printf("found dosmagic\n"); + if ((unsigned int)dhdr.f_lfanew == 0) + return EX_NOT_EXECUTABLE; + foffset = dhdr.f_lfanew; + foffset += 4; // hack - skip pe00 magic of NT + //printf("file offset: %x\n", foffset); + } + /* Read the coff header. */ + if ((result = (*read)(handle, foffset, &x, sizeof(x), &actual)) != 0) + return result; + if (actual < sizeof(x)) + return EX_NOT_EXECUTABLE; + + //printf("magic: %x\n", x.f_magic); + /* check magic */ + if (I386BADMAG(x)) + return EX_NOT_EXECUTABLE; + + /* read optional header */ + if ((result = (*read)(handle, foffset + FILHSZ, &ohdr, x.f_opthdr, &actual)) != 0) + return result; + + if (x.f_opthdr == NT32_OHDRSIZE) { + image_offset = ohdr.u.nt.image_base; + } + else + image_offset = 0; + + out_info->entry = (vm_offset_t) ohdr.entry + image_offset; + + phsize = x.f_nscns * SCNHSZ; + phdr = (SCNHDR*)alloca(phsize); + + result = (*read)(handle, x.f_opthdr + foffset + FILHSZ, phdr, phsize, &actual); + if (result) + return result; + if (actual < phsize) + return EX_CORRUPT; + + + for (i = 0; i < x.f_nscns; i++) + { + SCNHDR *ph = (SCNHDR*)((vm_offset_t)phdr + i * SCNHSZ); + ph->s_name[7] = 0; + //printf("section: %s\n", ph->s_name); + if (!(ph->s_flags & SECT_DISCARDABLE)) + { + exec_sectype_t type = EXEC_SECTYPE_ALLOC | + EXEC_SECTYPE_LOAD; + if (ph->s_flags & SECT_READ) type |= EXEC_SECTYPE_READ; + if (ph->s_flags & SECT_WRITE) type |= EXEC_SECTYPE_WRITE; + if (ph->s_flags & SECT_EXECUTE) type |= EXEC_SECTYPE_EXECUTE; +#if 1 + result = (*read_exec)(handle, + ph->s_scnptr, ph->misc.s_vsize, + ph->s_vaddr + image_offset, + ph->s_size, type); +#else + printf("load %x -> %x, size: %d/%d\n", ph->s_scnptr, ph->s_vaddr + image_offset, ph->misc.s_vsize, ph->s_size); +#endif + } + } + + return 0; +} + diff --git a/apps/rmgr/src/quota.h b/apps/rmgr/src/quota.h new file mode 100644 index 0000000..b88c134 --- /dev/null +++ b/apps/rmgr/src/quota.h @@ -0,0 +1,122 @@ +#ifndef QUOTA_H +#define QUOTA_H + +#include + +#include "globals.h" + +typedef struct +{ + unsigned low, high; + unsigned max, current; +} __attribute__((packed)) u_quota_t; + +typedef struct +{ + unsigned short low, high; + unsigned short max, current; +} __attribute__((packed)) us_quota_t; + +typedef struct +{ + unsigned char low, high; + unsigned char max, current; +} __attribute__((packed)) ub_quota_t; + +typedef struct +{ + unsigned max, current; +} __attribute__((packed)) mask_quota_t; + +typedef struct +{ + u_quota_t mem, himem; + us_quota_t task; + ub_quota_t small; + mask_quota_t irq; + unsigned short log_mcp; +} __attribute__((packed)) quota_t; + +typedef struct +{ + unsigned char mcp; + unsigned char prio; + unsigned char small_space; + unsigned char mods; +} __attribute__((packed)) bootquota_t; + +extern quota_t quota[TASK_MAX]; +extern bootquota_t bootquota[TASK_MAX]; + +L4_INLINE void quota_init(void); + +L4_INLINE void quota_init(void) +{ + unsigned i; + + for (i = 0; i < TASK_MAX; i++) + { + quota[i].mem.low = quota[i].mem.current = 0; + quota[i].mem.high = quota[i].mem.max = -1; + quota[i].himem.low = quota[i].himem.current = 0; + quota[i].himem.high = quota[i].himem.max = -1; + quota[i].task.low = quota[i].task.current = 0; + quota[i].task.high = quota[i].task.max = -1; + quota[i].small.low = quota[i].small.current = 0; + quota[i].small.high = quota[i].small.max = -1; + quota[i].irq.current = 0; + quota[i].irq.max = -1; + quota[i].log_mcp = -1; + + bootquota[i].mcp = 255; /* L4 default */ + bootquota[i].prio = 0x10; /* L4 default */ + bootquota[i].small_space = 0xff; /* for L4, 0xff means "no change" */ + bootquota[i].mods = 0; /* number of boot mods assn'd to this task */ + } +} + +#define __quota_check_u(q, where, amount) \ +( ((q).max >= (amount) && (q).current <= (q).max - (amount)) ? \ + (((q).low <= (where) && (q).high >= (where) + (amount) - 1) ? 1 : 0) \ + : 0) + +#define quota_check_mem(t, where, amount) \ +( __quota_check_u((where) < mem_high ? quota[(t)].mem \ + : quota[(t)].himem, \ + (where), (amount))) + +#define __quota_alloc_u(q, where, amount) \ +( ((q).max >= (amount) && (q).current <= (q).max - (amount)) ? \ + (((q).low <= (where) && (q).high >= (where) + (amount) - 1) ? \ + (q).current += (amount), 1 : 0) \ + : 0) + +#define quota_alloc_mem(t, where, amount) \ +( __quota_alloc_u((where) < mem_high ? quota[(t)].mem \ + : quota[(t)].himem, \ + (where), (amount))) + +#define quota_alloc_task(t, where) \ +( __quota_alloc_u(quota[(t)].task, (where), 1)) + +#define quota_alloc_small(t, where) \ +( __quota_alloc_u(quota[(t)].small, (where), 1)) + +#define quota_alloc_irq(t, where) \ +( (quota[(t)].irq.max & (1L << (where))) ? \ + (quota[(t)].irq.current |= (1L << (where))), 1 : 0) + + +#define __quota_free_u(q, amount) ( (q).current -= (amount) ) + +#define quota_free_mem(t, where, amount) \ +__quota_free_u((where) < mem_high ? quota[(t)].mem : quota[(t)].himem, \ + (amount)) + +#define quota_free_task(t, where) __quota_free_u(quota[(t)].task, 1) + +#define quota_free_small(t, where) __quota_free_u(quota[(t)].small, 1) + +#define quota_free_irq(t, where) ( quota[(t)].irq.current &= ~(1L << (where))) + +#endif diff --git a/apps/rmgr/src/rmgr.c b/apps/rmgr/src/rmgr.c new file mode 100644 index 0000000..97b1d34 --- /dev/null +++ b/apps/rmgr/src/rmgr.c @@ -0,0 +1,658 @@ +#include +#include + +#include + +#include "config.h" +#include "exec.h" +#include "globals.h" +#include "memmap.h" +#include "memmap_lock.h" + +/* the interface we define */ +#include +#include "rmgr.h" + +extern int boot_mem_dump; + +#define MGR_BUFSIZE 1024 + +#define MGR_STACKSIZE 1024 +static char mgr_stack[MGR_STACKSIZE]; +static void mgr(void) L4_NORETURN; + +/* + * we better make this static because of limited stack size + */ +static char str_buf[MGR_BUFSIZE]; + +/* started from init() in startup.c */ +void +rmgr(void) +{ + l4_threadid_t pa, pr; + dword_t dummy; + l4_msgdope_t result; + + /* we (the main thread of this task) will serve as a pager for our + children. */ + + /* before that, we start threads for other services, e.g. resource + management */ + pa = my_pager; pr = my_preempter; + l4_thread_ex_regs(rmgr_super_id, + (dword_t) mgr, (dword_t)(mgr_stack + MGR_STACKSIZE), + &pr, &pa, &dummy, &dummy, &dummy); + + if (boot_mem_dump) + { + int c; + l4_i386_ipc_call(rmgr_super_id, + L4_IPC_SHORT_MSG, RMGR_MEM_MSG(RMGR_MEM_INFO), 0, + L4_IPC_SHORT_MSG, &dummy, &dummy, + L4_IPC_NEVER, &result); + printf("\rRMGR: Return continues, Esc panics"); + c = getchar(); + printf("\r%40s\r",""); + if (c == 27) + panic("RMGR: memory dumped"); + } + + /* now start serving the subtasks */ + pager(); +} + +/* resource manager */ + +/* defined here because of the lack of a better place */ +quota_t quota[TASK_MAX]; +owner_t __task[TASK_MAX]; +owner_t __small[SMALL_MAX]; + +struct grub_multiboot_info mb_info; +char mb_cmdline[0x1000]; + +unsigned first_task_module = 1; +unsigned first_not_bmod_task; +unsigned first_not_bmod_free_task; +unsigned first_not_bmod_free_modnr; +unsigned fiasco_symbols = 0; +unsigned fiasco_symbols_end; +__mb_mod_name_str mb_mod_names[MODS_MAX]; +l4_threadid_t mb_mod_ids[MODS_MAX] = { L4_INVALID_ID, }; + +static void mgr(void) +{ + int task; + l4_proto_t p; + dword_t arg, d1, d2, mcp; + void *desc; + int err, unhandled, do_log; + l4_threadid_t sender, partner, n, s; + l4_msgdope_t result; + l4_sched_param_t sched; + + struct + { + l4_fpage_t fp; + l4_msgdope_t size_dope; + l4_msgdope_t send_dope; +#if defined(__X_ADAPTION__) || defined(__VERSION_X__) + dword_t dw2[3]; +#else /* __X_ADAPTION__ */ + dword_t dw2[2]; +#endif /* __X_ADAPTION__ */ + l4_strdope_t data; + } msg; + + for (;;) + { + msg.size_dope = L4_IPC_DOPE(2, 1); + msg.send_dope = L4_IPC_DOPE(2, 1); + msg.data.rcv_size = MGR_BUFSIZE; + msg.data.rcv_str = (dword_t)str_buf; + err = l4_i386_ipc_wait(&sender, &msg, &p.request, &arg, L4_IPC_NEVER, + &result); + + while (!err) + { + /* we received a request here */ + + do_log = ((debug_log_mask & (1L << p.proto.proto)) + && (! (debug_log_types & 2) + || ((debug_log_types >> 16) == p.proto.action))); + + if (do_log && (debug_log_types & 1)) + printf("RMGR: Log: rcv from %x:%x: [0x%x, 0x%x], r = 0x%x\n", + sender.lh.high, sender.lh.low, p.request, arg, + result.msgdope); + + /* who's the allocation unit? */ + if (L4_IPC_MSG_DECEITED(result)) + check(l4_nchief(sender, &partner) == L4_NC_INNER_CLAN); + else + partner = sender; + +#if 0 /* currently, this assertion doesn't hold when using RMGR_TASK_CREATE */ + assert(task_owner(partner.id.task) == myself.id.task); +#endif + /* handle the supervisor protocol */ + + desc = L4_IPC_SHORT_MSG; + d1 = d2 = (dword_t) -1; + + unhandled = 0; + + if (partner.id.task > O_MAX) + { + /* OOPS.. can't help this sender. */ + unhandled = 1; + goto reply; + } + + switch (p.proto.proto) + { + case RMGR_RMGR: + switch (p.proto.action) + { + case RMGR_RMGR_PING: + d1 = 0; d2 = ~(p.proto.param); + break; + default: + unhandled = 1; + } + break; + case RMGR_TASK: + switch (p.proto.action) + { + case RMGR_TASK_DELETE: + /* delete a task we've created on behalf of this user */ + + case RMGR_TASK_GET: + /* transfer task create right for task no + p.proto.param to sender */ + if (p.proto.param >= TASK_MAX) + break; + + if (p.proto.action == RMGR_TASK_GET) + { + if (!task_alloc(p.proto.param, partner.id.task)) + break; + } + else + { + if (task_owner(p.proto.param) != partner.id.task) + break; + } + + last_pf[p.proto.param].pfa = -1; + last_pf[p.proto.param].eip = -1; + + n = sender; + n.id.task = p.proto.param; + n.id.chief = myself.id.task; /* XXX I hope the args + suffice for l4_task_new() */ + n = l4_task_new(n, + p.proto.action == RMGR_TASK_GET + ? sender.lh.low : myself.lh.low, + 0, 0, L4_NIL_ID); + + if (l4_is_nil_id(n) || p.proto.action == RMGR_TASK_DELETE) + { + task_free(p.proto.param, partner.id.task); + + if (l4_is_nil_id(n) && p.proto.action == RMGR_TASK_GET) + break; /* failed */ + } + + d1 = 0; + + break; + + case RMGR_TASK_SET_SMALL: + case RMGR_TASK_SET_PRIO: +#ifdef __L4_STANDARD__ + n.lh.low = arg; + + /* try to guess the high word of the thread id */ + n.lh.high = partner.lh.high; + if (! task_equal(n, partner)) + { + /* XXX only works for childs of partner */ + n.id.chief = partner.id.task; + n.id.nest++; + } +#else +# ifdef __L4_VERSION_X__ + n.raw = arg; +# else +# warning undefined L4 version +# endif +#endif + + s = L4_INVALID_ID; + l4_thread_schedule(n, L4_INVALID_SCHED_PARAM, &s, &s, &sched); +#ifdef __L4_STANDARD__ + if (l4_is_invalid_sched_param(sched)) /* error? */ + { + /* XXX another try... we talk about a child of sender */ + if (task_equal(sender, partner)) + break; + + n.id.chief = sender.id.task; + n.id.nest = sender.id.nest + 1; + + s = L4_INVALID_ID; + l4_thread_schedule(n, L4_INVALID_SCHED_PARAM, + &s, &s, &sched); + + if (l4_is_invalid_sched_param(sched)) /* error? */ + break; /* give up. */ + } +#endif /* __L4_STANDARD__ */ + + if (p.proto.action == RMGR_TASK_SET_SMALL) + { + if (! small_space_size || p.proto.param == 0 + || p.proto.param >= 128/small_space_size + || ! small_alloc(p.proto.param, partner.id.task)) + break; + + sched.sp.small = small_space_size + | (p.proto.param * small_space_size * 2); + s = L4_INVALID_ID; + l4_thread_schedule(n, sched, &s, &s, &sched); + } + else /* p.proto.action == RMGR_TASK_SET_PRIO */ + { + if (quota[partner.id.task].log_mcp < p.proto.param) + break; + + sched.sp.prio = p.proto.param; + s = L4_INVALID_ID; + l4_thread_schedule(n, sched, &s, &s, &sched); + } + + d1 = 0; + break; + + case RMGR_TASK_CREATE: + /* create a task; arg = task number, p.proto.param = mcp, + *(dword_t*)str_buf = esp, + *(dword_t*)(str_buf + 4) = eip, + *(l4_threadid_t*)(str_buf + 8) = pager */ + + if (result.msgdope != L4_IPC_DOPE(2, 1).msgdope) + break; /* must have 8 bytes indirect string data */ + +#ifdef __L4_STANDARD__ + n = myself; + n.id.chief = myself.id.task; + /* we use task id + version number to create the task */ + n.lh.low = arg; + /* n.id.nest++; */ +#else +# ifdef __L4_VERSION_X__ + n.raw = arg; +# else +# warning undefined L4 version +# endif +#endif + task = n.id.task; + + if (task >= TASK_MAX + || l4_is_nil_id(* (l4_threadid_t*)(str_buf + 8)) + || !task_alloc(task, partner.id.task)) + break; + + mcp = p.proto.param > quota[partner.id.task].log_mcp + ? quota[partner.id.task].log_mcp : p.proto.param; + + if (do_log) + printf("RMGR: Log: creating task=%x:%x, esp=%x, " + "eip=%x, pager=%x:%x, mcp=%d\n", + n.lh.high, n.lh.low, + * (dword_t*)str_buf, * (dword_t*)(str_buf + 4), + ((l4_threadid_t*)(str_buf + 8))->lh.high, + ((l4_threadid_t*)(str_buf + 8))->lh.low, + mcp); + + n = l4_task_new(n, mcp, * (dword_t*)str_buf, + * (dword_t*)(str_buf + 4), + * (l4_threadid_t*)(str_buf + 8)); + + if (l4_is_nil_id(n)) + { + task_free(task, partner.id.task); + break; + } + + /* XXX for now, just reset all quotas to their + minimal value */ + quota[task].mem.max = 0; + quota[task].himem.max = 0; + quota[task].task.max = 0; + quota[task].small.max = 0; + quota[task].irq.max = -1; //XXX: hack, I NEED a irq + quota[task].log_mcp = + p.proto.param > quota[partner.id.task].log_mcp + ? quota[partner.id.task].log_mcp : p.proto.param; + + d1 = n.lh.low; + d2 = n.lh.high; + + break; + + case RMGR_TASK_CREATE_WITH_PRIO: + /* create a task; + arg = task number, + p.proto.param = mcp, + *(dword_t*)str_buf = esp, + *(dword_t*)(str_buf + 4) = eip, + *(l4_threadid_t*)(str_buf + 8) = pager, + *(dword_t*)(str_buf + 16) = sched_param */ + + if (result.msgdope != L4_IPC_DOPE(2, 1).msgdope) + break; /* must have 8 bytes indirect string data */ + +#ifdef __L4_STANDARD__ + n = myself; + n.id.chief = myself.id.task; + /* we use task id + version number to create the task */ + n.lh.low = arg; + /* n.id.nest++; */ +#else +# ifdef __L4_VERSION_X__ + n.raw = arg; +# else +# warning undefined L4 version +# endif +#endif + task = n.id.task; + + /* extract schedule parameters */ + sched.sched_param = *(dword_t*)(str_buf + 16); + sched.sp.small = 0; + if (quota[partner.id.task].log_mcp < sched.sp.prio) + sched.sp.prio = quota[partner.id.task].log_mcp; + + if (task >= TASK_MAX + || l4_is_nil_id(* (l4_threadid_t*)(str_buf + 8)) + || !task_alloc(task, partner.id.task)) + break; + + if (do_log) + printf("RMGR: Log: creating task=%x:%x, esp=%x, " + "eip=%x, pager=%x:%x, sched_param: %lx, mcp: %x\n", + n.lh.high, n.lh.low, + * (dword_t*)str_buf, * (dword_t*)(str_buf + 4), + ((l4_threadid_t*)(str_buf + 8))->lh.high, + ((l4_threadid_t*)(str_buf + 8))->lh.low, + (unsigned long)sched.sched_param, p.proto.param); + /* XXX for now, use an L4-mcp of 0 */ + n = l4_task_new(n, 0, * (dword_t*)str_buf, + * (dword_t*)(str_buf + 4), + * (l4_threadid_t*)(str_buf + 8)); + + if (l4_is_nil_id(n)) + { + task_free(task, partner.id.task); + break; + } + + l4_thread_schedule(n, sched, &s, &s, &sched); + + /* XXX for now, just reset all quotas to their + minimal value */ + quota[task].mem.max = 0; + quota[task].himem.max = 0; + quota[task].task.max = 0; + quota[task].small.max = 0; + quota[task].irq.max = 0; + quota[task].log_mcp = + p.proto.param > quota[partner.id.task].log_mcp + ? quota[partner.id.task].log_mcp : p.proto.param; + + d1 = n.lh.low; + d2 = n.lh.high; + break; + + case RMGR_TASK_GET_ID: + /* default is error */ + d1 = L4_INVALID_ID.lh.low; + d2 = L4_INVALID_ID.lh.high; + if (result.msgdope == L4_IPC_DOPE(2, 1).msgdope) + { + int a; + /* fixme: configfile name should be ignored */ + for (a = first_task_module; a < mb_info.mods_count; a++) + { + char *ptr, *str; + int len; + + str = mb_mod_names[a]; + if ((ptr = strrchr(str, '/'))) + ptr++; + else + ptr = mb_mod_names[a]; + + if ( (len = strcspn(ptr, " "))>0 + && strncmp(ptr, str_buf, len)==0) + { + d1 = mb_mod_ids[a].lh.low; + d2 = mb_mod_ids[a].lh.high; + break; + } + } + } + break; + + case RMGR_TASK_SET_ID: + /* default is error */ + d1 = L4_INVALID_ID.lh.low; + d2 = L4_INVALID_ID.lh.high; + if (result.msgdope == L4_IPC_DOPE(2, 1).msgdope) + { + int a, b; + /* fixme: configfile name should be ignored */ + for (a = first_task_module; a < mb_info.mods_count; a++) + { + /* found in boot_modules */ + if (strcmp(mb_mod_names[a], str_buf) == 0) + { + mb_mod_ids[a].lh.low = sender.lh.low; + mb_mod_ids[a].lh.high = sender.lh.high; + mb_mod_ids[a].id.task = p.proto.param; + mb_mod_ids[a].id.lthread = 0; + mb_mod_ids[a].id.chief = arg; + d1 = d2 = 0; + break; + } + } + /* search in modules we only have the quotas of */ + for (b = first_not_bmod_task; + a < first_not_bmod_free_modnr; a++, b++) + { + if (strcmp(mb_mod_names[a], str_buf) == 0) + { + if (task_owner(p.proto.param)==partner.id.task) + { + memcpy("a[p.proto.param], "a[b], + sizeof(quota[0])); + d1 = d2 = 0; + break; + } + } + } + } + break; + + default: + unhandled = 1; + } + break; + + case RMGR_IRQ: + switch (p.proto.action) + { + case RMGR_IRQ_GET: + if (p.proto.param < IRQ_MAX) + { + if (irq_alloc(p.proto.param, partner.id.task)) + { + /* the irq was free -- detach from it */ + dword_t e1, e2; + n = myself; + n.id.lthread = LTHREAD_NO_IRQ(p.proto.param); + err = l4_i386_ipc_call(n, L4_IPC_SHORT_MSG, 1, 0, + L4_IPC_SHORT_MSG, &e1, &e2, + L4_IPC_NEVER, &result); + check(err == 0); + + if (e1 == 0) + d1 = 0; /* success! */ + else + /* fucked! (couldn't attach to irq number) */ + irq_free(p.proto.param, partner.id.task); + } + } + break; + + case RMGR_IRQ_FREE: + if (p.proto.param < IRQ_MAX + && irq_free(p.proto.param, partner.id.task)) + { + dword_t e1, e2; + n = myself; + n.id.lthread = LTHREAD_NO_IRQ(p.proto.param); + err = l4_i386_ipc_call(n, L4_IPC_SHORT_MSG, 0, 0, + L4_IPC_SHORT_MSG, &e1, &e2, + L4_IPC_NEVER, &result); + check(err == 0); + + if (e1 == 0) + d1 = 0; /* success! */ + } + break; + + default: + unhandled = 1; + } + break; + + case RMGR_MEM: + /* we must synchronise the access to memmap function */ + enter_memmap_functions(RMGR_LTHREAD_SUPER, rmgr_pager_id); + switch (p.proto.action) + { + case RMGR_MEM_FREE: + /* must contain physical address and owner (== task_no) */ + /* a bit of paranoia */ + if (arg >= 0x40000000 && arg < 0xC0000000) + { + arg += 0x40000000; + if((sender.id.task != memmap_owner_page(arg)) + || !memmap_free_superpage(arg, sender.id.task)) + { + d1 = -1; /* failure */ + } + else + { + /* we can't unmap page here because the superpage was + * granted so sender has to unmap page itself */ + d1 = 0; + } + } + else + { + if((sender.id.task != memmap_owner_page(arg)) + || !memmap_free_page(arg,sender.id.task)) + d1 = -1; /* failure */ + else { + /* unmap fpage */ + l4_fpage_unmap(l4_fpage(arg, L4_LOG2_PAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP), + L4_FP_FLUSH_PAGE|L4_FP_OTHER_SPACES); + d1 = 0; + } + } + break; + case RMGR_MEM_FREE_FP: + printf("RMGR: unable to handle free fpage request.\n"); + /* I don't know how to resolve the user's fpage + into a physical address + */ + d1 = -1; /* failure */ + break; + case RMGR_MEM_RESERVE: + /* reserve memory; arg = size_and_align, + *(dword_t*)str_buf = range_low, + *(dword_t*)(str_buf + 4) = range_high */ + if (result.msgdope != L4_IPC_DOPE(2, 1).msgdope) + break; /* must have 8 bytes indirect string data */ + + d1 = reserve_range(arg, partner.id.task, + *(dword_t*)str_buf, + *(dword_t*)(str_buf+4)); + break; + case RMGR_MEM_INFO: + show_mem_info(); + d1 = 0; + break; + case RMGR_MEM_GET_PAGE0: + d1 = 0; + d2 = l4_fpage(0, L4_LOG2_PAGESIZE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage; + desc = L4_IPC_SHORT_FPAGE; + break; + default: + unhandled = 1; + } + leave_memmap_functions(RMGR_LTHREAD_SUPER, rmgr_pager_id); + break; + default: + unhandled = 1; + } + + reply: + if (verbose && unhandled) + { + printf("RMGR: can't handle request=0x%x, data=0x%x " + "from thread=%x\n", p.request, arg, sender.lh.low); + } + + + if ((do_log && (debug_log_types & 1)) + || ((verbose || debug) && d1 == (dword_t)-1)) + { + if (d1 != 0 && !do_log) /* error, and request not yet logged */ + printf("RMGR: Log: rcv from %x:%x: [0x%x, 0x%x], r = 0x%x\n", + sender.lh.high, sender.lh.low, p.request, arg, + result.msgdope); + + printf("RMGR: Log: snd to %x:%x: [0x%x, 0x%x]\n", + sender.lh.high, sender.lh.low, d1, d2); + } + + if ((do_log && (debug_log_types & 4)) + || (debug && d1 == (dword_t)-1)) + enter_kdebug("rmgr>"); + + /* send reply and wait for next message */ +#if defined(__X_ADAPTION__) || defined(__VERSION_X__) + msg.size_dope = L4_IPC_DOPE(3, 1); +#else /* __X_ADAPTION__ */ + msg.size_dope = L4_IPC_DOPE(2, 1); +#endif /* __X_ADAPTION__ */ + msg.send_dope = L4_IPC_DOPE(2, 0); + msg.data.rcv_size = MGR_BUFSIZE; + msg.data.rcv_str = (dword_t)str_buf; + err = l4_i386_ipc_reply_and_wait(sender, desc, d1, d2, + &sender, &msg, &p.request, &arg, + L4_IPC_TIMEOUT(0,1,0,0,0,0), + /* snd timeout = 0 */ + &result); + } + } +} + diff --git a/apps/rmgr/src/rmgr.h b/apps/rmgr/src/rmgr.h new file mode 100644 index 0000000..3786806 --- /dev/null +++ b/apps/rmgr/src/rmgr.h @@ -0,0 +1,30 @@ +#ifndef RMGR_H +#define RMGR_H + +#include +#include + +#include "irq.h" +#include "task.h" +#include "small.h" +#include "quota.h" +#include "init.h" + +extern struct grub_multiboot_info mb_info; + +extern unsigned first_task_module; +extern unsigned first_not_bmod_task; +extern unsigned first_not_bmod_free_task; +extern unsigned first_not_bmod_free_modnr; +extern unsigned fiasco_symbols; +extern unsigned fiasco_symbols_end; + +#define MOD_NAME_MAX 1000 +typedef char __mb_mod_name_str[MOD_NAME_MAX]; +extern __mb_mod_name_str mb_mod_names[MODS_MAX]; +extern l4_threadid_t mb_mod_ids[MODS_MAX]; +extern char mb_cmdline[0x1000]; + +void rmgr(void) L4_NORETURN; + +#endif diff --git a/apps/rmgr/src/rmgr.ld b/apps/rmgr/src/rmgr.ld new file mode 100644 index 0000000..57b93ba --- /dev/null +++ b/apps/rmgr/src/rmgr.ld @@ -0,0 +1,46 @@ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x00180000; + + .init : + { + *(.init) + startup.o(.text .rodata .data .bss COMMON) + init.o(.text .rodata .data .bss COMMON) + cfg-parse.o(.text .rodata .data .bss COMMON) + cfg-mem.o(.text .rodata .data .bss COMMON) + } =0x9090 + + . = ALIGN(0x1000); + + _stext = .; + + .text : + { + *(.text) + } =0x9090 + + _etext = .; + PROVIDE (etext = .); + + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(0x1000) + ((ALIGN(8) + 0x1000 - ALIGN(0x1000)) & (0x1000 - 1)); + .data : + { + *(.rodata) + *(.data) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .bss : + { + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/apps/rmgr/src/small.h b/apps/rmgr/src/small.h new file mode 100644 index 0000000..4e98dcf --- /dev/null +++ b/apps/rmgr/src/small.h @@ -0,0 +1,57 @@ +#ifndef SMALL_H +#define SMALL_H + +#include + +#include + +#include "globals.h" +#include "quota.h" + +L4_INLINE void small_init(void); +L4_INLINE int small_alloc(unsigned smallno, owner_t owner); +L4_INLINE int small_free(unsigned smallno, owner_t owner); +L4_INLINE owner_t small_owner(unsigned smallno); + +#define SMALL_MAX 128 + +extern owner_t __small[SMALL_MAX]; + +L4_INLINE void small_init(void) +{ + memset(__small, O_RESERVED, SMALL_MAX); +} + +L4_INLINE int small_alloc(unsigned smallno, owner_t owner) +{ + if (__small[smallno] == owner) + return 1; + if (__small[smallno] != O_FREE) + return 0; + + if (! quota_alloc_small(owner, smallno)) + return 0; + + __small[smallno] = owner; + return 1; +} + +L4_INLINE int small_free(unsigned smallno, owner_t owner) +{ + if (__small[smallno] != owner && __small[smallno] != O_FREE) + return 0; + + if (__small[smallno] != O_FREE) + { + quota_free_small(owner, smallno); + __small[smallno] = O_FREE; + } + return 1; +} + +L4_INLINE owner_t small_owner(unsigned smallno) +{ + return __small[smallno]; +} + +#endif diff --git a/apps/rmgr/src/startup.c b/apps/rmgr/src/startup.c new file mode 100644 index 0000000..53bc4c3 --- /dev/null +++ b/apps/rmgr/src/startup.c @@ -0,0 +1,1014 @@ +/* startup stuff */ + +/* it should be possible to throw away the text/data/bss of the object + file resulting from this source -- so, we don't define here + anything we could still use at a later time. instead, globals are + defined in globals.c */ + +/* OSKit stuff */ + +#include +#include +#include + +/* L4 stuff */ +#include + +/* local stuff */ +#include "exec.h" +#include "globals.h" +#include "rmgr.h" +#include "init.h" + +void startup(struct multiboot_info *mbi, unsigned int flag); + +static exec_read_exec_func_t l4_exec_read_exec; +static vm_offset_t l4_low, l4_high; + +static int +check_l4_version(char *start, char *end) +{ + char *p; + + no_pentium = 0; + + printf("check_l4_version %p to %p\n", start, end); + + for (p = start; p < end; p++) + { + if (memcmp(p, "L4/486 \346-Kernel", 15) == 0) + { + int m4_ok; + + printf("RMGR: detected L4/486\n"); + no_pentium = 1; + + /* remove old 4M event */ + m4_ok = 0; + for (p=start; pentry; + assert(0x00001000 <= l4i->sigma0_eip && l4i->sigma0_eip < 0x000a0000); + /* XXX can't think of more sanity checks that l4i really points to + the L4 kernel info page :-( */ + + /* XXX undocumented */ + l4i->reserved1.low = l4i->reserved1.high = 0; + for (i = 2; i < 4; i++) + l4i->dedicated[i].low = l4i->dedicated[i].high = 0; + + if (mb_mod[0].string) /* do we have a command line for L4? */ + { + /* more undocumented stuff: process kernel options */ + if (strstr((char *) mb_mod[0].string, "hercules")) + { + unsigned char *kd_init = + (char *)((vm_offset_t)l4i - 0x1000 + l4i->init_default_kdebug); + + assert(kd_init[0] == 0xb0 && kd_init[1] == 'a'); + kd_init[1] = 'h'; + } + + if (strstr((char *) mb_mod[0].string, "nowait")) + { + unsigned char *kd_debug; + int nowait_ok = 0; + + for(kd_debug = (unsigned char *) l4_low; + kd_debug < (unsigned char *) l4_low + (l4_high - l4_low); + kd_debug++) + { + /* check for machine code + "int $3; jmp 0f; .ascii "debug"; 0:" */ + if (memcmp(kd_debug, "\314\353\005debug", 8) == 0) + { + kd_debug[0] = 0x90; /* replace "int $3" by "nop" */ + nowait_ok = 1; + break; + } + } + assert(nowait_ok); + } + + /* all those serial port related options */ + { + unsigned short portaddr = 0x02F8; /* This is COM2, the default */ + unsigned short divisor = 1; /* 115200 bps */ + unsigned char* ratetable = 0; + + if (strstr((char *) mb_mod[0].string, " -comport")) + { + unsigned port; + unsigned char* p_adr; + + const unsigned char port_adr_hi[] = {0x00, 0x3F, 0x2F, 0x3E, 0x2E}; + + port = strtoul((strstr((char *) mb_mod[0].string, " -comport") + + strlen(" -comport")), NULL, 10); + + if (port) + { + p_adr = scan_kernel("\270\003\207\057\000"); + if (p_adr) + { + printf("RMGR: Setting COM%d as L4KD serial port\n", port); + p_adr[3] = port_adr_hi[port]; + portaddr = (port_adr_hi[port] << 4) | 0x8; + } + } + else + printf("RMGR: INVALID serial port\n"); + } + + if (strstr((char *) mb_mod[0].string, " -comspeed")) + { + unsigned rate; + + rate = strtoul((strstr((char *) mb_mod[0].string, " -comspeed") + + strlen(" -comspeed")), NULL, 10); + + if (rate) + { + /* check for rate table + dw 192, dw 96, dw 48, dw 24, ... + the 7th entry is used by default */ + ratetable = scan_kernel("\300\000\140\000\060\000\030\000"); + if (ratetable) + { + printf("RMGR: Setting L4KD serial port rate to %d bps\n", rate); + ((short*) ratetable)[7] = 115200/rate; + divisor = 115200/rate; + } + } + else + printf("RMGR: INVALID serial rate\n"); + } + + if (strstr((char *) mb_mod[0].string, " -VT")) + { + + if (!ratetable) + ratetable = scan_kernel("\300\000\140\000\060\000\030\000"); + + if (ratetable) + { + printf("RMGR: Enabling serial terminal at %3x, %d bps\n", portaddr, 115200/divisor); + /* Uaah, the word before the rate table holds the port address for remote_outchar */ + ((short*) ratetable)[-1] = portaddr; + + /* initialize the serial port */ + asm("mov $0x83,%%al;add $3,%%dx;outb %%al,%%dx;" + "sub $3,%%dx;mov %%bx,%%ax;outw %%ax,%%dx;add $3,%%dx;" + "mov $0x03,%%al;outb %%al,%%dx;dec %%dx;inb %%dx,%%al;" + "add $3,%%dx;inb %%dx,%%al;sub $3,%%dx;inb %%dx,%%al;" + "sub $2,%%dx;inb %%dx,%%al;add $2,%%dx;inb %%dx,%%al;" + "add $4,%%dx;inb %%dx,%%al;sub $4,%%dx;inb %%dx,%%al;" + "dec %%dx;xor %%al,%%al;outb %%al,%%dx;mov $11,%%al;" + "add $3,%%dx;outb %%al,%%dx\n" + : + /* no output */ + : + "d" (portaddr), + "b" (divisor) + : + "eax" + ); + + if (strstr((char *) mb_mod[0].string, " -VT+")) + { + unsigned char* p; + if ((p = scan_kernel("\203\370\377\165\034\350"))) + { + p[-6] = 1; + printf("RMGR: -VT+ mode enabled\n"); + }; + } + } + + } + + if (strstr((char *) mb_mod[0].string, " -I+")) + { + + /* idea: + in init_timer the idt_gate is set up for the timer irq handler. + There we install the kdebug_timer_intr_handler. + in kdebug_timer... timer_int is called (saved location of timer_int) */ + + unsigned long timer_int, kdebug_timer_intr_handler; + void* real_location; + void* tmp_location; + unsigned long relocation; + + unsigned short* new; + void* p; + void* dest; + + /* find remote_info_port */ + tmp_location = scan_kernel("\300\000\140\000\060\000\030\000"); + if (tmp_location) + tmp_location -= 2; + + /* find reference to remote_info_port */ + real_location = scan_kernel("\146\201\342\377\017"); + if (real_location) + real_location = (void*) ((unsigned long) (((unsigned short*) real_location)[4])); + + relocation = tmp_location - real_location; + + /* find the place where the timer_int is set up */ + p = scan_kernel("\000\000" /* this is a bit illegal !!!*/ + "\303" /* c3 */ + "\263\050" /* b3 28 */ + "\267\000" /* b7 00 */ + "\270" /* b8 */ + ); + if (p) + { + timer_int = ((unsigned long*)p)[2]; + + /* find kdebug_timer_intr_handler */ + dest = scan_kernel("\152\200\140\036\152\010" + "\037\314\074\014\074\033"); + /* no more comments */ + if (dest) + { + kdebug_timer_intr_handler = (((unsigned long) dest) - relocation); + ((unsigned long*)p)[2] = kdebug_timer_intr_handler; + dest = scan_kernel("\015\260\055\314" + ); + if (dest) + { + new = (unsigned short*) ((((unsigned short*)dest)[-5]) + relocation); + *new = timer_int; + printf("RMGR: I+ enabled\n"); + }; + }; + }; + }; + } + + /* + This option disables the patch that eliminates the miscalculation + of string offsets in messages containing indirect strings + + The patch changes calculation of the first string's offset in the + message buffer (in ipc_strings). + This offset was calculated + + addr(msgbuffer) + offset(dword_2) + 4*number_of_dwords + + this is changed to + addr(msgbuffer) + offset(dword_0) + 4*number_of_dwords + ^^^^^^^ + */ + if (strstr((char *) mb_mod[0].string, " -disablestringipcpatch")) + printf("RMGR: string IPC patch disabled\n"); + else + { + unsigned char* patchme; + patchme = scan_kernel("\024\213\126\004\301\352\015\215\164\226\024"); + if (patchme) + { + patchme[0] = 0x0c; + patchme[10] = 0x0c; + printf("RMGR: string IPC patch applied\n"); + } + else + printf("RMGR: string IPC patch not applied - signature not found\n"); + }; + + /* heavy undocumented stuff, we simply patch the kernel to get + access to irq0 and to be able to use the high resolution timer */ + if (strstr((char *) mb_mod[0].string, "irq0")) + { + unsigned char *kd_debug; + int irq0_ok = 0; + + for(kd_debug = (unsigned char *) l4_low; + kd_debug < (unsigned char *) l4_low + (l4_high - l4_low); + kd_debug++) + { + /* check for byte sequence + 0xb8 0x01 0x01 0x00 0x00 0xe8 ?? ?? ?? ?? 0x61 0xc3 */ + if (memcmp(kd_debug, "\270\001\001\000\000\350", 6) == 0) + { + if ((kd_debug[10] == 0141) && (kd_debug[11] == 0303)) + { + kd_debug[1] = '\0'; /* enable irq0 */ + irq0_ok = 1; + break; + } + } + } + assert(irq0_ok); + } + + /* boot L4 in real-mode (for old versions) */ + if (strstr((char *) mb_mod[0].string, "boothack")) + { + /* find "cmpl $0x2badb002,%eax" */ + vm_offset_t dest + = (vm_offset_t) scan_kernel("\075\002\260\255\053"); + + if (dest) + exec_info->entry = dest; + } + } +} + +static void +init_nucleus(l4_kernel_info_t* l4i) { + unsigned i; + + // for consistency with Dresden we always enter the kernel debugger... + l4i->kdebug_config = 0x100; + + /* assertion: the entry point is at the beginning of the kernel info + page */ + + assert(0x00001000 <= l4i->sigma0_eip && l4i->sigma0_eip < 0x000a0000); + /* XXX can't think of more sanity checks that l4i really points to + the L4 kernel info page :-( */ + + l4i->reserved1.low = l4i->reserved1.high = 0; + for (i = 2; i < 4; i++) + l4i->dedicated[i].low = l4i->dedicated[i].high = 0; + + if (mb_mod[0].string) /* do we have a command line for L4? */ + { + /* more undocumented stuff: process kernel options */ + if (strstr((char *) mb_mod[0].string, "hercules")) + { + printf("IBM's Nucleus does not support hercules as setting\n"); + } + + if (strstr((char *) mb_mod[0].string, "nowait")) + { + l4i->kdebug_config &= ~0x100; + } + + /* all those serial port related options */ + { + if (strstr((char *) mb_mod[0].string, " -comport")) + { + unsigned port; + const unsigned char port_adr_hi[] = {0x00, 0x3F, 0x2F, 0x3E, 0x2E}; + + port = strtoul((strstr((char *) mb_mod[0].string, " -comport") + + strlen(" -comport")), NULL, 10); + + if (port) + { + printf("RMGR: Setting COM%d as L4KD serial port\n", port); + l4i->kdebug_config |= ((port_adr_hi[port] << 4 | 0x8) << 20) & + 0xfff00000; + } + else + printf("RMGR: INVALID serial port\n"); + } + + if (strstr((char *) mb_mod[0].string, " -comspeed")) + { + unsigned rate; + + rate = strtoul((strstr((char *) mb_mod[0].string, " -comspeed") + + strlen(" -comspeed")), NULL, 10); + + if (rate) + { + l4i->kdebug_config |= ((115200/rate) << 16) & 0xf0000; + } + else + printf("RMGR: INVALID serial rate\n"); + } + + if (strstr((char *) mb_mod[0].string, " -VT")) + { + // set to serial + if (strstr((char *) mb_mod[0].string, " -VT+")) + { + printf("RMGR: VT-option does not exist - use comspeed/port instead\n"); + } + } + + } // end of comport-related stuff + + + if (strstr((char *) mb_mod[0].string, "-tracepages")) + { + unsigned tracepages; + + tracepages = strtoul((strstr((char *) mb_mod[0].string, " -tracepages") + + strlen(" -tracepages")), NULL, 10); + if (tracepages) { + l4i->kdebug_config |= (tracepages & 0xff); + printf("RMGR: debugger configured with %d trace pages\n", + tracepages); + } + else + printf("RMGR: invalid tracepage number\n"); + + } + + if (strstr((char *) mb_mod[0].string, "-lastdebugtask")) + { + unsigned ldtask; + + ldtask = strtoul((strstr((char *) mb_mod[0].string, " -lastdebugtask") + + strlen(" -lastdebugtask")), NULL, 10); + if (ldtask) { + l4i->kdebug_permission |= (ldtask & 0xff); + printf("RMGR: debugger can be invoked by task 0 to %d", + ldtask); + } + else + printf("RMGR: invalid debug task number\n"); + + } + + if (strstr((char *) mb_mod[0].string, "-d-no-mapping")) + { + l4i->kdebug_config &= ~0x100; + } + + if (strstr((char *) mb_mod[0].string, "-d-no-registers")) + { + l4i->kdebug_config &= ~0x200; + } + + if (strstr((char *) mb_mod[0].string, "-d-no-memory")) + { + l4i->kdebug_config &= ~0x400; + } + + if (strstr((char *) mb_mod[0].string, "-d-no-modif")) + { + l4i->kdebug_config &= ~0x800; + } + + if (strstr((char *) mb_mod[0].string, "-d-no-io")) + { + l4i->kdebug_config &= ~0x1000; + } + + if (strstr((char *) mb_mod[0].string, "-d-no-protocol")) + { + l4i->kdebug_config &= ~0x1000; + } + + + + + } + else + printf("no configuration string for the nucleus\n"); + + printf("RMGR: kernel-debug config: %x, %x\n", + l4i->kdebug_config, l4i->kdebug_permission); +} + +extern void pci_reloc(void); + +/* started from crt0.S */ +void +startup(struct multiboot_info *mbi, unsigned int flag) +{ + l4_kernel_info_t *l4i; + static struct grub_multiboot_info l4_mbi; + exec_info_t exec_info; + int exec_ret; + + int i; + + vm_offset_t sigma0_low = 0, sigma0_high = 0, sigma0_start = 0, + sigma0_stack = 0; /* zero-initialized to avoid spurious warnings */ + int have_sigma0 = 0; + struct exec_task e; + + vm_offset_t roottask_low = 0, roottask_high = 0, roottask_start = 0, + roottask_stack = 0; /* zero-initialized to avoid spurious warnings */ + int have_roottask = 0; + + /* we're not an L4 task yet -- we're just a GRUB-booted kernel */ + + assert(flag == MULTIBOOT_VALID); /* we need to be multiboot-booted */ + + assert(mbi->flags & MULTIBOOT_MODS); /* we need at least two boot modules: */ + assert(mbi->mods_count >= 2); /* 1 = L4 kernel, 2 = first user task */ + + assert(mbi->mods_count <= MODS_MAX); + + /* print RMGR messages on hercules screen? */ + if ((mbi->flags & MULTIBOOT_CMDLINE) + && strstr((char *) mbi->cmdline, " -hercules") + && have_hercules()) + hercules = 1; + + if ((mbi->flags & MULTIBOOT_CMDLINE) + && strstr((char *) mbi->cmdline, "-maxmem")) + { + mbi->mem_upper = 1024*(strtoul((strstr((char *) mbi->cmdline, " -maxmem") + strlen(" -maxmem")), NULL, 10) - 1); + printf("RMGR: limiting memory to %d MB (%d KB)\n", mbi->mem_upper/1024+1, mbi->mem_upper); + } + + /* Guess the amount of installed memory from the bootloader. We already + * need that value here because we have to check for a valid L4 kernel. + * Later (in init.c), mem_high is determined by the sigma0 server. */ + mem_high = mem_phys = 64*1024*1024; + if (mbi->flags & MULTIBOOT_MEMORY) + mem_high = mem_phys = 1024 * (mbi->mem_upper + mbi->mem_lower); + + /* copy Multiboot data structures we still need to a safe place + before playing with memory we don't own and starting L4 */ + + /* rmgr.c defines variables holding copies */ + if (mbi->flags & MB_INFO_VIDEO_INFO) + /* extended VIDEO information available */ + { + struct grub_multiboot_info *gmbi = (struct grub_multiboot_info*)mbi; + + printf("RMGR: Using extended multiboot info\n"); + + /* copy extended multiboot info structure */ + memcpy(&mb_info, mbi, sizeof(struct grub_multiboot_info)); + + /* copy VBE mode info structure */ + if (gmbi->vbe_mode_info) + { + memcpy(&mb_vbe_mode, (void*)(gmbi->vbe_mode_info), + sizeof(struct vbe_mode)); + mb_info.vbe_mode_info = (vm_offset_t) &mb_vbe_mode; + } + + /* copy VBE controller info structure */ + if (gmbi->vbe_control_info) + { + memcpy(&mb_vbe_cont, (void*)(gmbi->vbe_control_info), + sizeof(struct vbe_controller)); + mb_info.vbe_control_info = (vm_offset_t) &mb_vbe_cont; + } + + mb_info.flags &= (MB_INFO_MEMORY | MB_INFO_BOOTDEV | + MB_INFO_CMDLINE | MB_INFO_MODS | + MB_INFO_AOUT_SYMS | MB_INFO_ELF_SHDR | + MB_INFO_MEM_MAP | MB_INFO_VIDEO_INFO); + } + + else + /* extended VIDEO information not available, perhaps we use the old GRUB + * so only copy the reliable information */ + { + /* copy simple (old) multiboot structure */ + memcpy(&mb_info, mbi, sizeof(struct multiboot_info)); + mb_info.flags &= (MULTIBOOT_MEMORY | MULTIBOOT_BOOT_DEVICE | + MULTIBOOT_CMDLINE | MULTIBOOT_MODS | + MULTIBOOT_AOUT_SYMS | MULTIBOOT_ELF_SHDR | + MULTIBOOT_MEM_MAP); + } + + /* copy module descriptions */ + memcpy(mb_mod, (void *) mbi->mods_addr, + mbi->mods_count * sizeof (struct multiboot_module)); + mb_info.mods_addr = (vm_offset_t) mb_mod; + + for (i = 0; i < mbi->mods_count; i++) + { + char *name = (char *) mb_mod[i].string; + + strncpy(mb_mod_names[i], name ? name : "[unknown]", MOD_NAME_MAX); + mb_mod_names[i][MOD_NAME_MAX-1] = '\0'; /* terminate string */ + if (name) + mb_mod[i].string = (vm_offset_t) mb_mod_names[i]; + } + + if (mb_info.flags & MULTIBOOT_CMDLINE) + { + strncpy(mb_cmdline, (char *) (mb_info.cmdline), sizeof(mb_cmdline)); + mb_cmdline[sizeof(mb_cmdline) - 1] = 0; + mb_info.cmdline = (vm_offset_t) mb_cmdline; + } + /* shouldn't touch original Multiboot parameters after here */ + + /* compute range for modules which we must not overwrite during + booting the startup tasks */ + mod_exec_init(mb_mod, 0, mb_info.mods_count); + + /* lets look if we have a user-specified sigma0 */ + if ((mb_info.flags & MULTIBOOT_CMDLINE) + && strstr((char *) mb_info.cmdline, " -sigma0")) + { + /* we define a small stack for sigma0 here -- it is used by L4 + for parameter passing to sigma0. however, sigma0 must switch + to its own private stack as soon as it has initialized itself + because this memory region is later recycled in init.c */ + static char sigma0_init_stack[64]; /* XXX hardcoded */ + + l4_low = 0xffffffff; + l4_high = 0; + + assert(mb_info.mods_count >= (first_task_module + 2)); /* need one more module -- sigma0 */ + + printf("RMGR: loading %s\n", + mb_mod[1].string ? (char *) mb_mod[1].string : "[SIGMA0]"); + + e.mod_start = (void *)(mb_mod[first_task_module].mod_start); + e.task_no = first_task_module; + e.mod_no = first_task_module; + exec_load(mod_exec_read, l4_exec_read_exec, + &e, &exec_info); + + sigma0_low = l4_low & L4_PAGEMASK; + sigma0_high = (l4_high + (L4_PAGESIZE-1)) & L4_PAGEMASK; + sigma0_start = exec_info.entry; + sigma0_stack = + (vm_offset_t)(sigma0_init_stack + sizeof(sigma0_init_stack)); + + have_sigma0 = 1; + first_task_module++; + } + + /* lets look if we want to use rmgr just for loading and configuring the kernel */ + if ((mb_info.flags & MULTIBOOT_CMDLINE) + && strstr((char *) mb_info.cmdline, "-roottask")) + { + /* we define a small stack for roottask here -- it is used by L4 + for parameter passing to roottask. however, roottask must switch + to its own private stack as soon as it has initialized itself + because this memory region is later recycled in init.c */ + static char roottask_init_stack[64]; /* XXX hardcoded */ + + l4_low = 0xffffffff; + l4_high = 0; + +// assert(mb_info.mods_count >= (first_task_module + 2)); /* need one more module -- roottask */ + + printf("RMGR: loading %s\n", + mb_mod[first_task_module].string ? (char *) mb_mod[first_task_module].string : "[ROOTTASK]"); + + e.mod_start = (void *)(mb_mod[first_task_module].mod_start); + e.task_no = first_task_module; + e.mod_no = first_task_module; + exec_ret = exec_load(mod_exec_read, l4_exec_read_exec, + &e, &exec_info); + if (exec_ret) + exec_ret = exec_load_pe(mod_exec_read, l4_exec_read_exec, + (void *)(mb_mod[first_task_module].mod_start), &exec_info); + + roottask_low = l4_low & L4_PAGEMASK; + roottask_high = (l4_high + (L4_PAGESIZE-1)) & L4_PAGEMASK; + roottask_start = exec_info.entry; + roottask_stack = + (vm_offset_t)(roottask_init_stack + sizeof(roottask_init_stack)); + + have_roottask = 1; + first_task_module++; + } + + if ((mb_info.flags & MULTIBOOT_CMDLINE) + && strstr((char *) mb_info.cmdline, " -symbols")) + { + printf("RMGR: loading %s\n", + mb_mod[first_task_module].string + ? (char *) mb_mod[first_task_module].string : "[SYMBOLS]"); + + e.mod_start = (void *)mb_mod[first_task_module].mod_start; + e.task_no = 0; + e.mod_no = first_task_module; + exec_load(mod_exec_read, l4_exec_read_exec, + &e, &exec_info); + + fiasco_symbols = mb_mod[first_task_module].mod_start; + fiasco_symbols_end = (mb_mod[first_task_module].mod_end + + L4_PAGESIZE - 1) & L4_PAGEMASK; + + first_task_module++; + } + + if ((mb_info.flags & MULTIBOOT_CMDLINE) + && strstr((char *) mb_info.cmdline, " -mods=")) + { + last_task_module = atoi (strstr((char *) mb_info.cmdline, " -mods=") + 7); + } + + l4_low = 0xffffffff; + l4_high = 0; + + /* the first module is the L4 microkernel; load it */ + e.mod_start = (void *)mb_mod[0].mod_start; + e.task_no = 0; + e.mod_no = 0; + exec_load(mod_exec_read, l4_exec_read_exec, + &e, &exec_info); + + /* XXX we don't look at the Multiboot header of the L4 kernel image */ + + /* check for L4 version */ + l4_version = check_l4_version((unsigned char *) l4_low, + (unsigned char *) l4_low + (l4_high - l4_low)); + + if ((l4_version != VERSION_FIASCO) && fiasco_symbols) + { + printf("RMGR: L4 version is not Fiasco -- disabling Fiasco symbols\n"); + fiasco_symbols = 0; + } + + switch (l4_version) { + case VERSION_L4_V2: + l4i = (l4_kernel_info_t *) exec_info.entry; + init_jochen_dd_version(l4i, &exec_info); break; + + case VERSION_L4_IBM: + l4i = (l4_kernel_info_t *) exec_info.entry; + init_nucleus(l4i); break; + + case VERSION_PISTACHIO: + case VERSION_L4_KA: + { + unsigned char * p; + //no_pentium = 1; + l4i = 0; + printf("find kernel info page...\n"); + for (p = (unsigned char *) (l4_low & 0xfffff000); + p < (unsigned char *) l4_low + (l4_high - l4_low); + p += 0x1000) + { + dword_t magic = L4_KERNEL_INFO_MAGIC; + if (memcmp(p, &magic, 4) == 0) + { + l4i = (l4_kernel_info_t *) p; + printf("found kernel info page at %p\n", p); + break; + } + } + assert(l4i); + l4i->reserved0.low = l4_low; + l4i->reserved0.high = l4_high; + } + break; + + case VERSION_FIASCO: + { + static char cmdline[256]; + int l; + + /* use an info page prototype allocated from our address space; + this will be copied later into the kernel's address space */ + static char proto[L4_PAGESIZE]; + + memset(proto, 0, L4_PAGESIZE); + l4i = (l4_kernel_info_t *) proto; + + /* append address of kernel info prototype to kernel's command + line */ + if (mb_mod[0].string) + { + l = strlen((char *) mb_mod[0].string); + /* make sure it fits into cmdline[] */ + assert(l < sizeof(cmdline) - 40); + strcpy(cmdline, (char *) mb_mod[0].string); + } + else + l = 0; + + sprintf(cmdline + l, " proto=0x%x", (vm_offset_t) proto); + mb_mod[0].string = (vm_offset_t) cmdline; + } break; + default: + l4i = 0; + printf("RMGR: could not identify version of the kernel\n"); + getchar(); + } + + /* setup the L4 kernel info page before booting the L4 microkernel: + patch ourselves into the booter task addresses */ + l4i->root_esp = (dword_t) &_stack; + l4i->root_eip = (dword_t) init; +#if 0 + l4i->root_memory.low = l4i->dedicated[0].low = (dword_t) &_start; + l4i->root_memory.high = l4i->dedicated[0].high = (dword_t) &_end; +#else + l4i->root_memory.low = ((dword_t) &_start) & L4_PAGEMASK; + l4i->root_memory.high = (((dword_t) &_end) + (L4_PAGESIZE-1)) & L4_PAGEMASK; +#endif + + /* set up sigma0 info */ + if (have_sigma0) + { + printf("configuring s0: (%p, %p), start: %p\n", sigma0_low, sigma0_high, sigma0_start); + + l4i->sigma0_eip = sigma0_start; + l4i->sigma0_memory.low = sigma0_low; + l4i->sigma0_memory.high = sigma0_high; + + printf("s0 config: %p,%p,%p,%p\n", l4i->sigma0_eip, l4i->sigma0_esp, + l4i->sigma0_memory.low, l4i->sigma0_memory.high); + + /* XXX UGLY HACK: Jochen's kernel can't pass args on a sigma0 + stack not within the L4 kernel itself -- therefore we use the + kernel info page itself as the stack for sigma0. the field + we use is the task descriptor for the unused "ktest2" task */ + switch (l4_version) { + case VERSION_L4_V2: + case VERSION_L4_IBM: + l4i->sigma0_esp = 0x1060; + break; + case VERSION_FIASCO: + l4i->sigma0_esp = sigma0_stack; + break; + } + } + + /* set up roottask info */ + if (have_roottask) + { + printf("configuring roottask: (%p, %p), start: %p\n", roottask_low, roottask_high, roottask_start); + + l4i->root_eip = roottask_start; + l4i->root_memory.low = roottask_low; + l4i->root_memory.high = roottask_high; + printf("roottask config: %p,%p,%p,%p\n", l4i->root_eip, l4i->root_esp, + l4i->root_memory.low, l4i->root_memory.high); + } + + /* reserve memory for the modules */ + mod_exec_init(mb_mod, 1, mb_info.mods_count); + + printf("RMGR: reserve modules memory range: %x to %x\n", + mod_range_start, mod_range_end); + + l4i->dedicated[1].low = mod_range_start; + l4i->dedicated[1].high = mod_range_end; + + l4i->main_memory.low = 0; + l4i->main_memory.high = (mb_info.mem_upper + 1024) * 1024; + l4i->dedicated[0].low = mb_info.mem_lower * 1024; + l4i->dedicated[0].high = 1024*1024; + + /* now boot the L4 microkernel in a multiboot-compliant way */ + + if (l4_version == VERSION_PISTACHIO) + { + /* Pistachio has a slightly different way of starting + * tasks. The boot loader has a dedicated field in the + * kernel interface page to boot the root task. + */ + ((dword_t*)l4i)[46] = (dword_t)&mb_info; + + /* clear the memory-info field */ + ((dword_t*)l4i)[21] &= 0xffff0000; + } + + l4_mbi = mb_info; + assert(l4_mbi.flags & MULTIBOOT_MEMORY); + l4_mbi.flags = MULTIBOOT_MEMORY | MULTIBOOT_MODS; + if (mb_mod[0].string) + { + l4_mbi.cmdline = mb_mod[0].string; + l4_mbi.flags |= MULTIBOOT_CMDLINE; + } + + printf("RMGR: starting %s @ %p\n", + mb_mod[0].string ? (char *) mb_mod[0].string : "[L4]", exec_info.entry); + +//printf("RMGR: pci_reloc\n"); +//pci_reloc(); + kernel_running = 1; + + asm volatile + ("pushl $" SYMBOL_NAME_STR(exit) " + pushl %2 + ret" + : /* no output */ + : "a" (MULTIBOOT_VALID), "b" (&l4_mbi), "r" (exec_info.entry)); + + /*NORETURN*/ + +} + + +static int l4_exec_read_exec(void *handle, + vm_offset_t file_ofs, vm_size_t file_size, + vm_offset_t mem_addr, vm_size_t mem_size, + exec_sectype_t section_type) +{ + if (! (section_type & EXEC_SECTYPE_ALLOC)) + return 0; + + if (mem_addr < l4_low) l4_low = mem_addr; + if (mem_addr + mem_size > l4_high) l4_high = mem_addr + mem_size; + + return mod_exec_read_exec(handle, file_ofs, file_size, + mem_addr, mem_size, section_type); +} + diff --git a/apps/rmgr/src/task.h b/apps/rmgr/src/task.h new file mode 100644 index 0000000..ec3f3c5 --- /dev/null +++ b/apps/rmgr/src/task.h @@ -0,0 +1,55 @@ +#ifndef TASK_H +#define TASK_H + +#include + +#include + +#include "globals.h" +#include "quota.h" + +L4_INLINE void task_init(void); +L4_INLINE int task_alloc(unsigned taskno, owner_t owner); +L4_INLINE int task_free(unsigned taskno, owner_t owner); +L4_INLINE owner_t task_owner(unsigned taskno); + +extern owner_t __task[TASK_MAX]; + +L4_INLINE void task_init(void) +{ + memset(__task, O_RESERVED, TASK_MAX); +} + +L4_INLINE int task_alloc(unsigned taskno, owner_t owner) +{ + if (__task[taskno] == owner) + return 1; + if (__task[taskno] != O_FREE) + return 0; + + if (! quota_alloc_task(owner, taskno)) + return 0; + + __task[taskno] = owner; + return 1; +} + +L4_INLINE int task_free(unsigned taskno, owner_t owner) +{ + if (__task[taskno] != owner && __task[taskno] != O_FREE) + return 0; + + if (__task[taskno] != O_FREE) + { + quota_free_task(owner, taskno); + __task[taskno] = O_FREE; + } + return 1; +} + +L4_INLINE owner_t task_owner(unsigned taskno) +{ + return __task[taskno]; +} + +#endif diff --git a/apps/rmgr/src/trampoline.c b/apps/rmgr/src/trampoline.c new file mode 100644 index 0000000..0f137f3 --- /dev/null +++ b/apps/rmgr/src/trampoline.c @@ -0,0 +1,22 @@ +#include +#include + +#include "exec.h" + +/* this function is mapped into a new tasks address space to load the + registers in a multiboot-compliant way before starting the task's + real code */ +void task_trampoline(vm_offset_t entry, struct grub_multiboot_info *mbi) +{ + unsigned dummy1, dummy2, dummy3; + + asm volatile("movl %%edx,%%ebx + call *%%ecx + .globl " SYMBOL_NAME_STR(_task_trampoline_end) "\n" + SYMBOL_NAME_STR(_task_trampoline_end) ":" + : "=c" (dummy1), "=d" (dummy2), "=a" (dummy3) + : "0" (entry), "1" (mbi), "2" (MULTIBOOT_VALID) /* in */ + ); + + /* NORETURN */ +} diff --git a/apps/serv/ide-driver/.cvsignore b/apps/serv/ide-driver/.cvsignore new file mode 100644 index 0000000..e674e54 --- /dev/null +++ b/apps/serv/ide-driver/.cvsignore @@ -0,0 +1,3 @@ +ide-driver ide-driver.stripped +.depend +*.o *.ii *.i *.s diff --git a/apps/serv/ide-driver/Makefile b/apps/serv/ide-driver/Makefile new file mode 100644 index 0000000..95f468c --- /dev/null +++ b/apps/serv/ide-driver/Makefile @@ -0,0 +1,29 @@ +include ../../Makeconf $(wildcard .depend) + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include +LDFLAGS += -N -L../../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ +LIBDEPS = ../../lib/libio.a \ + ../../lib/librmgr.a \ + ../../lib/libl4malloc.a +LIBS += -lio -lrmgr -ll4malloc -lgcc + +TARGET = $(notdir $(shell "pwd")) + +LINKBASE=0x00400000 + +all: $(TARGET) + +$(TARGET): $(OBJS) Makefile $(LIBDEPS) + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) $(LIBS) + @cp -f $@ $@.stripped + $(STRIP) $@.stripped + @echo ""; echo "Done with $@."; echo "" + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/serv/ide-driver/crt0-x86.S b/apps/serv/ide-driver/crt0-x86.S new file mode 100644 index 0000000..5e47ee7 --- /dev/null +++ b/apps/serv/ide-driver/crt0-x86.S @@ -0,0 +1,61 @@ +###################################################################### +## +## Copyright (C) 2000, University of Karlsruhe +## +## Filename: crt0-x86.S +## Description: Sets up a small stack and calls main with valid +## multiboot paremeters. +## +## This program 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 +## of the License, or (at your option) any later version. +## +## This program 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 this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. +## +## $Log: crt0-x86.S,v $ +## Revision 1.1 2000/09/21 15:59:00 skoglund +## A first version of an ide driver. The implementation of a recoverable +## disk is not yet finished. +## +## +###################################################################### + .text + .global _start + .global _stext +_stext: +_start: + leal __stack, %esp + pushl %eax + pushl %ebx + pushl $___return_from_main + jmp main + + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + .space 1024 +__stack: diff --git a/apps/serv/ide-driver/hd.h b/apps/serv/ide-driver/hd.h new file mode 100644 index 0000000..7d3fb19 --- /dev/null +++ b/apps/serv/ide-driver/hd.h @@ -0,0 +1,259 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: hd.h + * Description: + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Log: hd.h,v $ + * Revision 1.1 2000/09/21 15:59:00 skoglund + * A first version of an ide driver. The implementation of a recoverable + * disk is not yet finished. + * + * + ********************************************************************/ +#ifndef __HD_H__ +#define __HD_H__ + + +#define MAX_DRIVES 1 /* must be power of 2 */ +#define MAX_SECTORS_PER_REQUEST 8 +#define SECTOR_SIZE 512 + +/* Location where fpages are received */ +#define RCV_LOCATION 0x00800000 +#define RCV_SIZE 16 /* 64KB */ + + + +/* + * Structure used to hold drive parameters. + */ +typedef struct drive_parameter_table_t drvparm_t; +struct drive_parameter_table_t { + word_t cylinders; + byte_t heads; + word_t start_cylinder; + word_t pre_comp_cylinder; + byte_t ecc_burst_length; + byte_t control_byte; + byte_t normal_timeout; + byte_t format_timeout; + byte_t checkdisk_timeout; + word_t landingzone_cylinder; + byte_t sectors; + byte_t unused; +} __attribute__ ((packed)); + + +/* + * Structure used to hold partition table entries. + */ +typedef struct partition_entry_t partition_t; +struct partition_entry_t { + byte_t boot; /* Boot flag: 0 = not active, 0x80 active */ + byte_t bhead; /* Begin: Head number */ + word_t bseccyl; /* Begin: Sector and cylinder numb of boot sector */ + byte_t sys; /* System code: 0x83 linux, 0x82 Linux swap etc. */ + byte_t ehead; /* End: Head number */ + word_t eseccyl; /* End: Sector and cylinder number of last sector */ + dword_t start; /* Relative sector number of start sector */ + dword_t numsec; /* Number of sectors in the partition */ +} __attribute__ ((packed)); + + + +/* + * Bitarrays are used for keeping track of valid diskblocks. + */ +class bitarray_t +{ + public: + + int size; + byte_t *bytes; + + inline int chk(int num) + { + return bytes[num >> 8] & (1 << (num & 7)); + } + + inline void set(int num) + { + bytes[num >> 8] |= (1 << (num & 7)); + } + + inline void clr(int num) + { + bytes[num >> 8] &= ~(1 << (num & 7)); + } + + inline void reset(void) + { + long *ptr = (long *) bytes; + int i = (((size+7) >> 3)+3) >> 2; + + while ( i-- ) + *ptr++ = 0; + } +}; + + +struct hd_vector { + int sectors_per_drive; + partition_t partition_table[4]; + bitarray_t current_block; + bitarray_t currently_written; +}; + +extern struct hd_vector hd[MAX_DRIVES]; + + + + + +/* + * Prototypes. + */ + +/* From main.c */ +void read_ptab(int drive_no); +void print_ptab(int drive_no, int num); +void init_driver(void); + +/* From ide.c */ +int open_controller(void); +int open_drive(int drive_no); +int read_block(int drive_no, int sector_no, int sectors, int *buffer_address); +int write_block(int drive_no, int sector_no, int sectors, int *buffer_address); + +/* From req.c */ +void server(void); + + + + +/* + * Helper functions. + */ + +static inline byte_t inb(dword_t port) +{ + byte_t tmp; + + if (port < 0x100) /* GCC can optimize this if constant */ + __asm__ __volatile__ ("inb %w1, %0 \n" + :"=al"(tmp) + :"dN"(port)); + else + __asm__ __volatile__ ("inb %%dx, %0 \n" + :"=al"(tmp) + :"d"(port)); + + return tmp; +} + + +static inline byte_t inw(dword_t port) +{ + byte_t tmp; + + if (port < 0x100) /* GCC can optimize this if constant */ + __asm__ __volatile__ ("in %w1, %0 \n" + :"=ax"(tmp) + :"dN"(port)); + else + __asm__ __volatile__ ("in %%dx, %0 \n" + :"=ax"(tmp) + :"d"(port)); + + return tmp; +} + + +static inline void outb(dword_t port, byte_t val) +{ + if (port < 0x100) /* GCC can optimize this if constant */ + __asm__ __volatile__ ("outb %1, %w0 \n" + : + :"dN"(port), "al"(val)); + else + __asm__ __volatile__ ("outb %1, %%dx \n" + : + :"d"(port), "al"(val)); +} + + +static int insw(int port, void *data, int num) +{ + int ret; + + __asm__ __volatile__ ( + "pushw %%es # store es \n" + "pushw %%ds # copy ds to es \n" + "popw %%es # \n" + "cld # Clear direction flag \n" + "rep # Repeat prefix \n" + "insw # \n" + "popw %%es # restore es \n" + :"=a"(ret) + :"d"(port), "D"(data), "c"(num)); + + return ret; +} + + +static int outsw(int port, void *data, int num) +{ + int ret; + + __asm__ __volatile__ ( + "cld # Clear direction flag \n" + "rep # Repeat prefix \n" + "outsw # \n" + :"=a"(ret) + :"d"(port), "S"(data), "c"(num)); + + return ret; +} + + +static inline void cli() +{ + __asm__ __volatile__ ("cli"); +} + + +static inline void sti() +{ + __asm__ __volatile__ ("sti"); +} + + + +#define panic(format, args...) \ +do { \ + printf("PANIC: %s(): %s, line %d\n", \ + __FUNCTION__, __FUNCTION__, __LINE__); \ + printf("PANIC: " format , ## args); \ + for (;;) \ + enter_kdebug("panic"); \ +} while(0) + + +#endif /* __HD_H__ */ diff --git a/apps/serv/ide-driver/ide.c b/apps/serv/ide-driver/ide.c new file mode 100644 index 0000000..7b13cd4 --- /dev/null +++ b/apps/serv/ide-driver/ide.c @@ -0,0 +1,394 @@ +#include +#include +#include +#include + +#include "hd.h" + + +#define IDE_PORT 0 + +#if IDE_PORT == 0 /* ide 0 */ + +#define IDE_HD_INTR 14 +#define PORT_BASE 0x1F0 + + +#else /* ide 1 */ + + +#define IDE_HD_INTR 15 +#define PORT_BASE 0x170 + +#endif /* IDE_PORT */ + + +/* + * PIC (8259) ports and codes + */ +#define PIC1_OCW1 0x21 +#define PIC1_OCW2 0x20 +#define PIC1_OCW3 0x20 + +#define PIC2_OCW1 0xA1 +#define PIC2_OCW2 0xA0 +#define PIC2_OCW3 0xA0 +#define PIC2_ISR_IRR 0xA0 +#define PIC2_IMR 0xA1 + +#define READ_IRR 0xA +#define READ_ISR 0xB + +#define SEOI 0x60 + +#define SEOI_MASTER (SEOI + 2) +#define SEOI_HD (SEOI + IDE_HD_INTR - 8) + +#define SYS_PORT_A 0x92 + +/* + * Hard disk controller ports, commands, and states + */ + +#define DATA_PORT (PORT_BASE + 0) +#define ERROR_PORT (PORT_BASE + 1) +#define SECTOR_COUNT_PORT (PORT_BASE + 2) +#define SECTOR_NO_PORT (PORT_BASE + 3) +#define CYLINDER_LOW_PORT (PORT_BASE + 4) +#define CYLINDER_HIGH_PORT (PORT_BASE + 5) +#define DRIVE_HEAD_SELECT_PORT (PORT_BASE + 6) +#define STATUS_PORT (PORT_BASE + 7) +#define COMMAND_PORT (PORT_BASE + 7) + +struct hd_stat { + unsigned error_bit :1; + unsigned dummy1 :1; + unsigned ecc_occurred_bit :1; + unsigned data_request_bit :1; + unsigned dummy2 :1; + unsigned write_fault_bit :1; + unsigned drive_ready_bit :1; + unsigned busy_bit :1; +}; + +struct hd_err { + unsigned data_mark_ntf_bit :1; + unsigned track0_ntf_bit :1; + unsigned invalid_cmd_bit :1; + unsigned dummy1 :1; + unsigned sector_id_ntf_bit :1; + unsigned dummy2 :1; + unsigned data_error_bit :1; + unsigned bad_block_bit :1; +}; + +#define is_error(stat) (stat->error_bit || \ + stat->ecc_occurred_bit || \ + stat->write_fault_bit || \ + stat->drive_ready_bit == 0) + +#define DEVICE_NO_BIT 4 +#define LBA_MODE_BIT 6 + +#define RECALIBRATE 0x10 +#define READ_SECTORS 0x20 +#define WRITE_SECTORS 0x30 +#define VERIFY_SECTORS 0x40 +#define IDENTIFY_DEVICE 0xEC + +#define RETRIES_ENABLED 0 +#define RETRIES_DISABLED 1 + +#define STEP_RATE_35US 0000 + +#define MULTIPLE_SECS_WORD 47 +#define CAPABILITIES_WORD 49 +#define SECTOR_CAPACITY 57 + +#define LBA_SUPPORTED_BIT 9 + +#define DRIVE_NR 0 + + +struct req0 { + unsigned sector_no_field :30; + unsigned drive_no_field :2; +}; + +struct req1 { +#define REQ_SEC_BITS 10 + unsigned sectors_field :9; + unsigned request_field :1; + unsigned buf_addr_field :22; +}; + +#define READ_OP 0 +#define WRITE_OP 1 + +#define OPEN_REQUEST 0x01000008 +#define CLOSE_REQUEST 0xfffffff1 + +#define OK_REPLY 0x01000000 +#define SECTOR_NO_OVRFLW_REPLY 0x80000001 +#define TOO_MANY_SECTORS_REPLY 0x80000002 +#define ILLEGAL_REQUEST_REPLY 0x80000003 + +struct hd_vector hd[MAX_DRIVES]; + +int +reg_to_irq(int irq) +{ + int ret; + dword_t dummy; + l4_msgdope_t dummydope; + + ret = rmgr_get_irq(irq); +// printf("idedrv: rmgr_get_irq() => %d\n", ret); + + if ( ret != 0 ) + { + printf("rmgr does not like us - no int!\n"); + return -1; + } + + ret = l4_ipc_receive(L4_INTERRUPT(irq), 0, + &dummy, &dummy, &dummy, + L4_IPC_TIMEOUT_NULL, + &dummydope); + + if ( ret != 2 ) + panic("Could not register irq (%x, %x)\n", ret, L4_INTERRUPT(irq)); + + return 0; +} + + +/* + * HD routines + */ +void piceoi(void) +{ + cli(); + + outb(PIC2_OCW2, SEOI_HD); + outb(PIC2_OCW3, READ_ISR); + if ( inb(PIC2_ISR_IRR) == 0 ) + outb(PIC1_OCW2, SEOI_MASTER); + + outb(PIC2_OCW1, inb(PIC2_OCW1) & ~(1 << (IDE_HD_INTR-8))); + + sti(); +} + +int +disk_status_and_drq(void) +{ + int status, i; + struct hd_stat *sp = (struct hd_stat *) &status; + + for ( i = 50000; i; i-- ) + { + status = inb(STATUS_PORT); + if ( sp->busy_bit == 0 && sp->data_request_bit ) + break; + } + + if ( i == 0 ) + sp->busy_bit = sp->data_request_bit = 0; + + return status; +} + +int +disk_status(void) +{ + int status, i; + struct hd_stat *sp = (struct hd_stat *) &status; + + for ( i = 50000; i; i-- ) + { + status = inb(STATUS_PORT); + if ( sp->busy_bit == 0 ) + break; + } + + if (i == 0) + sp->busy_bit = sp->data_request_bit = 0; + + return status ; +} + +int +disk_error(void) +{ + int error = inb(ERROR_PORT); + + return error; +} + +void +wait_for_interrupt(int irq) +{ + dword_t dummy; + l4_msgdope_t dummydope; + int result; + + //printf("wait_for_irq %d", irq); + result = l4_ipc_receive(L4_INTERRUPT(irq), 0, &dummy, &dummy, + &dummy, L4_IPC_NEVER, &dummydope); + + if ( result == 0 ) + piceoi(); + //enter_kdebug("got int"); +} + +void +switch_on_drive_lamp(void) +{ + outb(SYS_PORT_A, inb(SYS_PORT_A) | 0x40); +} + +void +switch_off_drive_lamp(void) +{ + outb(SYS_PORT_A, inb(SYS_PORT_A) & ~0x40); +} + + +/* + * Command to hard disk + */ +void +send_cmd_to_disk(int command, int drive_no, int sector_no, int sectors) +{ + outb(SECTOR_NO_PORT, sector_no); + outb(CYLINDER_LOW_PORT, sector_no >> 8); + outb(CYLINDER_HIGH_PORT, sector_no >> 16); + outb(DRIVE_HEAD_SELECT_PORT, ((sector_no >> 24) & 0xf) + + ((drive_no & (MAX_DRIVES - 1)) << DEVICE_NO_BIT) + + (1 << LBA_MODE_BIT)); + outb(SECTOR_COUNT_PORT, sectors); + outb(COMMAND_PORT, command); +} + +/* + * Open controller + */ +int +open_controller(void) +{ + if (reg_to_irq(IDE_HD_INTR)) return -1; + + /* Do we have a controller? */ + outb(SECTOR_COUNT_PORT, 1); + if (inb(SECTOR_COUNT_PORT) != 1) return -1; + outb(SECTOR_COUNT_PORT, 2); + if (inb(SECTOR_COUNT_PORT) != 2) return -1; + outb(SECTOR_NO_PORT, 3); + if (inb(SECTOR_NO_PORT) != 3) return -1; + outb(SECTOR_NO_PORT, 4); + if (inb(SECTOR_NO_PORT) != 4) return -1; + + cli(); + outb(PIC2_OCW1, inb(PIC2_OCW1) & ~(1 << (IDE_HD_INTR - 8))); + sti(); + + return 0; +} + +/* + * Open drive + */ +int +open_drive(int drive_no) +{ + int status, multiple_secs, capabilities = 0, sectors = 0, i, word; + struct hd_stat *sp = (struct hd_stat *) &status; + + hd[drive_no].sectors_per_drive = 0; + + printf("idedrv: open drive\n"); + + send_cmd_to_disk(IDENTIFY_DEVICE, drive_no, 0, 0); + wait_for_interrupt(IDE_HD_INTR); + status = disk_status(); + if ( sp->drive_ready_bit == 0 ) + return 0; + + disk_status_and_drq(); + + for (i = 0; i < 256; i++) + { + word = inw(DATA_PORT); + if ( i == MULTIPLE_SECS_WORD ) + multiple_secs = word & 0xff; + else if ( i == CAPABILITIES_WORD ) + capabilities = word; + else if ( i == SECTOR_CAPACITY ) + { + sectors = (inw(DATA_PORT) << 16) + word; + ++i; + } + } + + if ( capabilities & (1 << LBA_SUPPORTED_BIT) ) + return sectors; + else + return 0; +} + + +unsigned int total_sectors_read = 0, total_sectors_written = 0; + +/* + * Read block + */ +int +read_block(int drive_no, int sector_no, int sectors, int *buffer_address) +{ + int status; + struct hd_stat *sp = (struct hd_stat *)&status; + + switch_on_drive_lamp(); + send_cmd_to_disk(READ_SECTORS, drive_no, sector_no, sectors); + do { + wait_for_interrupt(IDE_HD_INTR); + status = disk_status_and_drq(); + if (sp->data_request_bit) + insw(DATA_PORT, buffer_address, SECTOR_SIZE / 2); + if (is_error(sp)) break; + (char *)buffer_address += SECTOR_SIZE; + --sectors; + total_sectors_read++; + } while (sectors > 0); + switch_off_drive_lamp(); + if (is_error(sp)) return status + (disk_error() << 8); + else return OK_REPLY; +} + +/* + * Write block + */ +int +write_block(int drive_no, int sector_no, int sectors, int *buffer_address) +{ + int status; + struct hd_stat *sp = (struct hd_stat *)&status; + + switch_on_drive_lamp(); + send_cmd_to_disk(WRITE_SECTORS, drive_no, sector_no, sectors); + while (1) { + status = disk_status_and_drq(); + if (is_error(sp)) break; + outsw(DATA_PORT, buffer_address, SECTOR_SIZE / 2); + wait_for_interrupt(IDE_HD_INTR); + (char *)buffer_address += SECTOR_SIZE; + --sectors ; + total_sectors_written++; + if (sectors > 0) continue; + else { status = disk_status(); break; } + } + switch_off_drive_lamp(); + if (is_error (sp)) return status + (disk_error() << 8); + else return OK_REPLY; +} diff --git a/apps/serv/ide-driver/main.c b/apps/serv/ide-driver/main.c new file mode 100644 index 0000000..40c0aeb --- /dev/null +++ b/apps/serv/ide-driver/main.c @@ -0,0 +1,130 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: main.c + * Description: IDE driver which also implements a "relocatable + * disk" + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Log: main.c,v $ + * Revision 1.1 2000/09/21 15:59:00 skoglund + * A first version of an ide driver. The implementation of a recoverable + * disk is not yet finished. + * + * + ********************************************************************/ +#include +#include +#include +#include +#include + +#include "hd.h" + + +int main(multiboot_info_t *mbi, dword_t mbvalid) +{ + if ( mbvalid == MULTIBOOT_VALID ) + { + if ( mbi->flags & MULTIBOOT_CMDLINE ) + printf("Started %s [%p]\n", mbi->cmdline, l4_myself()); + } + + if ( ! rmgr_init() ) + panic("idedrv: rmgr_init() failed\n"); + + init_driver(); + server(); + + /* NOT REACED */ +} + + +/* + * Read partition table. + */ +void read_ptab(int drive_no) +{ + char ptable_buf[512]; + partition_t *ptable = (partition_t *) (ptable_buf + 0x1be); + int i; + + read_block(drive_no, 0, 1, (int *) ptable_buf); + + for ( i = 0; i < 4; i++ ) + hd[drive_no].partition_table[i] = ptable[i]; +} + + +/* + * Print partition info. + */ +void print_ptab(int drive_no, int num) +{ + partition_t *p = &hd[drive_no].partition_table[num]; + + printf("Drive %d, Partition %d (size %dKB)\n", drive_no, num, + (p->numsec * SECTOR_SIZE)/1024); + printf(" boot = 0x%02x\n" + " begin_head = %d\n" + " begin_seccyl = %d\n" + " system = 0x%02x\n" + " end_head = %d\n" + " end_seccyl = %d\n" + " start_sec = %d\n" + " num_sectors = %d\n", + p->boot, p->bhead, p->bseccyl, + p->sys, p->ehead, p->eseccyl, + p->start, p->numsec); +} + + +/* + * Initialization of relocatable disk driver. + */ +void init_driver(void) +{ + dword_t size; + + if ( open_controller() == -1 ) + panic("idedrv: open_controller() failed\n"); + + for ( int i = 0; i < MAX_DRIVES; i++ ) + { + open_drive(i); + read_ptab(i); + + // Find size of drive. + for ( int j = size = 0; j < 4; j++ ) + { + partition_entry_t *p = hd[i].partition_table + j; + if ( p->numsec && (p->start + p->numsec) > size ) + size = p->start + p->numsec; + } + + // Initialize bitarrays. + hd[i].current_block.size = size; + hd[i].current_block.bytes = (byte_t *) malloc((size+7) >> 3); + hd[i].current_block.reset(); + + size /= 2; + hd[i].currently_written.size = size; + hd[i].currently_written.bytes = (byte_t *) malloc((size+7) >> 3); + hd[i].currently_written.reset(); + } +} diff --git a/apps/serv/ide-driver/req.c b/apps/serv/ide-driver/req.c new file mode 100644 index 0000000..fddfaf2 --- /dev/null +++ b/apps/serv/ide-driver/req.c @@ -0,0 +1,101 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: req.c + * Description: The server that handles requests to the ide drive. + * + * This program 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 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Log: req.c,v $ + * Revision 1.1 2000/09/21 15:59:00 skoglund + * A first version of an ide driver. The implementation of a recoverable + * disk is not yet finished. + * + * + ********************************************************************/ +#include +#include +#include + +#include "hd.h" + + +void server(void) +{ + l4_threadid_t client; + l4_msgdope_t result; + dword_t dw0, dw1, dw2 = 0, buf; + l4_idearg_t arg; + l4_fpage_t fp; + int r; + + /* Window for receiving buffers. */ + fp = l4_fpage(RCV_LOCATION, RCV_SIZE, 1, 1); + + printf("idedrv: awaiting requests\n"); + + for (;;) + { + r = l4_ipc_wait(&client, (void *) fp.fpage, + &dw0, &dw1, &arg.raw, + L4_IPC_NEVER, &result); + + for (;;) + { + buf = RCV_LOCATION + (dw0 & ((1 << RCV_SIZE)-1)); + + + if ( arg.args.write ) + { + printf("idedrv: write_block(%d, %d, %d, %p)\n", + arg.args.drive, arg.args.pos, + arg.args.length, buf); + +// r = write_block(arg.args.drive, +// arg.args.pos, +// arg.args.length, +// (int *) buf); + } + else + { + printf("idedrv: read_block(%d, %d, %d, %p)\n", + arg.args.drive, arg.args.pos, + arg.args.length, buf); + + r = read_block(arg.args.drive, + arg.args.pos, + arg.args.length, + (int *) buf); + } + + l4_fpage_unmap(fp, L4_FP_ALL_SPACES|L4_FP_FLUSH_PAGE); + + r = l4_ipc_reply_and_wait(client, (void *) 0, + dw0, dw1, dw2, + &client, (void *) fp.fpage, + &dw0, &dw1, &arg.raw, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + { + printf("idedrv: error reply_and_wait (%x)\n", result.raw); + break; + } + } + + } +} diff --git a/apps/sigma0/.cvsignore b/apps/sigma0/.cvsignore new file mode 100644 index 0000000..c537ff4 --- /dev/null +++ b/apps/sigma0/.cvsignore @@ -0,0 +1,4 @@ +sigma0 sigma0.stripped +.depend +*.o *.ii *.i *.s +kip.h diff --git a/apps/sigma0/.depend b/apps/sigma0/.depend new file mode 100644 index 0000000..04d16ce --- /dev/null +++ b/apps/sigma0/.depend @@ -0,0 +1,9 @@ +crt0-x86.o: crt0-x86.S ../../apps/include/config.h +sigma0.o: sigma0.c ../../apps/include/config.h sigma0-new.c \ + ../../apps/include/l4/l4.h ../../apps/include/l4/arch/l4.h \ + ../../apps/include/l4/arch/types.h \ + ../../apps/include/l4/arch/kdebug.h \ + ../../apps/include/l4/arch/syscalls.h \ + ../../apps/include/l4/arch/ipc.h ../../apps/include/l4/arch/kernel.h \ + ../../apps/include/l4/sigma0.h ../../apps/include/l4io.h \ + ../../apps/include/stdarg.h diff --git a/apps/sigma0/Makefile b/apps/sigma0/Makefile new file mode 100644 index 0000000..29c3864 --- /dev/null +++ b/apps/sigma0/Makefile @@ -0,0 +1,48 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: sigma0/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.22 2001/12/13 03:27:47 ud3 Exp $ +## +###################################################################### + + +include ../Makeconf .depend + +SRCS = crt0-$(ARCH).S sigma0.c +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../include +LDFLAGS += -N -L../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ + +TARGET = $(notdir $(shell "pwd")) + +ifeq ($(SIGMA0_LINKBASE), ) +$(error no sigma0 link address configured - make xconfig) +endif + +LINK_ADDR=$(SIGMA0_LINKBASE) + +all: $(TARGET).stripped + +$(TARGET): $(OBJS) Makefile $(TOPDIR)/apps/lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINK_ADDR) -o $@ $(OBJS) -lio -lgcc + @echo ""; echo "Done with $@." + +$(OBJS) .depend: kip.h + +clean:: + rm -f $(TARGET) $(TARGET).stripped + +sigma0.c: sigma0-new.c + +kip.h: Makefile $(TOPDIR)/kernel/include/kernel.h + @echo Building include file for kernel_info_page_t + @( echo "#ifndef __KIP_H__"; echo "#define __KIP_H__"; echo ""; echo "#include "; echo ""; cat $(TOPDIR)/kernel/include/kernel.h | awk 'BEGIN{printme=0} /typedef struct kernel_info_page_t {/ {printme = 1 } { if (printme == 1 ) { print $0 } } /} kernel_info_page_t;/ { printme = 0}' ; echo "#endif" ) > $@ + diff --git a/apps/sigma0/crt0-arm.S b/apps/sigma0/crt0-arm.S new file mode 100644 index 0000000..9a0e5d5 --- /dev/null +++ b/apps/sigma0/crt0-arm.S @@ -0,0 +1,27 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: sigma0/crt0-arm.S + * Description: Startup code for ARM family processors. + * + * @LICENSE@ + * + * $Id: crt0-arm.S,v 1.7 2002/05/06 13:52:51 ud3 Exp $ + * + ********************************************************************/ +#include + + .globl _start +_start: + ldr sp, 2f + bl sigma0_main + +1: b 1b +2: .word _sigma0_stack_top + + .bss + .p2align 12 +_sigma0_stack_bottom: + .space 8192 +_sigma0_stack_top: diff --git a/apps/sigma0/crt0-x86.S b/apps/sigma0/crt0-x86.S new file mode 100644 index 0000000..bbd6359 --- /dev/null +++ b/apps/sigma0/crt0-x86.S @@ -0,0 +1,53 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: sigma0/crt0-x86.S + * Description: Startup code for x86 family processors. + * + * @LICENSE@ + * + * $Id: crt0-x86.S,v 1.7 2002/05/06 13:52:51 ud3 Exp $ + * + ********************************************************************/ +#include + + .text + .global _start + .global _stext +_stext: +_start: + /* do we have a reasonable KIP pointer on the stack ??? + Jochen/Fiasco */ + testl $0x00000FFF, (%esp) + jne 0f + /* if not, it may already be in eax - L4/KA */ + popl %eax +0: leal stack, %esp + pushl %eax + pushl $___return_from_main + jmp sigma0_main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +stack: diff --git a/apps/sigma0/crt0-x86.o b/apps/sigma0/crt0-x86.o new file mode 100644 index 0000000..4adb47f Binary files /dev/null and b/apps/sigma0/crt0-x86.o differ diff --git a/apps/sigma0/kip.h b/apps/sigma0/kip.h new file mode 100644 index 0000000..286e59e --- /dev/null +++ b/apps/sigma0/kip.h @@ -0,0 +1,54 @@ +#ifndef __KIP_H__ +#define __KIP_H__ + +#include + +typedef struct kernel_info_page_t { + char magic[4]; /* "L4uK" */ + dword_t version; + char reserved_0x0C[8]; /* "L2" ... */ + + /* these are physical addresses !!! */ + void (*kdebug_init)(); + void (*kdebug_exception)(); + dword_t kdebug_low, kdebug_high; + dword_t sigma0_sp, sigma0_ip, sigma0_low, sigma0_high; + dword_t sigma1_sp, sigma1_ip, sigma1_low, sigma1_high; + dword_t root_sp, root_ip, root_low, root_high; + + dword_t l4_config; + dword_t reserved_0x54; + dword_t kdebug_config, kdebug_perms; + + /* memory areas */ + dword_t main_mem_low, main_mem_high; + /* these regions must not be used. They contains kernel code + (reserved mem0) or data (reserved mem1) grabbed by the kernel + before sigma0 was initialized */ + dword_t reserved_mem0_low, reserved_mem0_high; + dword_t reserved_mem1_low, reserved_mem1_high; + + /* these regions contain dedicated memory which cannot be used as + standard memory. For example, on PCs [640, 1M] is a popular + dedicated memory region. */ + dword_t dedicated_mem0_low, dedicated_mem0_high; + dword_t dedicated_mem1_low, dedicated_mem1_high; + dword_t dedicated_mem2_low, dedicated_mem2_high; + dword_t dedicated_mem3_low, dedicated_mem3_high; + dword_t dedicated_mem4_low, dedicated_mem4_high; + + /* the kernel clock */ +#if defined (CONFIG_SMP) + volatile +#endif + qword_t clock; + + /* ? */ + dword_t reserved_0xA8[2]; + + dword_t processor_frequency; + dword_t bus_frequency; + + dword_t reserved_0xB8[2]; +} kernel_info_page_t; +#endif diff --git a/apps/sigma0/sigma0 b/apps/sigma0/sigma0 new file mode 100644 index 0000000..a8faead Binary files /dev/null and b/apps/sigma0/sigma0 differ diff --git a/apps/sigma0/sigma0-new.c b/apps/sigma0/sigma0-new.c new file mode 100644 index 0000000..74b5cab --- /dev/null +++ b/apps/sigma0/sigma0-new.c @@ -0,0 +1,506 @@ +/********************************************************************* + * + * Copyright (C) 2001-2002, Karlsruhe University + * + * File path: sigma0/sigma0-new.c + * Description: Implementation of new generic sigma0 protocol. + * + * @LICENSE@ + * + * $Id: sigma0-new.c,v 1.12 2002/06/07 17:36:30 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#include + +#if 1 +extern "C" void *memset(void *b, int c, int size) +{ + char *p = (char *) b; + + while ( size-- ) + *(p++) = c; + + return b; +} +#endif + + +#define iskernelthread(x) (x.raw < myself.raw) +#define NO_MAP (~0UL) + +typedef byte_t space_id_t; + +l4_kernel_info_t *kip; + + +#if defined(CONFIG_ARCH_ARM) + +/* + * ARM configuration. + */ + +#define DEFAULT_SIZE (12) +#define PAGE_BITS (12) +#define PAGE_SIZE (1 << PAGE_BITS) +#define MAX_MEM (2*256L*1024L*1024L) +#define PAGE_SIZES (3) + +space_id_t page_array[MAX_MEM >> PAGE_BITS]; +dword_t page_shifts[PAGE_SIZES+1] = { 12, 16, 20, 32 }; +dword_t page_sizes[PAGE_SIZES] = { (1<<12), (1<<16), (1<<20) }; + +#elif defined(CONFIG_ARCH_X86) + +/* + * X86 configuration. + */ +#if defined(CONFIG_IO_FLEXPAGES) + +#define IOFP_LO_BOUND 0xF0000000 +#define IOFP_HI_BOUND 0xFFFFF000 + +#define PORT_FREE 0 + +#define IOFP_PORT(x) ((dword_t) (((x) >> 12) & 0x0000FFFF)) +#define IOFP_LD_SIZE(x) ((dword_t) (((x) >> 2) & 0x0000003F)) +#define IOFP_SIZE(x) ((dword_t) (1 << IOFP_LD_SIZE(x))) +#define MIN(a,b) (a> PAGE_BITS]; +dword_t page_shifts[PAGE_SIZES+1] = { 12, 22, 32 }; +dword_t page_sizes[PAGE_SIZES] = { (1<<12), (1<<22) }; + +#else +#error Page size specifications are lacking for this architecture. +#endif + + +/* +** +** Sigma0 protocol. +** +*/ + +void init_space(l4_kernel_info_t *kip); +void free_space(space_id_t space, dword_t addr, dword_t size); +dword_t allocate_space(space_id_t space, dword_t addr, dword_t size); +dword_t allocate_space(space_id_t space, dword_t size); + + +extern "C" void sigma0_main(l4_kernel_info_t *_kip) +{ + l4_threadid_t client; + l4_msgdope_t result; + l4_fpage_t fp; + dword_t dw0, dw1; + dword_t msg, sz; + int r; + + kip = _kip; + + l4_threadid_t myself = l4_myself(); + + printf("sigma0: kernel_info_page is at %p\n", kip); + + if ( (((char *) kip)[0] != 'L') | (((char *) kip)[1] != '4') | + (((char *) kip)[2] != 0xE6) | (((char *) kip)[3] != 'K') ) + enter_kdebug("sigma0: invalid KIP"); + + init_space(kip); + + for (;;) + { + r = l4_ipc_wait(&client, NULL, + &dw0, &dw1, &fp.raw, + L4_IPC_NEVER, &result); + + for (;;) + { +// printf("sigma0: tid=%08x dw0=%08x dw1=%08x dw2=%08x (rcvd)\n", +// client.raw, dw0, dw1, fp.raw); + + /* + * Handle compatibility with pagefault protocol and older + * versions of sigma0 RPC. + */ + + if ( dw0 == 0xfffffffc ) + /* Map arbitrary 4K page (old s0 compitability). */ + fp = l4_fpage(0, 12, 0, 1); + else if ( (fp.raw == 0 && dw0 != 0x1) || /* (PF compitability) */ + ((dw0 & 0x3) == 0) ) /* (old s0 compitability) */ + { + /* Map indicated page frame. */ +#if defined(CONFIG_ARCH_X86) + if ( dw0 > (1024*1024*1024) ) +#if defined(CONFIG_IO_FLEXPAGES) + if (dw0 >= IOFP_LO_BOUND && dw0 <= IOFP_HI_BOUND) + fp.raw = dw0 + 0x3; + else +#endif + fp = l4_fpage(dw0 + (1024*1024*1024), 22, 1, 1); + else +#endif + fp = l4_fpage(dw0, DEFAULT_SIZE, 1, 1); + } +#if defined(CONFIG_ARCH_X86) + else if ( ((dw0 & 0x3) == 0x1) && (dw1 == (22 << 2)) ) + /* Map indicated page frame (old s0 compitability). */ + fp = l4_fpage(dw0, 22, 1, 1); +#endif + + if ( dw0 != 0x1 ) + dw0 = 0x3; + +// printf("sigma0: tid=%08x dw0=%08x dw1=%08x dw2=%08x (ok)\n", +// client.raw, dw0, dw1, fp.raw); + + + msg = 2; /* We usually do a snd_fpage IPC. */ + sz = fp.fp.size; + + + if ( dw0 == 0x1 ) + { + if ( iskernelthread(client) ) + /* Recomended amount of in-kernel data. */ + msg = 0, dw0 = 0x100 << PAGE_BITS; + else + { + /* Kernel-info-page request. */ + dw0 = (dword_t) kip; + fp = l4_fpage(dw0, 12, 0, 0); + } + } + else if ( fp.raw & 0x1 ) + { + if ( fp.raw & 0x2 ) + /* Map the specified fpage. */ + dw0 = allocate_space(client.id.task, fp.raw, sz); + else + /* Map fpage from an arbitrary location. */ + dw0 = allocate_space(client.id.task, sz); + + if ( dw0 != NO_MAP ) + { +#if defined(CONFIG_IO_FLEXPAGES) + if (fp.raw >= IOFP_LO_BOUND && fp.raw <= IOFP_HI_BOUND) + fp.raw = dw0 = dw0 & ~0x3; + else +#endif + { + l4_fpage_t old_fp = fp; + fp = l4_fpage(dw0, sz, 1, iskernelthread(client)); + if (! iskernelthread(client)) + { + fp.fp.uncacheable = old_fp.fp.uncacheable; + fp.fp.unbufferable = old_fp.fp.unbufferable; + } + } + } + else + msg = dw0 = fp.raw = 0; + } + else + { + /* Free up space. Do not send reply. */ + free_space(client.id.task, fp.raw, sz); + break; + } + +// printf("sigma0: reply msg=%08x dw0=%08x dw1=%08x\n", +// msg, dw0, fp.raw); + + r = l4_ipc_reply_and_wait(client, (void *) msg, + dw0, fp.raw, 0, + &client, NULL, + &dw0, &dw1, &fp.raw, + L4_IPC_NEVER, &result); + + if ( L4_IPC_ERROR(result) ) + { + printf("sigma0: error reply_and_wait (%x)\n", result.raw); + break; + } + } + } +} + + +/* +** +** Space management. +** +*/ + +#define PAGE_RESERVED 0xFF +#define PAGE_FREE 0xFE +#define PAGE_SHARED 0xFC +#define PAGE_ROOT 0x04 + +#define PRINT_KIP + +#if defined(PRINT_KIP) +#define printkip(name, attrib) \ + printf(" kip: %s \t<%08x,%08x> (%s)\n", #name, \ + kip->##name##.low, kip->##name##.high, #attrib) +#else +#define printkip(name, attrib) +#endif + +void init_space(l4_kernel_info_t *kip) +{ + dword_t i; + + for ( i = 0; i < (MAX_MEM >> PAGE_BITS); i++ ) + page_array[i] = PAGE_RESERVED; + +#define setmem(name, attrib) \ + if ( kip->##name##.high ) \ + { \ + printkip(name, attrib); \ + if ( (kip->##name##.low >= kip->main_memory.low) && \ + (kip->##name##.high <= kip->main_memory.high) ) \ + { \ + for ( i = kip->##name##.low >> PAGE_BITS; \ + i < (kip->##name##.high) >> PAGE_BITS; \ + i++ ) \ + \ + page_array[i - (kip->main_memory.low >> PAGE_BITS)] = \ + PAGE_##attrib; \ + } \ + else \ + printf("kip->" #name " is wrong\n"); \ + } + + setmem(main_memory, FREE); + setmem(dedicated[0], SHARED); + setmem(dedicated[1], SHARED); + setmem(dedicated[2], SHARED); + setmem(dedicated[3], SHARED); + setmem(dedicated[4], SHARED); + + setmem(reserved0, RESERVED); + setmem(reserved1, RESERVED); + setmem(root_memory, ROOT); + setmem(sigma0_memory, RESERVED); + setmem(sigma1_memory, RESERVED); + setmem(kdebug_memory, RESERVED); + +#if defined(CONFIG_IO_FLEXPAGES) + for (dword_t idx = 0; idx < X86_IO_SPACE_SIZE; idx++) + io_space[idx] = PORT_FREE; +#endif +} + + +dword_t allocate_space(space_id_t space, dword_t addr, dword_t size) +{ + if (addr < kip->main_memory.low) + { + printf("s0: %x < %x", addr, kip->main_memory.low); + return NO_MAP; + } +#if defined(CONFIG_IO_FLEXPAGES) + if (addr >= IOFP_LO_BOUND && addr <= IOFP_HI_BOUND) + return allocate_io_space(space, addr); + +#endif + if ( size < PAGE_BITS ) + return NO_MAP; + + addr &= ~((1 << size)-1); + + /* Check if pages can be allocated. */ + dword_t tmp = addr - kip->main_memory.low; + dword_t num = 1 << (size - PAGE_BITS); + dword_t idx = tmp >> PAGE_BITS; + + for ( ; tmp < MAX_MEM && num--; idx++, tmp += PAGE_SIZE ) + { + if ( ! ((page_array[idx] == PAGE_FREE) || + (page_array[idx] == PAGE_SHARED) || + (page_array[idx] == space)) ) + return NO_MAP; + } + + if ( tmp >= MAX_MEM ) + return NO_MAP; + + /* Mark pages as allocated. */ + tmp = addr - kip->main_memory.low; + num = 1 << (size - PAGE_BITS); + idx = tmp >> PAGE_BITS; + + for ( ; num--; idx++ ) + if ( page_array[idx] == PAGE_FREE ) + page_array[idx] = space; + + return addr; +} + + +dword_t allocate_space(space_id_t space, dword_t size) +{ + dword_t addr, tmp, idx, num; + + if ( size < PAGE_BITS ) + return NO_MAP; + + /* Search for free location. */ + for ( addr = 0; addr < MAX_MEM; addr += (1 << size) ) + { + tmp = addr; + num = (1 << (size - PAGE_BITS)) + 1; + idx = tmp >> PAGE_BITS; + + for ( ; tmp <= MAX_MEM && --num; idx++, tmp += PAGE_SIZE ) + if ( page_array[idx] != PAGE_FREE ) + break; + + if ( num == 0 ) + { + /* Mark pages as allocated. */ + tmp = addr; + num = 1 << (size - PAGE_BITS); + idx = tmp >> PAGE_BITS; + + for ( ; num--; idx++ ) + if ( page_array[idx] == PAGE_FREE ) + page_array[idx] = space; + + return kip->main_memory.low + addr; + } + else if ( tmp >= MAX_MEM ) + return NO_MAP; + } + + return NO_MAP; +} + + +void free_space(space_id_t space, dword_t addr, dword_t size) +{ + dword_t snum, plus, tmp, num, idx, sz, endaddr; + +#if defined(CONFIG_IO_FLEXPAGES) + if (addr >= IOFP_LO_BOUND && addr <= IOFP_HI_BOUND){ + free_io_space(space, addr); + return; + } +#endif + if ( size < PAGE_BITS ) + return; + + addr &= ~((1 << size)-1); + endaddr = addr + (1 << size) - PAGE_SIZE; + + /* + * Freeing pages is tricky because we can not free a smaller page + * if we have mapped a larger page to the task. E.g., we can not + * free a 4KB page residing within an already mapped 4MB page. + */ + for ( sz = PAGE_SIZES; sz-- > 0; ) + { + snum = size > page_shifts[sz] ? (1 << (size - page_shifts[sz])) : 1; + plus = 0; + + for ( ; snum--; plus += page_sizes[sz] ) + { + tmp = (addr & ~(page_sizes[sz]-1)) + plus; + num = 1 << (page_shifts[sz] - PAGE_BITS); + idx = tmp >> PAGE_BITS; + + /* + * Check if task owns all pages within a larger page for + * this region. E.g., for x86 we need to check if a task + * owns all 4KB pages within a 4MB region. + */ + while ( (page_array[idx] == space) && --num ) idx++; + + if ( num == 0 ) + { + /* + * Task does indeed own all pages within the larger + * region. We unmap the whole region to make sure + * that the page is properly unmapped. + */ + l4_fpage_unmap(l4_fpage(tmp, page_shifts[sz], 0, 0), + (L4_FP_OTHER_SPACES|L4_FP_FLUSH_PAGE)); + + /* + * We now free up the actual unallocated pages. It + * might be that we have flushed too many pages above, + * but this should be handled afterwards by the + * underlying application (i.e., its pager). + */ + num = 1 << (page_shifts[sz] - PAGE_BITS); + idx = tmp >> PAGE_BITS; + for ( ; num--; idx++, tmp += PAGE_SIZE ) + if ( tmp >= addr && tmp <= endaddr && + page_array[idx] == space ) + page_array[idx] = PAGE_FREE; + } + } + } +} +#if defined(CONFIG_IO_FLEXPAGES) + +dword_t allocate_io_space(space_id_t space, dword_t addr){ + + dword_t size = IOFP_SIZE(addr); + dword_t port = IOFP_PORT(addr); + + + if (port + size > X86_IO_SPACE_SIZE) + return NO_MAP; + + for (dword_t idx = port; idx < port + size; idx++){ + if (io_space[idx] != PORT_FREE && io_space[idx] != space) + return NO_MAP; + } + + for (dword_t idx = port; idx < port + size; idx++){ + io_space[idx] = space; + } + + return addr; +} + +void free_io_space(space_id_t space, dword_t addr){ + + dword_t size = IOFP_SIZE(addr); + dword_t port = IOFP_PORT(addr); + + if (port + size > X86_IO_SPACE_SIZE) + return; + + for (dword_t idx = port; idx < port + size; idx++){ + if (io_space[idx] != space && io_space[idx] != PORT_FREE) + return; + } + + for (dword_t idx = port; idx < port + size; idx++){ + io_space[idx] = PORT_FREE; + } + + printf("sigma0: unmap IO-Page port = %x, size=%x, fp=%x\n", port, size, addr); + l4_fpage_unmap( ( (l4_fpage_t){raw: addr}), 0); + +} +#endif /* CONFIG_IO_FLEXPAGES */ diff --git a/apps/sigma0/sigma0.c b/apps/sigma0/sigma0.c new file mode 100644 index 0000000..c631d7b --- /dev/null +++ b/apps/sigma0/sigma0.c @@ -0,0 +1,473 @@ +/********************************************************************* + * + * Copyright (C) 2001-2002, Karlsruhe University + * + * File path: sigma0/sigma0.c + * Description: old sigma0 implementation + * + * @LICENSE@ + * + * $Id: sigma0.c,v 1.23 2002/05/06 13:52:51 ud3 Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_L4_NEWSIGMA0) +#include "sigma0-new.c" +#else + +#include +#include + +#include "kip.h" + +#if defined(CONFIG_ARCH_X86) +#define PAGE_BITS 12 +#define SUPERPAGE_BITS 22 +#endif +#if defined(CONFIG_ARCH_ARM) +#define PAGE_BITS 12 +#define SUPERPAGE_BITS 20 +#endif + +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define SUPERPAGE_SIZE (1 << SUPERPAGE_BITS) +#define SUPERPAGE_MASK (~(SUPERPAGE_SIZE-1)) + + + +#if 1 +extern "C" void memset(char* p, char c, int size) +{ + for (;size--;) + *(p++)=c; +} +#endif + + +#define iskernelthread(x) (x.raw < myself.raw) +#define MB64 64L*1024L*1024L +#define MB128 128L*1024L*1024L +#define MB256 256L*1024L*1024L +#define MB512 512L*1024L*1024L + +#define MAX_MEM MB256 +static unsigned char page_array[MAX_MEM/PAGE_SIZE]; + + +void dump_kip(kernel_info_page_t* kip) +{ + +#define kipel(x) printf(" kip: %s=\t%x\n", #x, kip->x); + + printf("%s: kernel_info_page magic is %c%c%c%c\n", __FUNCTION__, + ((char*) kip)[0], + ((char*) kip)[1], + ((char*) kip)[2], + ((char*) kip)[3]); + + kipel(main_mem_low); kipel(main_mem_high); + +//enter_kdebug("foo"); + kipel(sigma0_low); kipel(sigma0_high); + kipel(root_low); kipel(root_high); +//enter_kdebug("foo"); + kipel(reserved_mem0_low); kipel(reserved_mem0_high); + kipel(reserved_mem1_low); kipel(reserved_mem1_high); +//enter_kdebug("foo"); + kipel(dedicated_mem0_low); kipel(dedicated_mem0_high); + kipel(dedicated_mem1_low); kipel(dedicated_mem1_high); +//enter_kdebug("foo"); + printf("\nsigma0: Available main memory: %d MB (%d KB)\n", + (kip->main_mem_high-kip->main_mem_low)/1024/1024, + (kip->main_mem_high-kip->main_mem_low)/1024); +//enter_kdebug("foo"); +} + + +extern "C" void sigma0_main(kernel_info_page_t* kip) +{ + + l4_threadid_t client; + int r; + l4_msgdope_t result; + dword_t dw0, dw1, dw2; + dword_t msg; + + l4_threadid_t myself = l4_myself(); + + printf("%s: kernel_info_page is at %p\n", __FUNCTION__, kip); + if ((((char*) kip)[0] != 'L') | + (((char*) kip)[1] != '4') | + (((char*) kip)[2] != 0xE6) | + (((char*) kip)[3] != 'K')) + enter_kdebug("sigma0: invalid KIP!"); +// dump_kip(kip); + + dword_t free_mem = kip->main_mem_low; + dword_t kernel_mem = kip->main_mem_high-PAGE_SIZE; + +#define IDX(x) ((x)-(kip->main_mem_low/PAGE_SIZE)) + + if (sizeof(page_array) < (kip->main_mem_high-kip->main_mem_low)/PAGE_SIZE) + { + printf("sigma0: too much memory - %d < %d\n", sizeof(page_array), (kip->main_mem_high-kip->main_mem_low)/PAGE_SIZE); + enter_kdebug("too much memory"); + }; + +#define PAGE_SHARED 0xFC +#define PAGE_GONE 0xFD +#define PAGE_FREE 0xFE +#define PAGE_RESERVED 0xFF +#define PAGE_ROOT 0x04 + + /* initialize the page array */ + for (dword_t i = 0; i < sizeof(page_array); i++) + page_array[i] = PAGE_RESERVED; + for (dword_t i = kip->main_mem_low/PAGE_SIZE; + i < kip->main_mem_high/PAGE_SIZE; i++) + page_array[IDX(i)] = PAGE_FREE; + +#define exclude(name,attrib) \ + if ( kip->##name##_high ) { \ + if ((kip->##name##_low >= kip->main_mem_low) && \ + (kip->##name##_high <= kip->main_mem_high)) { \ + for ( dword_t i = kip->##name##_low / PAGE_SIZE; \ + i < (kip->##name##_high) / PAGE_SIZE; \ + i++ ) \ + page_array[IDX(i)] = PAGE_##attrib; } \ + else \ + printf("kip->" #name " is wrong\n"); } + + exclude(dedicated_mem0, SHARED); + exclude(dedicated_mem1, SHARED); + exclude(dedicated_mem2, SHARED); + exclude(dedicated_mem3, SHARED); + exclude(dedicated_mem4, SHARED); + + exclude(reserved_mem0, RESERVED); + exclude(reserved_mem1, RESERVED); + exclude(root, ROOT); + exclude(sigma0, RESERVED); + exclude(sigma1, RESERVED); + exclude(kdebug, RESERVED); + +#if defined(CONFIG_ARCH_X86) + page_array[IDX(0xb8000/PAGE_SIZE)] = PAGE_SHARED; + page_array[IDX(0x01000/PAGE_SIZE)] = PAGE_RESERVED; +#endif + + dword_t one_shot_break = 0; + +/* + macros to figure out request type + assumption: dw0:dw1:dw2 contains the received message + */ + +#define GET_ANY_PAGE (dw0 == 0xFFFFFFFC) +#define GET_KMEM_PAGES ((dw0 == 1) && ((dw1 & 0xFF) == 0)) +#define GET_INFO_PAGE ((dw0 == 1) && ((dw1 & 0xFF) == 1)) +#define GET_THIS_PAGE_SUPER ((dw0 & 1) && (dw1 == (SUPERPAGE_BITS << 2))) + +#if defined(CONFIG_ARCH_X86) +#define GET_THIS_PAGE (dw0 < 0x40000000) +#endif +#if defined(CONFIG_ARCH_ARM_EP7211) +#define GET_THIS_PAGE (1) +#endif + + while(1) + { +//printf("%s: do ipc_wait\n", __FUNCTION__); + r = l4_ipc_wait(&client, NULL, &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); + + while (1) + { + if (one_shot_break) + { + enter_kdebug("one_shot_break"); + one_shot_break = 0; + } + + msg = 2; /* usually we map an fpage */ + + +#if 0 + if (GET_ANY_PAGE) + { + if (iskernelthread(client)) + { + /* grant any page */ + printf("sigma0: s0 receives %x from kthread %x -> ", + dw0, client.raw); + while (kernel_mem > 0 && + page_array[IDX(kernel_mem/PAGE_SIZE)] != PAGE_FREE) + kernel_mem -= PAGE_SIZE; + + if (kernel_mem == 0) + { + //enter_kdebug("sigma0 out of memory"); + msg = dw0 = dw1 = dw2 = 0; + } + else + { + page_array[IDX(kernel_mem/PAGE_SIZE)] = PAGE_GONE; + dw0 = kernel_mem; + dw1 = dw0 | (PAGE_BITS << 2) | 3; + dw2 = 0; + + printf(" grant: %x\n", dw0); + } + } + else + { +#if 0 + printf("sigma0: s0 receives %x from %p -> map any page", + dw0, client); +#endif + + while (free_mem < MAX_MEM && page_array[IDX(free_mem/PAGE_SIZE)] != PAGE_FREE) + free_mem += PAGE_SIZE; + + if (free_mem >= MAX_MEM) + { + //enter_kdebug("sigma0 out of memory"); + msg = dw0 = dw1 = dw2 = 0; + } + else + { +#if defined(CONFIG_VERSION_X0) + page_array[IDX(free_mem/PAGE_SIZE)] = client.id.task; +#elif defined(CONFIG_VERSION_X1) + page_array[IDX(free_mem/PAGE_SIZE)] = PAGE_GONE; +#endif + dw0 = free_mem; + dw1 = dw0 | (PAGE_BITS << 2) | 2; + dw2 = 0; + +// printf(" map: %x\n", dw0); + + } + } + goto done; + } + + if (GET_THIS_PAGE) + + msg = 0; + printf("ill sigma0 request %x:%x:%x from %x", + dw0, dw1, dw2, client.raw); + enter_kdebug("ill_s0_request"); + + + +#else + if (iskernelthread(client)) + { + switch (dw0) + { + case 0xFFFFFFFC: + case 0xFFFFFFFE: /* Jochen */ + printf("sigma0: s0 receives %x from a kernel thread -> grant any page\n", + dw0); + /* grant any page */ + while (kernel_mem > 0 && page_array[IDX(kernel_mem/PAGE_SIZE)] != PAGE_FREE) + kernel_mem -= PAGE_SIZE; + + if (kernel_mem == 0) + { + //enter_kdebug("sigma0 out of memory"); + msg = dw0 = dw1 = dw2 = 0; + } + else + { + page_array[IDX(kernel_mem/PAGE_SIZE)] = PAGE_GONE; + dw0 = kernel_mem; + dw1 = dw0 | (PAGE_BITS << 2) | 3; + dw2 = 0; + + printf(" grant: %x:%x:%x-%x\n", dw0, dw1, dw2, msg); + } + break; + case 0x00000001: + printf("sigma0: %x for number of recommended pages\n", + client.raw); + if ((dw1 & 0xFF) == 0) + { + /* reply number of pages recommended for kernel use */ + msg = 0; dw0 = 0x100; + } + else + msg = dw0 = dw1 = dw2 = 0; + break; + default: + printf("sigma0: unknown request %x:%x:%x from %x\n", + dw0, dw1, dw2, client.raw); + msg = dw0 = dw1 = dw2 = 0; + break; + } + } + else + { + switch(dw0) + { + case 0xFFFFFFFC: +#if 0 + printf("sigma0: s0 receives %x from %p -> map any page", + dw0, client); +#endif + + while (free_mem < MAX_MEM && page_array[IDX(free_mem/PAGE_SIZE)] != PAGE_FREE) + free_mem += PAGE_SIZE; + + if (free_mem >= MAX_MEM) + { + //enter_kdebug("sigma0 out of memory"); + msg = dw0 = dw1 = dw2 = 0; + } + else + { +#if defined(CONFIG_VERSION_X0) + page_array[IDX(free_mem/PAGE_SIZE)] = client.id.task; +#elif defined(CONFIG_VERSION_X1) + page_array[IDX(free_mem/PAGE_SIZE)] = PAGE_GONE; +#endif + dw0 = free_mem; + dw1 = dw0 | (PAGE_BITS << 2) | 2; + dw2 = 0; + +// printf(" map: %x\n", dw0); + } + break; + + case 0x00000001: + if ((dw1 & 0xFF) == 1) + { + printf("sigma0: %x requests kernel-info page\n", + client.raw); + dw0 = 0; + dw1 = (((dword_t)kip) & PAGE_MASK) | (PAGE_BITS << 2); + dw2 = 0; + } + else + msg = dw0 = dw1 = dw2 = 0; + break; + +#if defined(CONFIG_ARCH_X86) + case 0x00000000: + case 0x00000002 ... 0x40000000: +#elif defined(CONFIG_ARCH_ARM_EP7211) || defined(CONFIG_ARCH_ARM_BRUTUS) + case 0xC0000000 ... 0xC0800000: +#endif +// printf("sigma0: s0 receives %x,%x from %x\n", dw0, dw1, client.raw); + if ( (dw0 & 1) && (dw1 & 0xFF) == (SUPERPAGE_BITS << 2) ) + { + /* map superpage writeable + and uncacheable !!! */ + + dword_t adr = dw0 & SUPERPAGE_MASK; + dword_t i; + for (i = 0; i < SUPERPAGE_SIZE/PAGE_SIZE; i++) + if (page_array[IDX(adr/PAGE_SIZE + i)] != PAGE_FREE) + { + msg = 0; + break; + } + + if (msg) + { + for (i = 0; i < 1024; i++) +#if defined(CONFIG_VERSION_X0) + page_array[IDX(adr/PAGE_SIZE + i)] = client.id.task; +#elif defined(CONFIG_VERSION_X1) + page_array[IDX(adr/PAGE_SIZE + i)] = PAGE_GONE; +#endif + + dw0 = adr; + dw1 = dw0 | (SUPERPAGE_BITS << 2) | 2; + dw2 = 0; + printf("sigma0: map 4M page at %x to %x\n", adr, client.raw); + } + } + else + { + if (page_array[IDX(dw0/PAGE_SIZE)] != PAGE_FREE && + page_array[IDX(dw0/PAGE_SIZE)] != PAGE_SHARED +#if defined(CONFIG_VERSION_X0) + && page_array[IDX(dw0/PAGE_SIZE)] != client.id.task +#endif + ) + { +#if 1 + printf("sigma0: page %x requested twice, old=%x, new=%x\n", dw0, page_array[IDX(dw0/PAGE_SIZE)], client.id.task); +// enter_kdebug("page requested twice"); +#endif + dw0 = dw1 = dw2 = msg = 0; + } + else + { + /* mark only free pages - ignore the shared!!! */ + if (page_array[IDX(dw0/PAGE_SIZE)] == PAGE_FREE) +#if defined(CONFIG_VERSION_X0) + page_array[IDX(dw0/PAGE_SIZE)] = client.id.task; +#elif defined(CONFIG_VERSION_X1) + page_array[IDX(dw0/PAGE_SIZE)] = PAGE_GONE; +#endif + + /* map 4k page, writeable */ + dw0 &= PAGE_MASK; + dw1 = dw0 | (PAGE_BITS << 2) | 2; + dw2 = 0; + } + } + break; + +#if defined(CONFIG_ARCH_X86) + case 0x40000004 ... 0xC0000000: +#elif defined(CONFIG_ARCH_ARM_EP7211) + case 0xFFFFFFFF: /* dummy */ +#endif + { + printf("sigma0: s0 receives %x from %x\n", + dw0, client.raw); + /* map 4M page */ + //enter_kdebug("s0: map superpage"); + + dw0 = (dw0 & SUPERPAGE_MASK) + 0x40000000; + dw1 = dw0 | (SUPERPAGE_BITS << 2) | 2; /* map superpage writeable + and uncacheable !!! */ + dw2 = 0; + + } + break; + + } + } +#endif + + + + + done: +#if 1 +//printf("%s: do reply_and_wait\n", __FUNCTION__); + r = l4_ipc_reply_and_wait(client, (void*) msg, + dw0, dw1, dw2, + &client, NULL, + &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); +//printf("%s: done reply_and_wait\n", __FUNCTION__); +#endif +#if 1 + if (L4_IPC_ERROR(result)) + { + printf("%s: error reply_and_wait (%x)\n", __FUNCTION__, result.raw); + break; + } +#endif + } + } +} + +#endif /* !CONFIG_L4_NEWSIGMA0 */ diff --git a/apps/sigma0/sigma0.o b/apps/sigma0/sigma0.o new file mode 100644 index 0000000..6741341 Binary files /dev/null and b/apps/sigma0/sigma0.o differ diff --git a/apps/sigma0/sigma0.stripped b/apps/sigma0/sigma0.stripped new file mode 100644 index 0000000..912f49e Binary files /dev/null and b/apps/sigma0/sigma0.stripped differ diff --git a/apps/template/Makefile b/apps/template/Makefile new file mode 100644 index 0000000..2a10a0b --- /dev/null +++ b/apps/template/Makefile @@ -0,0 +1,37 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: template/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.4 2001/11/30 14:20:06 ud3 Exp $ +## +###################################################################### +include ../Makeconf $(wildcard .depend) + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../include +LDFLAGS += -N -L../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ + +TARGET = $(notdir $(shell "pwd")) + +$(error edit the Makefile - adjust the next line and then delete this line) +LINKBASE=0x0c200000 + +all: $(TARGET) + +$(TARGET): $(OBJS) Makefile ../lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) -lio -lgcc + @cp -f $@ $@.stripped + $(STRIP) $@.stripped + @echo ""; echo "Done with $@."; echo "" + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/template/crt0-arm.S b/apps/template/crt0-arm.S new file mode 100644 index 0000000..640ff11 --- /dev/null +++ b/apps/template/crt0-arm.S @@ -0,0 +1,28 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: template/crt0-arm.S + * Description: example server startup code for StrongARM processors + * + * @LICENSE@ + * + * $Id: crt0-arm.S,v 1.3 2001/12/13 03:25:43 ud3 Exp $ + * + ********************************************************************/ + .globl _start +_start: + ldr sp, 2f + bl main +1: b 1b +2: .word _stack_top + + .globl __gccmain +__gccmain: + mov pc,lr + + .bss + .p2align 12 +_stack_bottom: + .space 8192 +_stack_top: diff --git a/apps/template/crt0-x86.S b/apps/template/crt0-x86.S new file mode 100644 index 0000000..85c29ea --- /dev/null +++ b/apps/template/crt0-x86.S @@ -0,0 +1,46 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: template/crt0-x86.S + * Description: example server startup code for x86 processors + * + * @LICENSE@ + * + * $Id: crt0-x86.S,v 1.5 2001/11/30 14:20:06 ud3 Exp $ + * + ********************************************************************/ + .text + .global _start + .global _stext +_stext: +_start: + leal __stack, %esp + pushl %eax + pushl %ebx + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/template/main.c b/apps/template/main.c new file mode 100644 index 0000000..b7ad7da --- /dev/null +++ b/apps/template/main.c @@ -0,0 +1,23 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: template/main.c + * Description: example "hello world" server + * + * @LICENSE@ + * + * $Id: main.c,v 1.2 2001/11/30 14:20:06 ud3 Exp $ + * + ********************************************************************/ +#include +#include + +int main(void*) +{ + + printf("%s: started\n", __FUNCTION__); + + while(1973) + /* do nothing */; +} diff --git a/apps/testing/migrate/Makefile b/apps/testing/migrate/Makefile new file mode 100644 index 0000000..31c063f --- /dev/null +++ b/apps/testing/migrate/Makefile @@ -0,0 +1,22 @@ +include ../../Makeconf + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include +LDFLAGS += -N -L../../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ + +TARGET = $(notdir $(shell "pwd")) + +LINKBASE=0x00200000 + +all: $(TARGET).stripped + +$(TARGET): $(OBJS) Makefile ../../lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) -lio -lgcc + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/testing/migrate/crt0-arm.S b/apps/testing/migrate/crt0-arm.S new file mode 100644 index 0000000..594350e --- /dev/null +++ b/apps/testing/migrate/crt0-arm.S @@ -0,0 +1,15 @@ + .globl _start +_start: + ldr sp, 2f + bl main +1: b 1b +2: .word _stack_top + + .globl __gccmain +__gccmain: + mov pc,lr + + .bss +_stack_bottom: + .space 8192 +_stack_top: diff --git a/apps/testing/migrate/crt0-x86.S b/apps/testing/migrate/crt0-x86.S new file mode 100644 index 0000000..3599507 --- /dev/null +++ b/apps/testing/migrate/crt0-x86.S @@ -0,0 +1,36 @@ + .text + .global _start + .global _stext +_stext: +_start: + int3 + nop + leal __stack, %esp + pushl %ebx /* mbi ptr */ + pushl %eax /* mb magic */ + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/testing/migrate/main.c b/apps/testing/migrate/main.c new file mode 100644 index 0000000..a980092 --- /dev/null +++ b/apps/testing/migrate/main.c @@ -0,0 +1,93 @@ +#include +#include +#include + + +/* assumption: local apic is user accessible mapped at 0xf00f0000 */ + + +#define KERNEL_LOCAL_APIC (0xF00F0000) +#define X86_APIC_ID 0x020 +/* + * local APIC + */ +static inline dword_t get_local_apic(dword_t reg) +{ + dword_t tmp; + tmp = *(__volatile__ dword_t*)(KERNEL_LOCAL_APIC + reg); + return tmp; +}; +static inline int get_apic_cpu_id() +{ + return ((get_local_apic(X86_APIC_ID) >> 24) & 0xf); +} + +static inline void sleep(int time) +{ +#if 0 + l4_sleep(time); +#else + for (int i=0; i + + .section .init + +ENTRY(__crt_dummy__) +ENTRY(_start) +ENTRY(start) + leal SYMBOL_NAME(_stack),%esp + pushl %eax + pushl %ebx + pushl $SYMBOL_NAME(_exit) + jmp SYMBOL_NAME(main) + +ENTRY(__main) + ret + + /* MultiBoot header - see multiboot.h. */ +#ifdef __ELF__ + .align 4 +#else /* ! __ELF__, that mean a.out assembler */ + .align 2 +#endif + +ENTRY(_mb_header) + .long 0x1BADB002 /* magic */ + .long 0x00010000 /* flags: AOUT_KLUDGE */ + .long - 0x00010000 - 0x1BADB002 + .long SYMBOL_NAME(_mb_header) /* header_addr */ + .long SYMBOL_NAME(__crt_dummy__) /* load_addr */ + .long _edata /* load_end_addr */ + .long _end /* bss_end_addr */ + .long SYMBOL_NAME(_start) /* entry */ + + .bss + + .space 1024 +ENTRY(_stack) diff --git a/apps/testing/pingpongsmp/doit b/apps/testing/pingpongsmp/doit new file mode 100644 index 0000000..a6f47b9 --- /dev/null +++ b/apps/testing/pingpongsmp/doit @@ -0,0 +1 @@ +gcc -Telf_i386.l4 -nostdlib -o ~/boot/l4-ka/pingpong '-DL4_INLINE=static inline' crt0.S receiver.S pingpong.c -I ~/L4/l4-ka/apps/rmgr/include/ -I ~/L4/l4-ka/apps/rmgr/include/l4/x86-x0-32/ -I. -I ~/drops/l4/include -L ~/drops/l4/lib/ -L /home/ud3/drops/oskit/ -L ~/L4/l4-ka/apps/rmgr/lib/ -L ~/L4/l4-ka/apps/lib -ll4util -lrmgr -loskit_support -loskit_kern -lio -lmc -O2 && chmod a+r /home/ud3/boot/l4-ka/pingpong diff --git a/apps/testing/pingpongsmp/elf_i386.l4 b/apps/testing/pingpongsmp/elf_i386.l4 new file mode 100644 index 0000000..b831a25 --- /dev/null +++ b/apps/testing/pingpongsmp/elf_i386.l4 @@ -0,0 +1,127 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/elf_i386/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ +/* . = 0x0400000 + SIZEOF_HEADERS; */ + . = 0x0800000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : + { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : + { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : + { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0x9090 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0x9090 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(0x1000) + (ALIGN(8) & (0x1000 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : + { + *(.ctors) + } + .dtors : + { + *(.dtors) + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff --git a/apps/testing/pingpongsmp/pingpong.c b/apps/testing/pingpongsmp/pingpong.c new file mode 100644 index 0000000..2f5f16d --- /dev/null +++ b/apps/testing/pingpongsmp/pingpong.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include + +#include + +#define LTHREAD_NO_RECEIVER 1 +#define LTHREAD_NO_SENDER 0 + +l4_threadid_t sender_id, receiver_id; + +unsigned char receiver_stack[1000]; + +extern inline void +rdtsc(unsigned long *time) +{ + __asm__ volatile ("pushl %%edx\n" + ".byte 0x0f, 0x31\n" + "popl %%edx\n" + : "=a" (*time) + : + : "dx" + ); +}; + +static inline void rdpmc(int no, qword_t* res) +{ + dword_t dummy; + __asm__ __volatile__ ( + "rdpmc" + : "=a"(*(dword_t*)res), "=d"(*((dword_t*)res + 1)), "=c"(dummy) + : "c"(no) + : "memory"); +} + + +void +start_receiver(void); +void +pong(void); +void +ping(); + +void start_receiver(void) +{ + dword_t dummy; + l4_msgdope_t result; + l4_threadid_t foo_id; + l4_sched_param_t schedparam; + + sender_id = receiver_id = l4_myself(); + receiver_id.id.task++; + receiver_id.id.chief = sender_id.id.task; + + rmgr_init(); + if (rmgr_get_task(receiver_id.id.task)) { + printf("(rmgr)create pong failed"); + exit(1); + } + + printf("calling l4_task_new(%x.%x, %d, %p, %p, %x.%x);\n", + receiver_id.lh.high, receiver_id.lh.low, + 255, &receiver_stack[255], pong, l4_myself().lh.high, + l4_myself().lh.low); + receiver_id = l4_task_new(receiver_id, 255, + (unsigned int)&receiver_stack[255], + (unsigned int)pong, l4_myself()); + + if (l4_is_nil_id(receiver_id)) { + printf("create pong failed"); + exit(1); + } + + l4_thread_switch(receiver_id); + + if (l4_i386_ipc_receive(receiver_id, L4_IPC_SHORT_MSG, &dummy, &dummy, + L4_IPC_NEVER, &result)) { + printf("error while receiving pf"); + exit(1); + } + + if (l4_i386_ipc_send(receiver_id, L4_IPC_SHORT_FPAGE, + 0, /* send base */ + l4_fpage(0, L4_WHOLE_ADDRESS_SPACE, + L4_FPAGE_RW, L4_FPAGE_MAP).fpage, + L4_IPC_TIMEOUT(0, 1, 0, 0, 0, 0), + &result)) { + printf("error while mapping addr space"); + exit(1); + } + +#if 0 + foo_id = L4_INVALID_ID; + l4_thread_schedule(receiver_id, (dword_t) -1, &foo_id, &foo_id, &schedparam); + schedparam.sp.small = L4_SMALL_SPACE(32, 1); + foo_id = L4_INVALID_ID; + l4_thread_schedule(receiver_id, schedparam, &foo_id, &foo_id, &schedparam); +#endif + /* one time around to synchronize with receiver */ + if (l4_i386_ipc_call(receiver_id, + L4_IPC_SHORT_MSG, dummy, dummy, + L4_IPC_SHORT_MSG, &dummy, &dummy, + L4_IPC_NEVER, &result)) { + printf("error while syncing with pong"); + exit(1); + } + printf("receiver ready"); +} + +#define RCV_MAN 255 +#define RCV_EXP 6 +extern long counter; +long ping_start, ping_stop; + +void activate_fpu(void); +void activate_fpu(void) +{ + static double x = 4195835.0; + static double y = 3145727.0; + static long fdiv_bug; + + printf("Checking 386/387 coupling... \n"); + __asm__("fninit\n\t" + "fldl %1\n\t" + "fdivl %2\n\t" + "fmull %2\n\t" + "fldl %1\n\t" + "fsubp %%st,%%st(1)\n\t" + "fistpl %0\n\t" + "fwait\n\t" + "fninit" + : "=m" (*&fdiv_bug) + : "m" (*&x), "m" (*&y)); + if (!fdiv_bug) { + printf("Ok, fpu using exception 16 error reporting.\n"); + return; + } +} + + +int +main(void) +{ + qword_t cnt0,cnt1; + + start_receiver(); + + while(1) + { +#define ROUNDS 100000 + + counter = ROUNDS; + + rdpmc(0,&cnt0); + rdtsc(&ping_start); + ping(); + rdtsc(&ping_stop); + rdpmc(0,&cnt1); + printf("\ncycles: %ld (%lx, %lx)\n", (ping_stop-ping_start)/(ROUNDS*2), + ping_stop, ping_start); + printf("rdpmc(0) = %Ld\n", cnt0); + printf("rdpmc(0) = %Ld\n", cnt1); + printf("events: %Ld\n", ((long)(cnt1-cnt0)*100)/(ROUNDS*2)); + +#if 0 + printf("activating fpu"); + activate_fpu(); + + counter = ROUNDS; + rdtsc(&ping_start); + ping(); + rdtsc(&ping_stop); + printf("cycles: %ld (%lx, %lx)\n", (ping_stop-ping_start)/(ROUNDS*2), + ping_stop, ping_start); +#endif + enter_kdebug("finished"); + } + return 0; +} diff --git a/apps/testing/pingpongsmp/receiver.S b/apps/testing/pingpongsmp/receiver.S new file mode 100644 index 0000000..a09cee8 --- /dev/null +++ b/apps/testing/pingpongsmp/receiver.S @@ -0,0 +1,89 @@ +#define __ASSEMBLY__ +#include + +#if 1 +#define IPC_SYSENTER int $0x30 +#else +#define IPC_SYSENTER \ +push %ecx ; \ +push %ebp ; \ +push $0x23 ; \ +push $0f ; \ +mov %esp,%ecx ; \ +sysenter ; \ +mov %ebp,%edx ; \ +0: +#endif + +#define PONG \ + movl SYMBOL_NAME(sender_id)+4, %edi ;\ + movl SYMBOL_NAME(sender_id), %esi ;\ + xorl %ebp, %ebp ;\ + xorl %ecx, %ecx ;\ + IPC_SYSENTER ;\ + ;\ + test %al, %al ;\ + jnz pong_exit ;\ + ;\ + xorl %eax, %eax + +#define PING \ + movl SYMBOL_NAME(receiver_id)+4, %edi ;\ + movl SYMBOL_NAME(receiver_id), %esi ;\ + xorl %eax, %eax ;\ + xorl %ebp, %ebp ;\ + xorl %ecx, %ecx ;\ + IPC_SYSENTER ;\ + ;\ + test %al, %al ;\ + jnz ping_exit + .globl counter +counter: .long 0 + + +ENTRY(pong) + movl $-1, %eax + ALIGN +pong_loop: + PONG + PONG + PONG + PONG + jmp pong_loop +pong_exit: + int $3 + jmp 1f + .ascii "pong error" +1: + jmp 1b + +ENTRY(ping) + pushl %ebp + pushl %ebx + pushl %edi + pushl %esi +ping_loop: + PING + PING + PING + PING + subl $4, SYMBOL_NAME(counter) + jnz ping_loop + + popl %esi + popl %edi + popl %ebx + popl %ebp + ret + +ping_exit: + int $3 + jmp 1f + .ascii "ping error" +1: + popl %esi + popl %edi + popl %ebx + ret + + \ No newline at end of file diff --git a/apps/testing/smpipc/Makefile b/apps/testing/smpipc/Makefile new file mode 100644 index 0000000..9dc68bc --- /dev/null +++ b/apps/testing/smpipc/Makefile @@ -0,0 +1,22 @@ +include ../../Makeconf + +SRCS = crt0-$(ARCH).S $(wildcard *.c) +OBJS = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(SRCS))) + +INCLUDES += ../../include +LDFLAGS += -N -L../../lib +DEFINES += USE_L4_TYPES +CFLAGS += -x c++ + +TARGET = $(notdir $(shell "pwd")) + +LINKBASE=0x00220000 + +all: $(TARGET).stripped + +$(TARGET): $(OBJS) Makefile ../../lib/libio.a + $(LD) $(LDFLAGS) -e_start -Ttext=$(LINKBASE) -o $@ $(OBJS) -lio -lgcc + +clean:: + rm -f $(TARGET) $(TARGET).stripped + diff --git a/apps/testing/smpipc/crt0-arm.S b/apps/testing/smpipc/crt0-arm.S new file mode 100644 index 0000000..594350e --- /dev/null +++ b/apps/testing/smpipc/crt0-arm.S @@ -0,0 +1,15 @@ + .globl _start +_start: + ldr sp, 2f + bl main +1: b 1b +2: .word _stack_top + + .globl __gccmain +__gccmain: + mov pc,lr + + .bss +_stack_bottom: + .space 8192 +_stack_top: diff --git a/apps/testing/smpipc/crt0-x86.S b/apps/testing/smpipc/crt0-x86.S new file mode 100644 index 0000000..3599507 --- /dev/null +++ b/apps/testing/smpipc/crt0-x86.S @@ -0,0 +1,36 @@ + .text + .global _start + .global _stext +_stext: +_start: + int3 + nop + leal __stack, %esp + pushl %ebx /* mbi ptr */ + pushl %eax /* mb magic */ + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/testing/smpipc/main.c b/apps/testing/smpipc/main.c new file mode 100644 index 0000000..2f5797b --- /dev/null +++ b/apps/testing/smpipc/main.c @@ -0,0 +1,87 @@ +#include +#include +#include + + +/* assumption: local apic is user accessible mapped at 0xf00f0000 */ + + +#define KERNEL_LOCAL_APIC (0xF00F0000) +#define X86_APIC_ID 0x020 +/* + * local APIC + */ +static inline dword_t get_local_apic(dword_t reg) +{ + dword_t tmp; + tmp = *(__volatile__ dword_t*)(KERNEL_LOCAL_APIC + reg); + return tmp; +}; +static inline int get_apic_cpu_id() +{ + return ((get_local_apic(X86_APIC_ID) >> 24) & 0xf); +} + +static inline void sleep(int time) +{ +#if 0 + l4_sleep(time); +#else + for (int i=0; i"; echo ""; cat $(TOPDIR)/kernel/include/kernel.h | awk 'BEGIN{printme=0} /typedef struct kernel_info_page_t {/ {printme = 1 } { if (printme == 1 ) { print $0 } } /} kernel_info_page_t;/ { printme = 0}' ; echo "#endif" ) > $@ + +#tcb.h: Makefile $(TOPDIR)/kernel/include/thread.h +# @echo Building include file for tcb_t +# @( echo "#ifndef __TCB_H__"; echo "#define __TCB_H__"; echo ""; echo "#include "; echo ""; cat $(TOPDIR)/kernel/include/thread.h | awk 'BEGIN{printme=0} /*cut here*/ {printme = 1 } { if (printme == 1 ) { print $0 } } /*cut there*/ { printme = 0}' ; echo "#endif" ) > $@ + +copy: all + cp $(TARGET) /tftpboot/ diff --git a/apps/topp/crt0-x86.S b/apps/topp/crt0-x86.S new file mode 100644 index 0000000..2b7071f --- /dev/null +++ b/apps/topp/crt0-x86.S @@ -0,0 +1,34 @@ + .text + .global _start + .global _stext +_stext: +_start: + leal __stack, %esp + pushl %eax + pushl %ebx + pushl $___return_from_main + jmp main + +#if 1 + .align 16, 0x90 +__mb_header: + .long 0x1BADB002; + .long 0x00010000; + .long - 0x00010000 - 0x1BADB002; + .long __mb_header; + .long _start; + .long _edata; + .long _end; + .long _start; +#endif + +___return_from_main: + int $3 + jmp 1f + .ascii "System stopped." +1: jmp ___return_from_main + + .bss + + .space 1024 +__stack: diff --git a/apps/topp/topp.c b/apps/topp/topp.c new file mode 100644 index 0000000..155c7d0 --- /dev/null +++ b/apps/topp/topp.c @@ -0,0 +1,718 @@ +/* + * TOPP + */ + +//#define CONFIG_TIME_DEMO 1 +/* + * if enabled, the pagefault handling time will be measured via x86 MTTR + * therefore the handling is made atomic via cli/sti + */ + +#define CONFIG_TCB_DEBUG 1 + +#include +#include +#include +#include +#include +#include "universe.h" +#include "sync.h" + +//static dword_t pager_stack[STACK_SIZE]; +static dword_t checkpointer_stack[STACK_SIZE]; +static dword_t dirty_bits[MAX_MEM / PAGE_SIZE / WORD_SIZE]; +static dword_t cow_bits[MAX_MEM / PAGE_SIZE / WORD_SIZE]; + +static volatile pa_t page_array[MAX_MEM / PAGE_SIZE]; +static dword_t PAGE_COUNT; +static dword_t BITS_COUNT; +static dword_t FREE_PAGE; +static dword_t ACTIVE_CKP; + +static dword_t ide_block_offset; +static dword_t ide_header_offset; +static dword_t ide_block_num; +static dword_t ide_drive; + +/* + * internal id's + */ + +static l4_threadid_t pager_id, check_id; + +/* + * time measure macro + */ + +#ifdef CONFIG_TIME_DEMO +#define rdtsc(x) __asm__ __volatile__ ("rdtsc" : "=a"(x): : "edx"); +#define cli __asm__ __volatile__ ("cli":::); +#define sti __asm__ __volatile__ ("sti":::); +#endif + + +#define memset(value, dest, numwords) \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep\n\t" \ + "stosl" \ + : "=c" (dummy), "=d" (dummy)\ + : "a" (value), "D" (dest), "c" (numwords) ) + +/* + * Some simple functions on the datastructures + */ + +dword_t is_page_in (dword_t vmem, l4_threadid_t requestor) +{ + //simply searches the mapping data structures + + dword_t page1 = (vmem & PAGE_MASK | requestor.id.task); + dword_t page2 = (vmem & PAGE_MASK | requestor.id.task) ^ (1 << 8); + dword_t page3 = page1 ^ (1 << 11); + dword_t page4 = page2 ^ (1 << 11); + + //if is a bit clumsy with the present bit + for (dword_t i = 0; i < PAGE_COUNT; i++) + if (page_array[i].vmem == page1 || page_array[i].vmem == page2 || + page_array[i].vmem == page3 || page_array[i].vmem == page4) + return i; + return INVALID_P; + +} + +void +dump_array () +{ + //debug output + + dword_t k = 0; + + for (dword_t i = 0; i < PAGE_COUNT; i++) + { + + if (page_array[i].addr.taskid != 0xff) + { + printf ("%x ", page_array[i].vmem); + k++; + if (k == 6) + { + k = 0; + printf ("\n"); + printf ("%d: ", i); + } + } + } + printf ("\n"); + +} + +void +dump_mem (void *start, dword_t count) +{ + char *buffer2 = (char *) start; + for (dword_t jj = 0; jj < count / 16; jj++) + { + printf ("%x:\t", buffer2); + for (dword_t jjj = 0; jjj < 16; jjj++) + { + printf ("%x ", *buffer2); + buffer2++; + } + printf ("\n"); + } +} + +dword_t map_to (dword_t vmem, l4_threadid_t requestor) +{ + //assign a free page to a task id + static dword_t i; + dword_t tmp = i; + dword_t flag = 1; + while (1) + { + if (page_array[i].addr.taskid == 0xff) + break; + i++; + i %= PAGE_COUNT; + if (i == tmp) + { + flag = 0; + break; + } + } + if (flag) + { + page_array[i].vmem = (vmem & PAGE_MASK) | requestor.id.task; + return i; + } + else + return INVALID_P; + +} + +dword_t cow_page (dword_t old, l4_threadid_t requestor) +{ + //copy a page to a different location + + dword_t i = map_to ((page_array[old].vmem & PAGE_MASK), requestor); + + if (i != INVALID_P) + { + + dword_t *to = (dword_t *) (MTAB_BASE + i * PAGE_SIZE); + dword_t *from = (dword_t *) (MTAB_BASE + old * PAGE_SIZE); + if (((MTAB_BASE + i * PAGE_SIZE) & PAGE_MASK) == 0x0 || + ((MTAB_BASE + old * PAGE_SIZE) & PAGE_MASK) == 0x0) + enter_kdebug (); + memcpy (to, from, 4096); + + page_array[old].addr.taskid = 0xff; + + return i; + + } + else + { + + return INVALID_P; + + } +} + +void +read_old () +{ + //reads old data structures + ide_init (); + char buffer[512]; + ide_drive = 0; + + //searching topp-partition + + int result = ide_read (ide_drive, 0, (void *) buffer, 512); + if (result) + { + enter_kdebug ("ide-read error"); + } + partition_t *ptable = (partition_t *) (buffer + 0x000001be); + int i = 0; + while ((i < 4) && (ptable->sys != TOPP_SYS_CODE)) + { + i++; + ptable++; +#ifdef DEBUG + printf (" %d entry: %x \n", i, ptable->sys); +#endif + } + + if (i == 4) + enter_kdebug ("no TOPP-Partition found"); + ide_block_num = ptable->numsec; + ide_block_offset = ptable->start; + printf ("found partition@%x size %x blocks\n", ide_block_offset, + ide_block_num); + + //reading topp-Partition + + result = ide_read (ide_drive, ide_block_offset, (void *) buffer, 512); + partition_header_t *header = (partition_header_t *) buffer; + if (header->magic != HEADER_MAGIC) + { + enter_kdebug ("uninitialised Parititon found\n"); + //nothing else to do + return; + } + return; + printf ("found %d used entries\n", header->used_entries); + + ide_header_offset = header->addr_first_block; + if (header->used_entries < PAGE_COUNT) + enter_kdebug ("not enough pages to load checkpoint"); + + //use either full amount of entries or the first PAGE_COUNT ones + int end_of_header = (header->used_entries < PAGE_COUNT) ? + header->used_entries : PAGE_COUNT; + printf ("found %d entries starting blocks at %x\n", + header->used_entries, header->addr_first_block); + + //reading old mappings + int offset = sizeof (partition_header_t); + int block_count = 0; + int count = offset; + for (int k = offset; k < end_of_header + offset; k++) + { + if (count == 128) + { + count = 0; + block_count++; + result = ide_read (ide_drive, ide_block_offset + block_count, + (void *) buffer, 512); + if (result) + enter_kdebug ("ide-read error"); + } + page_array[k - offset].vmem = buffer[count]; + count++; + } + + //reset present bit to 0 on all vmem's + + for (int i = 0; i < MAX_MEM / PAGE_SIZE; i++) + { + if (page_array[i].addr.taskid != 0xff) + page_array[i].addr.present = 0; + } +} + +void +write_mapping () +{ + //writes mapping to disk + dword_t buffer[128]; + partition_header_t *header = (partition_header_t *) buffer; + header->used_entries = PAGE_COUNT; + header->magic = HEADER_MAGIC; + header->addr_first_block = ide_block_offset + HEADER_LENGTH; + dword_t count = sizeof (partition_header_t); + dword_t block_count = 0; + // dump_array(); + for (dword_t i = 0; i < PAGE_COUNT; i++) + { + if (count != 128) + { + buffer[count] = page_array[i].vmem & (~(0xf << 8)); + count++; + } + else + { + count = 0; + ide_write (ide_drive, ide_block_offset + block_count, + (void *) buffer, 512); + block_count++; + } + } + for (; count < 128; count++) + buffer[count] = 0xffffffff; + ide_write (ide_drive, ide_block_offset + block_count, (void *) buffer, 512); + +} + +inline void +read_page (dword_t i) +{ + //loads a single 4 k page from disk + dword_t page = i * PAGE_SIZE + MTAB_BASE; + int result = ide_read (ide_drive, + (i * (PAGE_SIZE / BLOCK_SIZE)) + ide_header_offset + + HEADER_LENGTH, (void *) page, PAGE_SIZE); + if (result) + enter_kdebug ("ide-read error"); + page_array[i].addr.present = 1; +} + +inline void +write_page (dword_t i) +{ + //writes a single 4 k page from disk + dword_t page = i * PAGE_SIZE + MTAB_BASE; + int result = ide_write (ide_drive, + (i * (PAGE_SIZE / BLOCK_SIZE)) + ide_header_offset + + HEADER_LENGTH, (void *) page, PAGE_SIZE); + if (result) + enter_kdebug ("ide-write error"); + +} + +/* + * pager thread + * + * no exception handling, yet + */ + +void +pager_thread () +{ + + dword_t dw0, dw1, dw2 = 0; + l4_threadid_t requestor, req = L4_NIL_ID; + l4_msgdope_t result; + l4_fpage_t fpage; + fpage.fpage = 0; + fpage.fp.write = 1; + fpage.fp.size = PAGE_BITS; + + dword_t fpage_base = 0; + dword_t snd_msg = 0; + + printf ("waiting for PF-IPC\n"); + l4_ipc_wait (&requestor, NULL, &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); +#ifdef CONFIG_TIME_DEMO + dword_t in, out; + dword_t flag = 0; +#endif + + while (1) + { +#ifdef CONFIG_TIME_DEMO + rdtsc (in); +#endif + +#ifdef CONFIG_TCB_DEBUG + printf ("received pagefault from %x@%x\n", requestor, dw0); + dump_array (); +#endif + if (result.raw) + { + printf("raw result of IPC %x\n", result.raw); + enter_kdebug ("error on PF-IPC: "); + } + + if (requestor == check_id) + { + //shutdown paging for checkpointing + l4_ipc_call (check_id, 0, 42, 0, 0, NULL, &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); + requestor = L4_NIL_ID; + printf ("waiting for PF-IPC\n"); + l4_ipc_wait (&requestor, NULL, &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); +#ifdef CONFIG_TCB_DEBUG + printf ("received pagefault from %x@%x\n", requestor, dw0); + dump_array (); +#endif + } + else + { + + req.raw = requestor.raw; + if (dw0 > TCB_AREA && dw0 < (TCB_AREA + TCB_AREA_SIZE)) + { + requestor.raw = 0; + requestor.id.task = 0x3; +#ifdef CONFIG_TCB_DEBUG + printf ("map into TCB-AREA\n"); +#endif + } + fpage_base = dw0 & PAGE_MASK; + dword_t i = is_page_in (dw0, requestor); +#ifdef CONFIG_TCB_DEBUG + printf ("%x: used entry: %x\n", i, page_array[i].vmem); +#endif + if (i != INVALID_P) + { +#ifdef CONFIG_TCB_DEBUG + printf ("found used page\n"); +#endif + snd_msg = 2; + + //if page on disk, then read from disk + if (!page_array[i].addr.present) + { +#ifdef CONFIG_TCB_DEBUG + printf ("page not present\n"); +#endif + read_page (i); + page_array[i].addr.present = 1; + } + + //remap page writeable + if (ACTIVE_CKP + && (cow_bits[i / WORD_SIZE] & (1 << (i % WORD_SIZE)))) + { + //copy page somewhere else if currently checkpointing +#ifdef CONFIG_TCB_DEBUG + printf ("making page %x cow\n", i); +#endif + dword_t next = cow_page (i, requestor); +#ifdef CONFIG_TIME_DEMO + flag = 1; +#endif + if (next != INVALID_P) + { +#ifdef CONFIG_TCB_DEBUG + printf ("move page %x -> %x\n", i, next); +#endif + l4_fpage_t unmap; + unmap.fpage = ((i * PAGE_SIZE + MTAB_BASE) | (12 << 2)); + while (lock_page ((void *) (page_array + i))) + { +#ifdef CONFIG_TCB_DEBUG + printf ("pager caught in %x\n", i); +#endif + l4_yield (); + } + l4_fpage_unmap (unmap, 2); + unlock_page ((void *) (page_array + i)); + i = next; + page_array[i].addr.present = 1; + } + else + enter_kdebug ("no free page found"); + + } + + fpage.fpage = i * PAGE_SIZE + MTAB_BASE; + + } + else + { + //map empty page + + i = map_to (dw0, requestor); + page_array[i].addr.present = 1; +#ifdef CONFIG_TCB_DEBUG + printf ("map zero page\n"); +#endif + if (i == INVALID_P) + { + enter_kdebug ("no more free pages"); + snd_msg = 0; + } + else + { + snd_msg = 2; + fpage.fpage = i * PAGE_SIZE + MTAB_BASE; + //zero fill + dword_t *dest = (dword_t *) fpage.fpage; + dword_t dummy; + memset (0, dest, 1024); +#ifdef CONFIG_TCB_DEBUG + printf ("deleting page %x\n", i); +#endif + } + + } + + //toggle dirty bit + dirty_bits[i / WORD_SIZE] = + dirty_bits[i / WORD_SIZE] | (1 << (i % WORD_SIZE)); + printf("dirty: %x\n", &dirty_bits[i / WORD_SIZE]); + fpage.fp.write = 1; + fpage.fp.grant = 0; + fpage.fp.zero = 0; + fpage.fp.size = PAGE_BITS; + if (snd_msg) + { + dw1 = fpage.fpage; + dw0 = fpage_base; + } + else + dw0 = dw1 = 0; + dw2 = 0; +#ifdef CONFIG_TCB_DEBUG + printf ("sending back fpage: %x base: %x to %x\n", dw1, dw0, req.raw); +#endif + +#ifdef CONFIG_TIME_DEMO + rdtsc (out); + out = (out - in) / 2; + if (flag) + printf ("%d \tCOPY!!!\n", out); + else + printf ("%d \n", out); + flag = 0; +#endif + + /* + * still missing the check whether receiving tcb is write protected + */ + + l4_ipc_reply_and_wait (req, (dword_t *) snd_msg, dw0, dw1, dw2, + &requestor, NULL, &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); + while(result.raw) + l4_ipc_wait (&requestor, NULL, &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); + } + } +} + +/* + * checkpoint thread + */ + +void +checkpoint_thread () +{ + dword_t mtab_bit = PAGE_BITS; + dword_t dw0, dw1, dw2; + l4_msgdope_t result; + while (((dword_t) (0x00000001 << mtab_bit)) < ((PAGE_SIZE * PAGE_COUNT))) + mtab_bit++; + l4_fpage_t fpage_all; + fpage_all.fpage = MTAB_BASE | (mtab_bit << 2); +#ifdef CONFIG_TCB_DEBUG + int k = 0; +#endif + + while (1) + { + //l4_ipc_sleep(255, 5); // ~4min + l4_sleep (mills (1000)); + printf ("stopping pager\n"); + l4_ipc_call (pager_id, 0, 0, 0, 0, NULL, &dw0, &dw1, &dw2, + L4_IPC_NEVER, &result); + printf ("pager stoped\n"); + ACTIVE_CKP = 0xffffffff; + +#ifdef CONFIG_TCB_DEBUG + printf ("start checkpointing ...\n"); + dump_array (); + // enter_kdebug (); +#endif + + // unmap all pages + l4_fpage_unmap (fpage_all, 0); //affect only other AS's + + // copy and reset dirty_bits + for (dword_t i = 0; i < PAGE_COUNT / WORD_SIZE; i++) + { + cow_bits[i] = dirty_bits[i]; + dirty_bits[i] = 0; + } + + //write back mappings + write_mapping (); + + //wake up pager + printf ("waking up pager\n"); + l4_ipc_send (pager_id, 0, dw0, dw1, dw2, L4_IPC_TIMEOUT_NULL, &result); + printf ("woke up pager\n"); +#ifdef CONFIG_TIME_DEMO + //sleep for measurements + l4_sleep (mills (1)); +#else + //write back dirty pages + printf ("write now used pages\n"); + dword_t p_c = 0; + dword_t p_s = 0; + for (dword_t i = 0; i < PAGE_COUNT / WORD_SIZE; i++) + { + if (cow_bits[i]) + { + dword_t j = 0; + dword_t jj = 0; + do + { + if (cow_bits[i] & (0x00000001 << j)) + { + jj = i * WORD_SIZE + j; + while (lock_page ((void *) (page_array + jj))) + { + printf ("checkpointer caught in %x", jj); + p_s++; + l4_yield (); + } + write_page (jj); + p_c++; + unlock_page ((void *) (page_array + jj)); + cow_bits[i] = cow_bits[i] & (~(1 << j)); + } + j++; + } + while (cow_bits[i]); + } + } +#endif + //clean up + ACTIVE_CKP = 0; +#ifdef CONFIG_TCB_DEBUG + printf ("Checkpoint on disk: %d pages %d locks\n", p_c, p_s); +#endif + } +} + +// lthread0 +int +main (void) +{ + l4_threadid_t mypagerid, myid, preempt_id; + dword_t dw0, dw1, dw2; + l4_msgdope_t result; + unsigned int dummyint; + + // get id of my pager + + myid = l4_myself (); + preempt_id = mypagerid = L4_INVALID_ID; + l4_thread_ex_regs (myid, 0xffffffff, 0xffffffff, &preempt_id, &mypagerid, + &dummyint, &dummyint, &dummyint); + + // get kernel info page + + l4_ipc_call (mypagerid, 0, 1, 1, 0, (void *) (INFO_BASE + 0x32), + &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); + kernel_info_page_t *infopage = (kernel_info_page_t *) INFO_BASE; + if (infopage->magic[0] != 'L' || + infopage->magic[1] != '4' || + infopage->magic[2] != 0xe6 || + infopage->magic[3] != 'K') + enter_kdebug ("unreadable kernel info page"); + printf ("%dMB Memory reported by kernel\n", + (infopage->main_mem_high / 1048576)); + dword_t pmem_base = + ((infopage->main_mem_high / PAGE_SIZE) * (100 - PERCENTAGE)) / 100 * + PAGE_SIZE; + //((infopage->main_mem_high/100)*(100-PERCENTAGE))&PAGE_MASK; + PAGE_COUNT = (infopage->main_mem_high - pmem_base) / PAGE_SIZE; + pmem_base = infopage->main_mem_high - PAGE_COUNT * PAGE_SIZE; + BITS_COUNT = PAGE_COUNT / WORD_SIZE; + FREE_PAGE = 0; + + // init the paging structures + for (dword_t k = 0; k < BITS_COUNT; k++) + { + dirty_bits[k] = cow_bits[k] = 0; + } + + // get the uppermost PERCENTAGE of pages from sigma0 + + dword_t pmap = pmem_base; + dword_t mapbase = (MTAB_BASE | 0x32); +#ifdef CONFIG_TCB_DEBUG + printf ("grabing %x pages from s0\n", PAGE_COUNT); + printf ("start address %x\n", pmem_base); +#endif + for (dword_t k = 0; k < PAGE_COUNT; k++) + { + // request arbitrary pages one after another pmap+0x2 + l4_ipc_call (mypagerid, 0, 0xfffffffc, 0x00400300, 0, + (void *) mapbase, &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); + // if no page returned + if (!dw0 & !dw1) + page_array[k].vmem = 0x0; + else + { + page_array[k].vmem = 0xFFFFFFFF; + FREE_PAGE++; + mapbase += PAGE_SIZE; + } + pmap += PAGE_SIZE; + } + + // loading of old datastructures from disk +#ifndef CONFIG_TIME_DEMO + read_old (); +#endif + + // start pager thread + pager_id.raw = myid.raw; + // pager_id.id.thread++; + l4_threadid_t tmp = mypagerid; + enter_kdebug (); + // l4_thread_ex_regs(pager_id, (dword_t) pager_thread, + // (dword_t) &(pager_stack[STACK_SIZE-1]), + // &preempt_id, &mypagerid, &dummyint, &dummyint, &dummyint); + + // start checkpoint thread + check_id.raw = myid.raw; + check_id.id.thread += 1; + l4_thread_ex_regs (check_id, (dword_t) checkpoint_thread, + (dword_t) & (checkpointer_stack[STACK_SIZE - 1]), + &preempt_id, &mypagerid, &dummyint, &dummyint, + &dummyint); + mypagerid = tmp; + pager_thread (); + // while(1) l4_yield(); + return 1; + //checkpoint_thread(); +} diff --git a/apps/topp/universe.h b/apps/topp/universe.h new file mode 100644 index 0000000..885bcf8 --- /dev/null +++ b/apps/topp/universe.h @@ -0,0 +1,97 @@ +#ifndef __universe_h +#define __universe_h + +#include "kip.h" +//#include "tcb.h" + +/* + * percentage of physical memory used for persistent threads + */ + +#define PERCENTAGE 10 +#define DEBUG 1 + +//some basics + +#define INFO_BASE 0x7FFFF000 +#define MTAB_BASE 0x80000000 +#define PAGE_BITS 12 +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define BLOCK_SIZE 512 +#define WORD_SIZE 32 +#define STACK_SIZE 1024 +#define INVALID_P 0xFFFFFFFF +#define TCB_AREA 0xe0000000 +#define L4_NUMBITS_TCBS 10 +#define TCB_SIZE (1 << L4_NUMBITS_TCBS) +#define TCB_AREA_SIZE 0x04000000 + +#define iskernelthread(x) IS_KERNEL_ID(x) + +#define MAX_MEM (128*1024*1024) + + + +/* + * decoding Pagefaults + */ + +#define WRITE_FAULT(y) (y&0x2) + +/* + * page array + * + * lock=1 page is locked for I/O or flushing + * present=0 page not in memory + * present=1 page in memory + * taskid=00 kernel + * taskid=ff unused + * unused should be 0 + */ + +typedef union pa_t +{ + dword_t vmem; + struct addr + { + unsigned taskid:8; + unsigned present:1; + unsigned unused:2; + unsigned lock:1; + unsigned vmem:20; + } + addr; +} +pa_t; + + +typedef struct partition_entry_t partition_t; +struct partition_entry_t +{ + byte_t boot; /* Boot flag: 0 = not active, 0x80 active */ + byte_t bhead; /* Begin: Head number */ + word_t bsecsyl; /* Begin: Sector and cylinder numb of boot sector */ + byte_t sys; /* System code: 0x83 linux, 0x82 Linux swap etc. */ + byte_t ehead; /* End: Head number */ + word_t esecsyl; /* End: Sector and cylinder number of last sector */ + dword_t start; /* Relative sector number of start sector */ + dword_t numsec; /* Number of sectors in the partition */ +} +__attribute__ ((packed)); + +typedef struct partition_header_t +{ + dword_t used_entries; + dword_t addr_first_block; + dword_t magic; +} +__attribute ((packed)); + +#define TOPP_SYS_CODE 0x90 + +#define HEADER_MAGIC 0x01281977 + +#define HEADER_LENGTH 2048 + +#endif diff --git a/apps/xconfig/.config b/apps/xconfig/.config new file mode 100644 index 0000000..c787690 --- /dev/null +++ b/apps/xconfig/.config @@ -0,0 +1,42 @@ +# +# Automatically generated make config: don't edit +# + +# +# Architecture +# +CONFIG_ARCH_ARM=n +CONFIG_ARCH_X86=y +CONFIG_ARCH_MIPS=n +CONFIG_ARCH_SH=n +CONFIG_ARCH_M68K=n +CONFIG_ARCH_ARM_DNARD=y +CONFIG_ARCH_ARM_BRUTUS=n +CONFIG_ARCH_ARM_PLEB=n +CONFIG_ARCH_ARM_IPAQ=n +CONFIG_ARCH_ARM_EP7211=n +CONFIG_ARCH_X86_I586=y +CONFIG_ARCH_MIPS_R4000=y +CONFIG_ARCH_SH_EMU=y +CONFIG_ARCH_SH_SH3=n +CONFIG_ARCH_SH_SH4=n +CONFIG_ARCH_M68K_DRAGONBALL=y + +# +# Kernel Configuration +# +CONFIG_VERSION_X0=y +CONFIG_VERSION_X1=n +CONFIG_L4_NEWSIGMA0=y +CONFIG_IO_FLEXPAGES=y +CONFIG_L4_SYSENTEREXIT=n + +# +# Base Applications +# +CONFIG_BUILD_SIGMA0=y +LBS0_X86=00020000 +CONFIG_BUILD_ROOTTASK=n +CONFIG_BUILD_RMGR=n +CONFIG_LIBIO_OUTSCRN=y +CONFIG_LIBIO_OUTCOM=n diff --git a/apps/xconfig/.cvsignore b/apps/xconfig/.cvsignore new file mode 100644 index 0000000..680897e --- /dev/null +++ b/apps/xconfig/.cvsignore @@ -0,0 +1,3 @@ +.config +tkparse +config.tk diff --git a/apps/xconfig/Makefile b/apps/xconfig/Makefile new file mode 100644 index 0000000..94c6968 --- /dev/null +++ b/apps/xconfig/Makefile @@ -0,0 +1,36 @@ +SHELL=bash + +ifeq ($(MACHTYPE), i686-pc-cygwin) + WISH=cygitkwish30 +else +ifneq ($(shell type -p wish8.3),) + WISH=wish8.3 +else + WISH=wish +endif +endif + +-include ../Makeconf.local + +doit: config.tk + @$(WISH) -f config.tk + @echo Rewriting Makeconf.local + @awk -F'[_=]' -f rewrite.awk .config | ed -s ../Makeconf.local + +config.tk: $(wildcard *.in) header.tk tail.tk tkparse + cat header.tk > config.tk && \ + ./tkparse < config.in >> config.tk && \ + echo "set defaults \"defconfig\"" >> config.tk && \ + cat tail.tk >> config.tk + +tkparse: tkparse.o tkcond.o tkgen.o + ${CC} -o tkparse tkparse.o tkcond.o tkgen.o + +../Makeconf.local: + @echo Creating default Makeconf.local + @echo "PLATFORM=i586" > $@ + @echo "SIGMA0_LINKBASE=" >> $@ + @echo "ROOTTASK_LINKBASE=" >> $@ + +clean: + rm -f *.o tkparse config.tk diff --git a/apps/xconfig/apps.in b/apps/xconfig/apps.in new file mode 100644 index 0000000..f35cc83 --- /dev/null +++ b/apps/xconfig/apps.in @@ -0,0 +1,67 @@ +mainmenu_option next_comment +comment 'Base Applications' + +bool 'Build sigma0' CONFIG_BUILD_SIGMA0 Y +if [ "$CONFIG_BUILD_SIGMA0" = "y" ]; then + if [ "$CONFIG_ARCH_ARM" = "y" ]; then + if [ "$CONFIG_ARCH_ARM_DNARD" = "y" ]; then + hex 'DNARD sigma0 base' LBS0_ARM_DNARD 0C000000 + fi + if [ "$CONFIG_ARCH_ARM_BRUTUS" = "y" ]; then + hex 'Brutus sigma0 base' LBS0_ARM_BRUTUS D0000000 + fi + if [ "$CONFIG_ARCH_ARM_PLEB" = "y" ]; then + hex 'PLEB sigma0 base' LBS0_ARM_PLEB C8020000 + fi + if [ "$CONFIG_ARCH_ARM_IPAQ" = "y" ]; then + hex 'IPaq sigma0 base' LBS0_ARM_IPAQ D0000000 + fi + if [ "$CONFIG_ARCH_ARM_EP7211" = "y" ]; then + hex 'EP7211 sigma0 base' LBS0_ARM_EP7211 C0400000 + fi + fi + if [ "$CONFIG_ARCH_X86" = "y" ]; then + hex 'X86 sigma0 base' LBS0_X86 00020000 + fi +fi + +bool 'Build root task' CONFIG_BUILD_ROOTTASK Y +if [ "$CONFIG_BUILD_ROOTTASK" = "y" ]; then + if [ "$CONFIG_ARCH_ARM" = "y" ]; then + if [ "$CONFIG_ARCH_ARM_DNARD" = "y" ]; then + hex 'DNARD root task base' LBRT_ARM_DNARD 0C100000 + fi + if [ "$CONFIG_ARCH_ARM_BRUTUS" = "y" ]; then + hex 'Brutus root task base' LBRT_ARM_BRUTUS D0100000 + fi + if [ "$CONFIG_ARCH_ARM_PLEB" = "y" ]; then + hex 'PLEB root task base' LBRT_ARM_PLEB C8040000 + fi + if [ "$CONFIG_ARCH_ARM_IPAQ" = "y" ]; then + hex 'IPaq root task base' LBRT_ARM_IPAQ D0100000 + fi + if [ "$CONFIG_ARCH_ARM_EP7211" = "y" ]; then + hex 'EP7211 root task base' LBRT_ARM_EP7211 C0500000 + fi + fi + if [ "$CONFIG_ARCH_X86" = "y" ]; then + hex 'X86 root task base' LBRT_X86 00300000 + fi +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then +bool 'Build resource manager' CONFIG_BUILD_RMGR Y +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + choice 'Putc output device' \ + "screen CONFIG_LIBIO_OUTSCRN \ + serial CONFIG_LIBIO_OUTCOM" y + + if [ "$CONFIG_LIBIO_OUTCOM" = "y" ] + hex 'Serial port address' CONFIG_LIBIO_COMPORT 3F8 + int 'Serial port speed' CONFIG_LIBIO_COMSPEED 115200 + fi +fi + +endmenu diff --git a/apps/xconfig/arch.in b/apps/xconfig/arch.in new file mode 100644 index 0000000..b12e9a6 --- /dev/null +++ b/apps/xconfig/arch.in @@ -0,0 +1,47 @@ +mainmenu_option next_comment +comment 'Architecture' + +if [ "1" != "0" ] then; + define_bool _CONFIG_ARCH y +fi + +choice 'Major CPU Architecture' \ + "arm CONFIG_ARCH_ARM \ + x86 CONFIG_ARCH_X86 \ + mips CONFIG_ARCH_MIPS \ + superh CONFIG_ARCH_SH \ + m68k CONFIG_ARCH_M68K" arm $_CONFIG_ARCH + +if [ "$CONFIG_ARCH_ARM" = "y" ]; then + choice 'ARM Board Type' \ + "DNARD CONFIG_ARCH_ARM_DNARD \ + Brutus CONFIG_ARCH_ARM_BRUTUS \ + PLEB CONFIG_ARCH_ARM_PLEB \ + IPaq CONFIG_ARCH_ARM_IPAQ \ + EP7211 CONFIG_ARCH_ARM_EP7211" DNARD $CONFIG_ARCH_ARM +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + choice 'x86 Model' \ + "i586 CONFIG_ARCH_X86_I586" i586 $CONFIG_ARCH_X86 +fi + +if [ "$CONFIG_ARCH_MIPS" = "y" ]; then + choice 'MIPS CPU Model' \ + "R4000 CONFIG_ARCH_MIPS_R4000" R4000 $CONFIG_ARCH_MIPS +fi + +if [ "$CONFIG_ARCH_SH" = "y" ]; then + choice 'SuperH Model' \ + "Emulator CONFIG_ARCH_SH_EMU \ + SH3 CONFIG_ARCH_SH_SH3 \ + SH4 CONFIG_ARCH_SH_SH4" SH3 $CONFIG_ARCH_SH +fi + + +if [ "$CONFIG_ARCH_M68K" = "y" ]; then + choice 'm68k CPU Model' \ + "Dragonball CONFIG_ARCH_M68K_DRAGONBALL" Dragonball $CONFIG_ARCH_M68K +fi + + diff --git a/apps/xconfig/config.help b/apps/xconfig/config.help new file mode 100644 index 0000000..480033a --- /dev/null +++ b/apps/xconfig/config.help @@ -0,0 +1,52 @@ +default sigma0 entry point +CONFIG_SIGMA0_ENTRY + Turning this on initializes the kernel info page with the given + values. Hence, there's no need for the boot process to write the + sigma0 initial IP and SP values to the kernel info page. + + src/global.c + +default root task entry point +CONFIG_ROOTTASK_ENTRY + Turning this on initializes the kernel info page with the given + values. Hence, there's no need for the boot process to write the + initial IP and SP values for the root task to the kernel info page. + + src/global.c + +Use SYSENTER/SYSEXIT for IPC +CONFIG_L4_SYSENTEREXIT + Turning this on uses the "sysenter" instruction for the IPC system + call. This currently works only with Jochen's version "Y". :-) + When switched off, the old-style "int $0x30" is used. + + include/l4/x86/ipc.h + +Disable INTs in user mode +CONFIG_USERMODE_NOIRQ + Setting this option to YES creates all user threads with disabled + interrupts. This could easily disable timer triggered events like + scheduling, IPC timeouts, etc. + + create_user_stack_frame in include/arch/thread.h + + +Trace kernel page faults +CONFIG_DEBUG_TRACE_KPF + If set to yes, kernel page faults are reported. + + src/arch/memory.c + + +Trace user page faults +CONFIG_DEBUG_TRACE_UPF + If set to yes, user page faults are reported. + + src/arch/memory.c + +Trace interrupts +CONFIG_DEBUG_TRACE_IRQS + If set, detection of an interrupt is reported + + src/arch/interrupt.c + diff --git a/apps/xconfig/config.in b/apps/xconfig/config.in new file mode 100644 index 0000000..7f9ecfe --- /dev/null +++ b/apps/xconfig/config.in @@ -0,0 +1,12 @@ +mainmenu_name "L4/KA Userland Configuration" + +source arch.in + +source kernel.in + +# source debugger.in + +source apps.in + +endmenu + diff --git a/apps/xconfig/config.tk b/apps/xconfig/config.tk new file mode 100644 index 0000000..4ebd409 --- /dev/null +++ b/apps/xconfig/config.tk @@ -0,0 +1,1167 @@ +# FILE: header.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1999, Michael Elizabeth Chastain, +# - Remove unused do_cmd function (part of the 2.0 sound support). +# - Arrange buttons in three columns for better screen fitting. +# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like: +# dep_tristate 'foo' CONFIG_FOO m +# +# 23 January 1999, Michael Elizabeth Chastain, +# - Shut vfix the hell up. +# +# 24 January 1999, Michael Elizabeth Chastain, +# - Improve the exit message (Jeff Ronne). + +# +# This is a handy replacement for ".widget cget" that requires neither tk4 +# nor additional source code uglification. +# +proc cget { w option } { + return "[lindex [$w configure $option] 4]" +} + +# +# Function to compensate for broken config.in scripts like the sound driver, +# which make dependencies on variables that are never even conditionally +# defined. +# +proc vfix { var } { + global $var + if [ catch {eval concat $$var} ] { + set $var 0 + } +} + +# +# Constant values used by certain dep_tristate commands. +# +set CONSTANT_Y 1 +set CONSTANT_M 2 +set CONSTANT_N 0 + +# +# Create a "reference" object to steal colors from. +# +button .ref + +# +# On monochrome displays, -disabledforeground is blank by default; that's +# bad. Fill it with -foreground instead. +# +if { [cget .ref -disabledforeground] == "" } { + .ref configure -disabledforeground [cget .ref -foreground] +} + + +# +# Define some macros we will need to parse the config.in file. +# + +proc mainmenu_name { text } { + wm title . "$text" +} + +proc menu_option { w menu_num text } { + global menus_per_column +# if { $menu_num <= $menus_per_column } then { +# set myframe left +# } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { +# set myframe middle +# } else { +# set myframe right +# } + if { $menu_num <= 6 } then { + set myframe arch + } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { + set myframe apps + } else { + set myframe control + } + button .f0.x$menu_num -anchor w -text "$text" \ + -command "$w .$w \"$text\"" + pack .f0.x$menu_num -pady 0 -side top -fill x -in .f0.$myframe +} + +proc load_configfile { w title func } { + catch {destroy $w} + toplevel $w -class Dialog + global loadfile + frame $w.x + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + label $w.x.l -text "Enter filename:" -relief raised + entry $w.x.x -width 35 -relief sunken -borderwidth 2 \ + -textvariable loadfile + pack $w.x.l $w.x.x -anchor w -side left + pack $w.x -side top -pady 10 + wm title $w "$title" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "destroy $w; focus $oldFocus;$func .fileio" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc maybe_exit { w } { + catch {destroy $w} + toplevel $w -class Dialog + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + message $w.m -width 400 -aspect 300 \ + -text "Changes will be lost. Are you sure?" -relief flat + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Are you sure?" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "exit" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc read_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 && [file readable $loadfile] == 1 } then { + read_config $loadfile + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to read file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Bummer" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc write_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 + && ([file writable $loadfile] == 1 || ([file exists $loadfile] == 0 && [file writable [file dirname $loadfile]] == 1)) } then { + writeconfig $loadfile /dev/null + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to write file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc read_config { filename } { + set file1 [open $filename r] + clear_choices + while { [gets $file1 line] >= 0} { + if [regexp {([0-9A-Za-z_]+)=([ynm])} $line foo var value] { + if { $value == "y" } then { set cmd "global $var; set $var 1" } + if { $value == "n" } then { set cmd "global $var; set $var 0" } + if { $value == "m" } then { set cmd "global $var; set $var 2" } + eval $cmd + } + if [regexp {# ([0-9A-Za-z_]+) is not set} $line foo var] { + set cmd "global $var; set $var 0" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)=([0-9A-Fa-f]+)} $line foo var value] { + set cmd "global $var; set $var $value" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { + set cmd "global $var; set $var \"$value\"" + eval $cmd + } + } + close $file1 + update_choices + update_mainmenu .rdupd +} +proc write_comment { file1 file2 text } { + puts $file1 "" + puts $file1 "#" + puts $file1 "# $text" + puts $file1 "#" + puts $file2 "/*" + puts $file2 " * $text" + puts $file2 " */" +} + +proc write_tristate { file1 file2 varname variable dep } { + if { $variable == 0 } \ + then { puts $file1 "$varname=n"; } \ + elseif { $variable == 1 && $dep == 0 } \ + then { puts $file1 "$varname=y"; } \ + elseif { $variable == 1 && $dep == 1 } \ + then { puts $file1 "$varname=y"; \ + puts $file2 "#define $varname 1" } \ + else { \ + puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ + } +} + +#proc write_tristate { file1 file2 varname variable dep } { +# if { $variable == 0 } \ +# then { puts $file1 "# $varname is not set"; \ +# puts $file2 "#undef $varname"} \ +# elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \ +# then { puts $file1 "$varname=m"; \ +# puts $file2 "#undef $varname"; \ +# puts $file2 "#define ${varname}_MODULE 1" } \ +# elseif { $variable == 1 && $dep != 2 } \ +# then { puts $file1 "$varname=y"; \ +# puts $file2 "#define $varname 1" } \ +# else { \ +# puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ +# } +#} + +proc write_int { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname $variable"; \ + } +} + +proc write_hex { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname 0x$variable"; \ + } +} + +proc write_string { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=\"$variable\""; \ + puts $file2 "#define $varname \"$variable\""; \ + } +} + +proc option_name {w mnum line text helpidx} { + button $w.x$line.l -text "$text" -relief groove -anchor w + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] + button $w.x$line.help -text "Help" -relief raised \ + -command "dohelp .dohelp $helpidx" + pack $w.x$line.help -side right -fill y + pack $w.x$line.l -side right -fill both -expand on +} + +proc toggle_switch2 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc toggle_switch3 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + global CONFIG_MODULES + if {($CONFIG_MODULES == 0)} then { + $w.x$line.m configure -state disabled + } + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc bool {w mnum line text variable} { + toggle_switch2 $w $mnum $line $text $variable + $w.x$line.m configure -state disabled + pack $w.x$line -anchor w -fill both -expand on +} + +proc tristate {w mnum line text variable } { + toggle_switch3 $w $mnum $line $text $variable + pack $w.x$line -anchor w -fill both -expand on +} + +proc dep_tristate {w mnum line text variable depend } { + tristate $w $mnum $line $text $variable +} + +proc int { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc hex { w mnum line text variable } { + int $w $mnum $line $text $variable +} + +proc istring { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc minimenu { w mnum line text variable helpidx } { + frame $w.x$line + menubutton $w.x$line.x -textvariable $variable -menu \ + $w.x$line.x.menu -relief raised \ + -anchor w + option_name $w $mnum $line $text $helpidx + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc comment {w line text } { +#nothing done for comments now. +} + +proc dohelp {w var } { + catch {destroy $w} + toplevel $w -class Dialog + + set filefound 0 + set found 0 + set lineno 0 + + if { [file readable config.help] == 1} then { + set filefound 1 + # First escape sed regexp special characters in var: + set var [exec echo "$var" | sed s/\[\]\[\/.^$*\]/\\\\&/g] + # Now pick out right help text: + set message [exec sed -n " + /^$var\[ \]*\$/,\${ + /^$var\[ \]*\$/c\\ +${var}:\\ + + /^#/b + /^\[^ \]/q + s/^ // + p + } + " config.help] + set found [expr [string length "$message"] > 0] + } + + frame $w.f1 + + if { $found == 0 } then { + if { $filefound == 0 } then { + message $w.f1.m -width 750 -aspect 300 -relief flat -text \ + "No help available - unable to open file config.help. This file should have come with your kernel." + } else { + message $w.f1.m -width 400 -aspect 300 -relief flat -text \ + "No help available for $var" + } + label $w.f1.bm -bitmap error + wm title $w "RTFM" + } else { + text $w.f1.m -width 73 -relief flat -wrap word + $w.f1.m insert 0.0 $message + $w.f1.m conf -state disabled -height [$w.f1.m index end] + + label $w.f1.bm -bitmap info + wm title $w "Configuration help" + } + pack $w.f1.bm $w.f1.m -side left -padx 10 + pack $w.f1 -side top + set oldFocus [focus] + + # Do the OK button + # + frame $w.f2 + button $w.f2.ok -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f2.ok -side bottom -pady 6 -anchor n + pack $w.f2 -side bottom -padx 10 -anchor s + + # Finish off the window + # + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc wrapup {w } { + catch {destroy $w} + toplevel $w -class Dialog + + message $w.m -width 400 -aspect 300 -relief raised -justify center -text \ + "Check the top-level Makefile for additional configuration." + + label $w.bm -bitmap info + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "End of L4/KA kernel configuration." + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "exit" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + +} + +# +# Next set up the particulars for the top level menu, and define a few +# buttons which we will stick down at the bottom. +# + +frame .f0 +frame .f0.arch +frame .f0.apps +frame .f0.control + +set menus_per_column 3 + +mainmenu_name "L4/KA Userland Configuration" +menu_option menu1 1 "Architecture" +proc menu1 {w title} { + catch {destroy $w} + toplevel $w -class Dialog + wm withdraw $w + message $w.m -width 400 -aspect 300 -text \ + "Architecture" -relief raised + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Architecture" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Main Menu" \ + -width 15 -command "destroy $w; focus $oldFocus; update_mainmenu $w" + button $w.f.next -text "Next" \ + -width 15 -command " destroy $w; focus $oldFocus; menu2 .menu2 \"$title\"" + button $w.f.prev -text "Prev" \ + -width 15 -command " destroy $w; focus $oldFocus; menu0 .menu0 \"$title\"" + $w.f.prev configure -state disabled + pack $w.f.back $w.f.next $w.f.prev -side left -expand on + pack $w.f -pady 10 -side bottom -anchor w -fill x + frame $w.topline -relief ridge -borderwidth 2 -height 2 + pack $w.topline -side top -fill x + + frame $w.botline -relief ridge -borderwidth 2 -height 2 + pack $w.botline -side bottom -fill x + + frame $w.config + pack $w.config -fill y -expand on + + scrollbar $w.config.vscroll -command "$w.config.canvas yview" + pack $w.config.vscroll -side right -fill y + + canvas $w.config.canvas -height 1\ + -relief flat -borderwidth 0 -yscrollcommand "$w.config.vscroll set" \ + -width [expr [winfo screenwidth .] * 1 / 2] + frame $w.config.f + pack $w.config.canvas -side right -fill y + + + global tmpvar_0 + minimenu $w.config.f 1 0 "Major CPU Architecture" tmpvar_0 CONFIG_ARCH_ARM + menu $w.config.f.x0.x.menu + $w.config.f.x0.x.menu add radiobutton -label "arm" -variable tmpvar_0 -value "arm" -command "update_menu1 .menu1.config.f" + $w.config.f.x0.x.menu add radiobutton -label "x86" -variable tmpvar_0 -value "x86" -command "update_menu1 .menu1.config.f" + $w.config.f.x0.x.menu add radiobutton -label "mips" -variable tmpvar_0 -value "mips" -command "update_menu1 .menu1.config.f" + $w.config.f.x0.x.menu add radiobutton -label "superh" -variable tmpvar_0 -value "superh" -command "update_menu1 .menu1.config.f" + $w.config.f.x0.x.menu add radiobutton -label "m68k" -variable tmpvar_0 -value "m68k" -command "update_menu1 .menu1.config.f" + global tmpvar_1 + minimenu $w.config.f 1 1 "ARM Board Type" tmpvar_1 CONFIG_ARCH_ARM_DNARD + menu $w.config.f.x1.x.menu + $w.config.f.x1.x.menu add radiobutton -label "DNARD" -variable tmpvar_1 -value "DNARD" -command "update_menu1 .menu1.config.f" + $w.config.f.x1.x.menu add radiobutton -label "Brutus" -variable tmpvar_1 -value "Brutus" -command "update_menu1 .menu1.config.f" + $w.config.f.x1.x.menu add radiobutton -label "PLEB" -variable tmpvar_1 -value "PLEB" -command "update_menu1 .menu1.config.f" + $w.config.f.x1.x.menu add radiobutton -label "IPaq" -variable tmpvar_1 -value "IPaq" -command "update_menu1 .menu1.config.f" + $w.config.f.x1.x.menu add radiobutton -label "EP7211" -variable tmpvar_1 -value "EP7211" -command "update_menu1 .menu1.config.f" + global tmpvar_2 + minimenu $w.config.f 1 2 "x86 Model" tmpvar_2 CONFIG_ARCH_X86_I586 + menu $w.config.f.x2.x.menu + $w.config.f.x2.x.menu add radiobutton -label "i586" -variable tmpvar_2 -value "i586" -command "update_menu1 .menu1.config.f" + global tmpvar_3 + minimenu $w.config.f 1 3 "MIPS CPU Model" tmpvar_3 CONFIG_ARCH_MIPS_R4000 + menu $w.config.f.x3.x.menu + $w.config.f.x3.x.menu add radiobutton -label "R4000" -variable tmpvar_3 -value "R4000" -command "update_menu1 .menu1.config.f" + global tmpvar_4 + minimenu $w.config.f 1 4 "SuperH Model" tmpvar_4 CONFIG_ARCH_SH_EMU + menu $w.config.f.x4.x.menu + $w.config.f.x4.x.menu add radiobutton -label "Emulator" -variable tmpvar_4 -value "Emulator" -command "update_menu1 .menu1.config.f" + $w.config.f.x4.x.menu add radiobutton -label "SH3" -variable tmpvar_4 -value "SH3" -command "update_menu1 .menu1.config.f" + $w.config.f.x4.x.menu add radiobutton -label "SH4" -variable tmpvar_4 -value "SH4" -command "update_menu1 .menu1.config.f" + global tmpvar_5 + minimenu $w.config.f 1 5 "m68k CPU Model" tmpvar_5 CONFIG_ARCH_M68K_DRAGONBALL + menu $w.config.f.x5.x.menu + $w.config.f.x5.x.menu add radiobutton -label "Dragonball" -variable tmpvar_5 -value "Dragonball" -command "update_menu1 .menu1.config.f" + + + + focus $w + update_menu1 $w.config.f + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + update idletasks + $w.config.canvas create window 0 0 -anchor nw -window $w.config.f + + $w.config.canvas configure \ + -width [expr [winfo reqwidth $w.config.f] + 1]\ + -scrollregion "-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \ + [expr [winfo reqheight $w.config.f] + 1]" + + set winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]] + set scry [expr [winfo screenh $w] / 2] + set maxy [expr [winfo screenh $w] * 3 / 4] + set canvtotal [expr [winfo reqh $w.config.f] + 2] + if [expr $winy + $canvtotal < $maxy] { + $w.config.canvas configure -height $canvtotal + } else { + $w.config.canvas configure -height [expr $scry - $winy] + } + update idletasks + wm maxsize $w [winfo width $w] [winfo screenheight $w] + wm minsize $w [winfo width $w] 100 + + wm deiconify $w +} + + +proc update_menu1 {w} { + update_define + global tmpvar_0; vfix tmpvar_0 + global CONFIG_ARCH_ARM_DNARD; vfix CONFIG_ARCH_ARM_DNARD + if {($tmpvar_0 == "arm")} then { .menu1.config.f.x1.x configure -state normal} else { .menu1.config.f.x1.x configure -state disabled} + global CONFIG_ARCH_ARM_BRUTUS; vfix CONFIG_ARCH_ARM_BRUTUS + if {($tmpvar_0 == "arm")} then { .menu1.config.f.x1.x configure -state normal} else { .menu1.config.f.x1.x configure -state disabled} + global CONFIG_ARCH_ARM_PLEB; vfix CONFIG_ARCH_ARM_PLEB + if {($tmpvar_0 == "arm")} then { .menu1.config.f.x1.x configure -state normal} else { .menu1.config.f.x1.x configure -state disabled} + global CONFIG_ARCH_ARM_IPAQ; vfix CONFIG_ARCH_ARM_IPAQ + if {($tmpvar_0 == "arm")} then { .menu1.config.f.x1.x configure -state normal} else { .menu1.config.f.x1.x configure -state disabled} + global CONFIG_ARCH_ARM_EP7211; vfix CONFIG_ARCH_ARM_EP7211 + if {($tmpvar_0 == "arm")} then { .menu1.config.f.x1.x configure -state normal} else { .menu1.config.f.x1.x configure -state disabled} + global CONFIG_ARCH_X86_I586; vfix CONFIG_ARCH_X86_I586 + if {($tmpvar_0 == "x86")} then { .menu1.config.f.x2.x configure -state normal} else { .menu1.config.f.x2.x configure -state disabled} + global CONFIG_ARCH_MIPS_R4000; vfix CONFIG_ARCH_MIPS_R4000 + if {($tmpvar_0 == "mips")} then { .menu1.config.f.x3.x configure -state normal} else { .menu1.config.f.x3.x configure -state disabled} + global CONFIG_ARCH_SH_EMU; vfix CONFIG_ARCH_SH_EMU + if {($tmpvar_0 == "superh")} then { .menu1.config.f.x4.x configure -state normal} else { .menu1.config.f.x4.x configure -state disabled} + global CONFIG_ARCH_SH_SH3; vfix CONFIG_ARCH_SH_SH3 + if {($tmpvar_0 == "superh")} then { .menu1.config.f.x4.x configure -state normal} else { .menu1.config.f.x4.x configure -state disabled} + global CONFIG_ARCH_SH_SH4; vfix CONFIG_ARCH_SH_SH4 + if {($tmpvar_0 == "superh")} then { .menu1.config.f.x4.x configure -state normal} else { .menu1.config.f.x4.x configure -state disabled} + global CONFIG_ARCH_M68K_DRAGONBALL; vfix CONFIG_ARCH_M68K_DRAGONBALL + if {($tmpvar_0 == "m68k")} then { .menu1.config.f.x5.x configure -state normal} else { .menu1.config.f.x5.x configure -state disabled} + + update_mainmenu $w +} + + +menu_option menu2 2 "Kernel Configuration" +proc menu2 {w title} { + catch {destroy $w} + toplevel $w -class Dialog + wm withdraw $w + message $w.m -width 400 -aspect 300 -text \ + "Kernel Configuration" -relief raised + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Kernel Configuration" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Main Menu" \ + -width 15 -command "destroy $w; focus $oldFocus; update_mainmenu $w" + button $w.f.next -text "Next" \ + -width 15 -command " destroy $w; focus $oldFocus; menu3 .menu3 \"$title\"" + button $w.f.prev -text "Prev" \ + -width 15 -command " destroy $w; focus $oldFocus; menu1 .menu1 \"$title\"" + pack $w.f.back $w.f.next $w.f.prev -side left -expand on + pack $w.f -pady 10 -side bottom -anchor w -fill x + frame $w.topline -relief ridge -borderwidth 2 -height 2 + pack $w.topline -side top -fill x + + frame $w.botline -relief ridge -borderwidth 2 -height 2 + pack $w.botline -side bottom -fill x + + frame $w.config + pack $w.config -fill y -expand on + + scrollbar $w.config.vscroll -command "$w.config.canvas yview" + pack $w.config.vscroll -side right -fill y + + canvas $w.config.canvas -height 1\ + -relief flat -borderwidth 0 -yscrollcommand "$w.config.vscroll set" \ + -width [expr [winfo screenwidth .] * 1 / 2] + frame $w.config.f + pack $w.config.canvas -side right -fill y + + + global tmpvar_6 + minimenu $w.config.f 2 0 "Kernel Interface Specification" tmpvar_6 CONFIG_VERSION_X0 + menu $w.config.f.x0.x.menu + $w.config.f.x0.x.menu add radiobutton -label "X.0" -variable tmpvar_6 -value "X.0" -command "update_menu2 .menu2.config.f" + $w.config.f.x0.x.menu add radiobutton -label "X.1" -variable tmpvar_6 -value "X.1" -command "update_menu2 .menu2.config.f" + bool $w.config.f 2 1 "Use new sigma0 RPC protocol" CONFIG_L4_NEWSIGMA0 + bool $w.config.f 2 2 "Enable IO-FlexPages" CONFIG_IO_FLEXPAGES + bool $w.config.f 2 3 "Use SYSENTER/SYSEXIT for IPC" CONFIG_L4_SYSENTEREXIT + + + + focus $w + update_menu2 $w.config.f + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + update idletasks + $w.config.canvas create window 0 0 -anchor nw -window $w.config.f + + $w.config.canvas configure \ + -width [expr [winfo reqwidth $w.config.f] + 1]\ + -scrollregion "-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \ + [expr [winfo reqheight $w.config.f] + 1]" + + set winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]] + set scry [expr [winfo screenh $w] / 2] + set maxy [expr [winfo screenh $w] * 3 / 4] + set canvtotal [expr [winfo reqh $w.config.f] + 2] + if [expr $winy + $canvtotal < $maxy] { + $w.config.canvas configure -height $canvtotal + } else { + $w.config.canvas configure -height [expr $scry - $winy] + } + update idletasks + wm maxsize $w [winfo width $w] [winfo screenheight $w] + wm minsize $w [winfo width $w] 100 + + wm deiconify $w +} + + +proc update_menu2 {w} { + update_define + global CONFIG_L4_NEWSIGMA0; vfix CONFIG_L4_NEWSIGMA0 + global tmpvar_0; vfix tmpvar_0 + global CONFIG_IO_FLEXPAGES; vfix CONFIG_IO_FLEXPAGES + if {($CONFIG_L4_NEWSIGMA0 == 1 && $tmpvar_0 == "x86")} then { .menu2.config.f.x2.y configure -state normal;.menu2.config.f.x2.n configure -state normal;.menu2.config.f.x2.l configure -state normal;set CONFIG_IO_FLEXPAGES [expr $CONFIG_IO_FLEXPAGES&15];} else { .menu2.config.f.x2.y configure -state disabled;.menu2.config.f.x2.n configure -state disabled;.menu2.config.f.x2.l configure -state disabled;set CONFIG_IO_FLEXPAGES [expr $CONFIG_IO_FLEXPAGES|16];} + + update_mainmenu $w +} + + +menu_option menu3 3 "Base Applications" +proc menu3 {w title} { + catch {destroy $w} + toplevel $w -class Dialog + wm withdraw $w + message $w.m -width 400 -aspect 300 -text \ + "Base Applications" -relief raised + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Base Applications" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Main Menu" \ + -width 15 -command "destroy $w; focus $oldFocus; update_mainmenu $w" + button $w.f.next -text "Next" \ + -width 15 -command " destroy $w; focus $oldFocus; menu4 .menu4 \"$title\"" + $w.f.next configure -state disabled + button $w.f.prev -text "Prev" \ + -width 15 -command " destroy $w; focus $oldFocus; menu2 .menu2 \"$title\"" + pack $w.f.back $w.f.next $w.f.prev -side left -expand on + pack $w.f -pady 10 -side bottom -anchor w -fill x + frame $w.topline -relief ridge -borderwidth 2 -height 2 + pack $w.topline -side top -fill x + + frame $w.botline -relief ridge -borderwidth 2 -height 2 + pack $w.botline -side bottom -fill x + + frame $w.config + pack $w.config -fill y -expand on + + scrollbar $w.config.vscroll -command "$w.config.canvas yview" + pack $w.config.vscroll -side right -fill y + + canvas $w.config.canvas -height 1\ + -relief flat -borderwidth 0 -yscrollcommand "$w.config.vscroll set" \ + -width [expr [winfo screenwidth .] * 1 / 2] + frame $w.config.f + pack $w.config.canvas -side right -fill y + + + bool $w.config.f 3 0 "Build sigma0" CONFIG_BUILD_SIGMA0 + hex $w.config.f 3 1 "DNARD sigma0 base" LBS0_ARM_DNARD + hex $w.config.f 3 2 "Brutus sigma0 base" LBS0_ARM_BRUTUS + hex $w.config.f 3 3 "PLEB sigma0 base" LBS0_ARM_PLEB + hex $w.config.f 3 4 "IPaq sigma0 base" LBS0_ARM_IPAQ + hex $w.config.f 3 5 "EP7211 sigma0 base" LBS0_ARM_EP7211 + hex $w.config.f 3 6 "X86 sigma0 base" LBS0_X86 + bool $w.config.f 3 7 "Build root task" CONFIG_BUILD_ROOTTASK + hex $w.config.f 3 8 "DNARD root task base" LBRT_ARM_DNARD + hex $w.config.f 3 9 "Brutus root task base" LBRT_ARM_BRUTUS + hex $w.config.f 3 10 "PLEB root task base" LBRT_ARM_PLEB + hex $w.config.f 3 11 "IPaq root task base" LBRT_ARM_IPAQ + hex $w.config.f 3 12 "EP7211 root task base" LBRT_ARM_EP7211 + hex $w.config.f 3 13 "X86 root task base" LBRT_X86 + bool $w.config.f 3 14 "Build resource manager" CONFIG_BUILD_RMGR + global tmpvar_7 + minimenu $w.config.f 3 15 "Putc output device" tmpvar_7 CONFIG_LIBIO_OUTSCRN + menu $w.config.f.x15.x.menu + $w.config.f.x15.x.menu add radiobutton -label "screen" -variable tmpvar_7 -value "screen" -command "update_menu3 .menu3.config.f" + $w.config.f.x15.x.menu add radiobutton -label "serial" -variable tmpvar_7 -value "serial" -command "update_menu3 .menu3.config.f" + hex $w.config.f 3 16 "Serial port address" CONFIG_LIBIO_COMPORT + int $w.config.f 3 17 "Serial port speed" CONFIG_LIBIO_COMSPEED + + + + focus $w + update_menu3 $w.config.f + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + update idletasks + $w.config.canvas create window 0 0 -anchor nw -window $w.config.f + + $w.config.canvas configure \ + -width [expr [winfo reqwidth $w.config.f] + 1]\ + -scrollregion "-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \ + [expr [winfo reqheight $w.config.f] + 1]" + + set winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]] + set scry [expr [winfo screenh $w] / 2] + set maxy [expr [winfo screenh $w] * 3 / 4] + set canvtotal [expr [winfo reqh $w.config.f] + 2] + if [expr $winy + $canvtotal < $maxy] { + $w.config.canvas configure -height $canvtotal + } else { + $w.config.canvas configure -height [expr $scry - $winy] + } + update idletasks + wm maxsize $w [winfo width $w] [winfo screenheight $w] + wm minsize $w [winfo width $w] 100 + + wm deiconify $w +} + + +proc update_menu3 {w} { + update_define + global CONFIG_BUILD_SIGMA0; vfix CONFIG_BUILD_SIGMA0 + global tmpvar_0; vfix tmpvar_0 + global tmpvar_1; vfix tmpvar_1 + global LBS0_ARM_DNARD; vfix LBS0_ARM_DNARD + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "DNARD")} then { .menu3.config.f.x1.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x1.l configure -state normal; } else { .menu3.config.f.x1.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x1.l configure -state disabled;} + global LBS0_ARM_BRUTUS; vfix LBS0_ARM_BRUTUS + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "Brutus")} then { .menu3.config.f.x2.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x2.l configure -state normal; } else { .menu3.config.f.x2.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x2.l configure -state disabled;} + global LBS0_ARM_PLEB; vfix LBS0_ARM_PLEB + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "PLEB")} then { .menu3.config.f.x3.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x3.l configure -state normal; } else { .menu3.config.f.x3.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x3.l configure -state disabled;} + global LBS0_ARM_IPAQ; vfix LBS0_ARM_IPAQ + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "IPaq")} then { .menu3.config.f.x4.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x4.l configure -state normal; } else { .menu3.config.f.x4.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x4.l configure -state disabled;} + global LBS0_ARM_EP7211; vfix LBS0_ARM_EP7211 + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "EP7211")} then { .menu3.config.f.x5.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x5.l configure -state normal; } else { .menu3.config.f.x5.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x5.l configure -state disabled;} + global LBS0_X86; vfix LBS0_X86 + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "x86")} then { .menu3.config.f.x6.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x6.l configure -state normal; } else { .menu3.config.f.x6.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x6.l configure -state disabled;} + global CONFIG_BUILD_ROOTTASK; vfix CONFIG_BUILD_ROOTTASK + global LBRT_ARM_DNARD; vfix LBRT_ARM_DNARD + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "DNARD")} then { .menu3.config.f.x8.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x8.l configure -state normal; } else { .menu3.config.f.x8.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x8.l configure -state disabled;} + global LBRT_ARM_BRUTUS; vfix LBRT_ARM_BRUTUS + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "Brutus")} then { .menu3.config.f.x9.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x9.l configure -state normal; } else { .menu3.config.f.x9.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x9.l configure -state disabled;} + global LBRT_ARM_PLEB; vfix LBRT_ARM_PLEB + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "PLEB")} then { .menu3.config.f.x10.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x10.l configure -state normal; } else { .menu3.config.f.x10.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x10.l configure -state disabled;} + global LBRT_ARM_IPAQ; vfix LBRT_ARM_IPAQ + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "IPaq")} then { .menu3.config.f.x11.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x11.l configure -state normal; } else { .menu3.config.f.x11.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x11.l configure -state disabled;} + global LBRT_ARM_EP7211; vfix LBRT_ARM_EP7211 + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "EP7211")} then { .menu3.config.f.x12.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x12.l configure -state normal; } else { .menu3.config.f.x12.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x12.l configure -state disabled;} + global LBRT_X86; vfix LBRT_X86 + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "x86")} then { .menu3.config.f.x13.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x13.l configure -state normal; } else { .menu3.config.f.x13.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x13.l configure -state disabled;} + global CONFIG_BUILD_RMGR; vfix CONFIG_BUILD_RMGR + if {($tmpvar_0 == "x86")} then { .menu3.config.f.x14.y configure -state normal;.menu3.config.f.x14.n configure -state normal;.menu3.config.f.x14.l configure -state normal;set CONFIG_BUILD_RMGR [expr $CONFIG_BUILD_RMGR&15];} else { .menu3.config.f.x14.y configure -state disabled;.menu3.config.f.x14.n configure -state disabled;.menu3.config.f.x14.l configure -state disabled;set CONFIG_BUILD_RMGR [expr $CONFIG_BUILD_RMGR|16];} + global CONFIG_LIBIO_OUTSCRN; vfix CONFIG_LIBIO_OUTSCRN + if {($tmpvar_0 == "x86")} then { .menu3.config.f.x15.x configure -state normal} else { .menu3.config.f.x15.x configure -state disabled} + global CONFIG_LIBIO_OUTCOM; vfix CONFIG_LIBIO_OUTCOM + if {($tmpvar_0 == "x86")} then { .menu3.config.f.x15.x configure -state normal} else { .menu3.config.f.x15.x configure -state disabled} + global tmpvar_7; vfix tmpvar_7 + global CONFIG_LIBIO_COMPORT; vfix CONFIG_LIBIO_COMPORT + if {($tmpvar_0 == "x86") && ($tmpvar_7 == "serial")} then { .menu3.config.f.x16.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x16.l configure -state normal; } else { .menu3.config.f.x16.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x16.l configure -state disabled;} + global CONFIG_LIBIO_COMSPEED; vfix CONFIG_LIBIO_COMSPEED + if {($tmpvar_0 == "x86") && ($tmpvar_7 == "serial")} then { .menu3.config.f.x17.x configure -state normal -foreground [ cget .ref -foreground ]; .menu3.config.f.x17.l configure -state normal; } else { .menu3.config.f.x17.x configure -state disabled -foreground [ cget .ref -disabledforeground ];.menu3.config.f.x17.l configure -state disabled;} + + update_mainmenu $w +} + + +proc update_mainmenu {w} { +} + + +set tmpvar_0 "(not set)" +set CONFIG_ARCH_ARM 0 +set CONFIG_ARCH_X86 0 +set CONFIG_ARCH_MIPS 0 +set CONFIG_ARCH_SH 0 +set CONFIG_ARCH_M68K 0 +set tmpvar_1 "(not set)" +set CONFIG_ARCH_ARM_DNARD 0 +set CONFIG_ARCH_ARM_BRUTUS 0 +set CONFIG_ARCH_ARM_PLEB 0 +set CONFIG_ARCH_ARM_IPAQ 0 +set CONFIG_ARCH_ARM_EP7211 0 +set tmpvar_2 "(not set)" +set CONFIG_ARCH_X86_I586 0 +set tmpvar_3 "(not set)" +set CONFIG_ARCH_MIPS_R4000 0 +set tmpvar_4 "(not set)" +set CONFIG_ARCH_SH_EMU 0 +set CONFIG_ARCH_SH_SH3 0 +set CONFIG_ARCH_SH_SH4 0 +set tmpvar_5 "(not set)" +set CONFIG_ARCH_M68K_DRAGONBALL 0 +set tmpvar_6 "(not set)" +set CONFIG_VERSION_X0 0 +set CONFIG_VERSION_X1 0 +set CONFIG_L4_NEWSIGMA0 0 +set CONFIG_IO_FLEXPAGES 0 +set CONFIG_L4_SYSENTEREXIT 0 +set CONFIG_BUILD_SIGMA0 0 +set LBS0_ARM_DNARD 0C000000 +set LBS0_ARM_BRUTUS D0000000 +set LBS0_ARM_PLEB C8020000 +set LBS0_ARM_IPAQ D0000000 +set LBS0_ARM_EP7211 C0400000 +set LBS0_X86 00020000 +set CONFIG_BUILD_ROOTTASK 0 +set LBRT_ARM_DNARD 0C100000 +set LBRT_ARM_BRUTUS D0100000 +set LBRT_ARM_PLEB C8040000 +set LBRT_ARM_IPAQ D0100000 +set LBRT_ARM_EP7211 C0500000 +set LBRT_X86 00300000 +set CONFIG_BUILD_RMGR 0 +set tmpvar_7 "(not set)" +set CONFIG_LIBIO_OUTSCRN 0 +set CONFIG_LIBIO_OUTCOM 0 +set CONFIG_LIBIO_COMPORT 3F8 +set CONFIG_LIBIO_COMSPEED 115200 +proc writeconfig {file1 file2} { + set cfg [open $file1 w] + set autocfg [open $file2 w] + set notmod 1 + set notset 0 + puts $cfg "#" + puts $cfg "# Automatically generated make config: don't edit" + puts $cfg "#" + puts $autocfg "/*" + puts $autocfg " * Automatically generated C config: don't edit" + puts $autocfg " */" + puts $autocfg "#define AUTOCONF_INCLUDED" + write_comment $cfg $autocfg "Architecture" + global _CONFIG_ARCH + if {("1" != "0")} then { set _CONFIG_ARCH 1 } + global tmpvar_0 + global _CONFIG_ARCH + if { $tmpvar_0 == "arm"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM 1 $_CONFIG_ARCH } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM 0 $_CONFIG_ARCH } + global _CONFIG_ARCH + if { $tmpvar_0 == "x86"} then { write_tristate $cfg $autocfg CONFIG_ARCH_X86 1 $_CONFIG_ARCH } else { write_tristate $cfg $autocfg CONFIG_ARCH_X86 0 $_CONFIG_ARCH } + global _CONFIG_ARCH + if { $tmpvar_0 == "mips"} then { write_tristate $cfg $autocfg CONFIG_ARCH_MIPS 1 $_CONFIG_ARCH } else { write_tristate $cfg $autocfg CONFIG_ARCH_MIPS 0 $_CONFIG_ARCH } + global _CONFIG_ARCH + if { $tmpvar_0 == "superh"} then { write_tristate $cfg $autocfg CONFIG_ARCH_SH 1 $_CONFIG_ARCH } else { write_tristate $cfg $autocfg CONFIG_ARCH_SH 0 $_CONFIG_ARCH } + global _CONFIG_ARCH + if { $tmpvar_0 == "m68k"} then { write_tristate $cfg $autocfg CONFIG_ARCH_M68K 1 $_CONFIG_ARCH } else { write_tristate $cfg $autocfg CONFIG_ARCH_M68K 0 $_CONFIG_ARCH } + global tmpvar_1 + global CONFIG_ARCH_ARM + if { $tmpvar_1 == "DNARD"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_DNARD 1 $CONFIG_ARCH_ARM } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_DNARD 0 $CONFIG_ARCH_ARM } + global CONFIG_ARCH_ARM + if { $tmpvar_1 == "Brutus"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_BRUTUS 1 $CONFIG_ARCH_ARM } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_BRUTUS 0 $CONFIG_ARCH_ARM } + global CONFIG_ARCH_ARM + if { $tmpvar_1 == "PLEB"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_PLEB 1 $CONFIG_ARCH_ARM } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_PLEB 0 $CONFIG_ARCH_ARM } + global CONFIG_ARCH_ARM + if { $tmpvar_1 == "IPaq"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_IPAQ 1 $CONFIG_ARCH_ARM } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_IPAQ 0 $CONFIG_ARCH_ARM } + global CONFIG_ARCH_ARM + if { $tmpvar_1 == "EP7211"} then { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_EP7211 1 $CONFIG_ARCH_ARM } else { write_tristate $cfg $autocfg CONFIG_ARCH_ARM_EP7211 0 $CONFIG_ARCH_ARM } + global tmpvar_2 + global CONFIG_ARCH_X86 + if { $tmpvar_2 == "i586"} then { write_tristate $cfg $autocfg CONFIG_ARCH_X86_I586 1 $CONFIG_ARCH_X86 } else { write_tristate $cfg $autocfg CONFIG_ARCH_X86_I586 0 $CONFIG_ARCH_X86 } + global tmpvar_3 + global CONFIG_ARCH_MIPS + if { $tmpvar_3 == "R4000"} then { write_tristate $cfg $autocfg CONFIG_ARCH_MIPS_R4000 1 $CONFIG_ARCH_MIPS } else { write_tristate $cfg $autocfg CONFIG_ARCH_MIPS_R4000 0 $CONFIG_ARCH_MIPS } + global tmpvar_4 + global CONFIG_ARCH_SH + if { $tmpvar_4 == "Emulator"} then { write_tristate $cfg $autocfg CONFIG_ARCH_SH_EMU 1 $CONFIG_ARCH_SH } else { write_tristate $cfg $autocfg CONFIG_ARCH_SH_EMU 0 $CONFIG_ARCH_SH } + global CONFIG_ARCH_SH + if { $tmpvar_4 == "SH3"} then { write_tristate $cfg $autocfg CONFIG_ARCH_SH_SH3 1 $CONFIG_ARCH_SH } else { write_tristate $cfg $autocfg CONFIG_ARCH_SH_SH3 0 $CONFIG_ARCH_SH } + global CONFIG_ARCH_SH + if { $tmpvar_4 == "SH4"} then { write_tristate $cfg $autocfg CONFIG_ARCH_SH_SH4 1 $CONFIG_ARCH_SH } else { write_tristate $cfg $autocfg CONFIG_ARCH_SH_SH4 0 $CONFIG_ARCH_SH } + global tmpvar_5 + global CONFIG_ARCH_M68K + if { $tmpvar_5 == "Dragonball"} then { write_tristate $cfg $autocfg CONFIG_ARCH_M68K_DRAGONBALL 1 $CONFIG_ARCH_M68K } else { write_tristate $cfg $autocfg CONFIG_ARCH_M68K_DRAGONBALL 0 $CONFIG_ARCH_M68K } + write_comment $cfg $autocfg "Kernel Configuration" + global tmpvar_6 + if { $tmpvar_6 == "X.0" } then { write_tristate $cfg $autocfg CONFIG_VERSION_X0 1 $notmod } else { write_tristate $cfg $autocfg CONFIG_VERSION_X0 0 $notmod } + if { $tmpvar_6 == "X.1" } then { write_tristate $cfg $autocfg CONFIG_VERSION_X1 1 $notmod } else { write_tristate $cfg $autocfg CONFIG_VERSION_X1 0 $notmod } + global CONFIG_L4_NEWSIGMA0 + write_tristate $cfg $autocfg CONFIG_L4_NEWSIGMA0 $CONFIG_L4_NEWSIGMA0 $notmod + global CONFIG_IO_FLEXPAGES + if {($CONFIG_L4_NEWSIGMA0 == 1 && $tmpvar_0 == "x86")} then { write_tristate $cfg $autocfg CONFIG_IO_FLEXPAGES $CONFIG_IO_FLEXPAGES $notmod } + global CONFIG_L4_SYSENTEREXIT + write_tristate $cfg $autocfg CONFIG_L4_SYSENTEREXIT $CONFIG_L4_SYSENTEREXIT $notmod + write_comment $cfg $autocfg "Base Applications" + global CONFIG_BUILD_SIGMA0 + write_tristate $cfg $autocfg CONFIG_BUILD_SIGMA0 $CONFIG_BUILD_SIGMA0 $notmod + global LBS0_ARM_DNARD + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "DNARD")} then { write_hex $cfg $autocfg LBS0_ARM_DNARD $LBS0_ARM_DNARD $notmod } + global LBS0_ARM_BRUTUS + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "Brutus")} then { write_hex $cfg $autocfg LBS0_ARM_BRUTUS $LBS0_ARM_BRUTUS $notmod } + global LBS0_ARM_PLEB + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "PLEB")} then { write_hex $cfg $autocfg LBS0_ARM_PLEB $LBS0_ARM_PLEB $notmod } + global LBS0_ARM_IPAQ + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "IPaq")} then { write_hex $cfg $autocfg LBS0_ARM_IPAQ $LBS0_ARM_IPAQ $notmod } + global LBS0_ARM_EP7211 + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "EP7211")} then { write_hex $cfg $autocfg LBS0_ARM_EP7211 $LBS0_ARM_EP7211 $notmod } + global LBS0_X86 + if {($CONFIG_BUILD_SIGMA0 == 1) && ($tmpvar_0 == "x86")} then { write_hex $cfg $autocfg LBS0_X86 $LBS0_X86 $notmod } + global CONFIG_BUILD_ROOTTASK + write_tristate $cfg $autocfg CONFIG_BUILD_ROOTTASK $CONFIG_BUILD_ROOTTASK $notmod + global LBRT_ARM_DNARD + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "DNARD")} then { write_hex $cfg $autocfg LBRT_ARM_DNARD $LBRT_ARM_DNARD $notmod } + global LBRT_ARM_BRUTUS + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "Brutus")} then { write_hex $cfg $autocfg LBRT_ARM_BRUTUS $LBRT_ARM_BRUTUS $notmod } + global LBRT_ARM_PLEB + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "PLEB")} then { write_hex $cfg $autocfg LBRT_ARM_PLEB $LBRT_ARM_PLEB $notmod } + global LBRT_ARM_IPAQ + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "IPaq")} then { write_hex $cfg $autocfg LBRT_ARM_IPAQ $LBRT_ARM_IPAQ $notmod } + global LBRT_ARM_EP7211 + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "arm") && ($tmpvar_1 == "EP7211")} then { write_hex $cfg $autocfg LBRT_ARM_EP7211 $LBRT_ARM_EP7211 $notmod } + global LBRT_X86 + if {($CONFIG_BUILD_ROOTTASK == 1) && ($tmpvar_0 == "x86")} then { write_hex $cfg $autocfg LBRT_X86 $LBRT_X86 $notmod } + global CONFIG_BUILD_RMGR + if {($tmpvar_0 == "x86")} then { write_tristate $cfg $autocfg CONFIG_BUILD_RMGR $CONFIG_BUILD_RMGR $notmod } + global tmpvar_7 + if { $tmpvar_7 == "screen" } then { write_tristate $cfg $autocfg CONFIG_LIBIO_OUTSCRN 1 $notmod } else { write_tristate $cfg $autocfg CONFIG_LIBIO_OUTSCRN 0 $notmod } + if { $tmpvar_7 == "serial" } then { write_tristate $cfg $autocfg CONFIG_LIBIO_OUTCOM 1 $notmod } else { write_tristate $cfg $autocfg CONFIG_LIBIO_OUTCOM 0 $notmod } + global CONFIG_LIBIO_COMPORT + if {($tmpvar_0 == "x86") && ($tmpvar_7 == "serial")} then { write_hex $cfg $autocfg CONFIG_LIBIO_COMPORT $CONFIG_LIBIO_COMPORT $notmod } + global CONFIG_LIBIO_COMSPEED + if {($tmpvar_0 == "x86") && ($tmpvar_7 == "serial")} then { write_int $cfg $autocfg CONFIG_LIBIO_COMSPEED $CONFIG_LIBIO_COMSPEED $notmod } + close $cfg + close $autocfg +} + + +proc clear_choices { } { + global CONFIG_ARCH_ARM; set CONFIG_ARCH_ARM 0 + global CONFIG_ARCH_X86; set CONFIG_ARCH_X86 0 + global CONFIG_ARCH_MIPS; set CONFIG_ARCH_MIPS 0 + global CONFIG_ARCH_SH; set CONFIG_ARCH_SH 0 + global CONFIG_ARCH_M68K; set CONFIG_ARCH_M68K 0 + global CONFIG_ARCH_ARM_DNARD; set CONFIG_ARCH_ARM_DNARD 0 + global CONFIG_ARCH_ARM_BRUTUS; set CONFIG_ARCH_ARM_BRUTUS 0 + global CONFIG_ARCH_ARM_PLEB; set CONFIG_ARCH_ARM_PLEB 0 + global CONFIG_ARCH_ARM_IPAQ; set CONFIG_ARCH_ARM_IPAQ 0 + global CONFIG_ARCH_ARM_EP7211; set CONFIG_ARCH_ARM_EP7211 0 + global CONFIG_ARCH_X86_I586; set CONFIG_ARCH_X86_I586 0 + global CONFIG_ARCH_MIPS_R4000; set CONFIG_ARCH_MIPS_R4000 0 + global CONFIG_ARCH_SH_EMU; set CONFIG_ARCH_SH_EMU 0 + global CONFIG_ARCH_SH_SH3; set CONFIG_ARCH_SH_SH3 0 + global CONFIG_ARCH_SH_SH4; set CONFIG_ARCH_SH_SH4 0 + global CONFIG_ARCH_M68K_DRAGONBALL; set CONFIG_ARCH_M68K_DRAGONBALL 0 + global CONFIG_VERSION_X0; set CONFIG_VERSION_X0 0 + global CONFIG_VERSION_X1; set CONFIG_VERSION_X1 0 + global CONFIG_LIBIO_OUTSCRN; set CONFIG_LIBIO_OUTSCRN 0 + global CONFIG_LIBIO_OUTCOM; set CONFIG_LIBIO_OUTCOM 0 +} + + +proc update_choices { } { + global tmpvar_0 + global CONFIG_ARCH_ARM + if { $CONFIG_ARCH_ARM == 1 } then { set tmpvar_0 "arm" } + global CONFIG_ARCH_X86 + if { $CONFIG_ARCH_X86 == 1 } then { set tmpvar_0 "x86" } + global CONFIG_ARCH_MIPS + if { $CONFIG_ARCH_MIPS == 1 } then { set tmpvar_0 "mips" } + global CONFIG_ARCH_SH + if { $CONFIG_ARCH_SH == 1 } then { set tmpvar_0 "superh" } + global CONFIG_ARCH_M68K + if { $CONFIG_ARCH_M68K == 1 } then { set tmpvar_0 "m68k" } + global tmpvar_1 + global CONFIG_ARCH_ARM_DNARD + if { $CONFIG_ARCH_ARM_DNARD == 1 } then { set tmpvar_1 "DNARD" } + global CONFIG_ARCH_ARM_BRUTUS + if { $CONFIG_ARCH_ARM_BRUTUS == 1 } then { set tmpvar_1 "Brutus" } + global CONFIG_ARCH_ARM_PLEB + if { $CONFIG_ARCH_ARM_PLEB == 1 } then { set tmpvar_1 "PLEB" } + global CONFIG_ARCH_ARM_IPAQ + if { $CONFIG_ARCH_ARM_IPAQ == 1 } then { set tmpvar_1 "IPaq" } + global CONFIG_ARCH_ARM_EP7211 + if { $CONFIG_ARCH_ARM_EP7211 == 1 } then { set tmpvar_1 "EP7211" } + global tmpvar_2 + global CONFIG_ARCH_X86_I586 + if { $CONFIG_ARCH_X86_I586 == 1 } then { set tmpvar_2 "i586" } + global tmpvar_3 + global CONFIG_ARCH_MIPS_R4000 + if { $CONFIG_ARCH_MIPS_R4000 == 1 } then { set tmpvar_3 "R4000" } + global tmpvar_4 + global CONFIG_ARCH_SH_EMU + if { $CONFIG_ARCH_SH_EMU == 1 } then { set tmpvar_4 "Emulator" } + global CONFIG_ARCH_SH_SH3 + if { $CONFIG_ARCH_SH_SH3 == 1 } then { set tmpvar_4 "SH3" } + global CONFIG_ARCH_SH_SH4 + if { $CONFIG_ARCH_SH_SH4 == 1 } then { set tmpvar_4 "SH4" } + global tmpvar_5 + global CONFIG_ARCH_M68K_DRAGONBALL + if { $CONFIG_ARCH_M68K_DRAGONBALL == 1 } then { set tmpvar_5 "Dragonball" } + global tmpvar_6 + global CONFIG_VERSION_X0 + if { $CONFIG_VERSION_X0 == 1 } then { set tmpvar_6 "X.0" } + global CONFIG_VERSION_X1 + if { $CONFIG_VERSION_X1 == 1 } then { set tmpvar_6 "X.1" } + global tmpvar_7 + global CONFIG_LIBIO_OUTSCRN + if { $CONFIG_LIBIO_OUTSCRN == 1 } then { set tmpvar_7 "screen" } + global CONFIG_LIBIO_OUTCOM + if { $CONFIG_LIBIO_OUTCOM == 1 } then { set tmpvar_7 "serial" } +} + + +proc update_define { } { + global _CONFIG_ARCH + if {("1" != "0")} then { set _CONFIG_ARCH 1 } +} + + +set defaults "defconfig" +# FILE: tail.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1998, Michael Elizabeth Chastain, +# Arrange buttons in three columns for better screen fitting. +# + +# +# Read the user's settings from .config. These will override whatever is +# in config.in. Don't do this if the user specified a -D to force +# the defaults. +# +if { [file readable .config] == 1} then { + if { $argc > 0 } then { + if { [lindex $argv 0] != "-D" } then { + read_config .config + } + else + { + read_config $defaults + } + } else { + read_config .config + } +} else { + read_config $defaults +} + +update_mainmenu .f0 + +button .f0.control.save -anchor w -text "Save and Exit" \ + -command { writeconfig .config ../include/config.h; read_config .config; \ + writeconfig .config ../include/config.h; exit; wrapup .wrap } + +button .f0.control.quit -anchor w -text "Quit Without Saving" \ + -command { maybe_exit .maybe } + +button .f0.control.load -anchor w -text "Load Configuration from File" \ + -command { load_configfile .load "Load Configuration from file" read_config_file +} + +button .f0.control.store -anchor w -text "Store Configuration to File" \ + -command { load_configfile .load "Store Configuration to file" write_config_file } + +# +# Now pack everything. +# + +pack .f0.control.store .f0.control.load .f0.control.quit .f0.control.save \ + -padx 0 -pady 0 -side bottom -fill x +pack .f0.arch .f0.apps .f0.control -side left -padx 5 -pady 0 -fill y +pack .f0 -padx 5 -pady 5 + +# +# If we cannot write our config files, disable the write button. +# +if { [file exists .config] == 1 } then { + if { [file writable .config] == 0 } then { + .f0.control.save configure -state disabled + } + } else { + if { [file writable .] == 0 } then { + .f0.control.save configure -state disabled + } + } + diff --git a/apps/xconfig/defconfig b/apps/xconfig/defconfig new file mode 100644 index 0000000..33a06e5 --- /dev/null +++ b/apps/xconfig/defconfig @@ -0,0 +1,14 @@ +# +CONFIG_ARCH_X86=y +# +CONFIG_ARCH_X86_I586=y +CONFIG_ARCH_ARM_DNARD=y +CONFIG_ARCH_MIPS_R4000=y +CONFIG_ARCH_SH_EMU=y +CONFIG_ARCH_M68K_DRAGONBALL=y +# +CONFIG_VERSION_X0=y + +CONFIG_BUILD_SIGMA0=y +# +CONFIG_LIBIO_OUTSCRN=y diff --git a/apps/xconfig/header.tk b/apps/xconfig/header.tk new file mode 100644 index 0000000..7921002 --- /dev/null +++ b/apps/xconfig/header.tk @@ -0,0 +1,485 @@ +# FILE: header.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1999, Michael Elizabeth Chastain, +# - Remove unused do_cmd function (part of the 2.0 sound support). +# - Arrange buttons in three columns for better screen fitting. +# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like: +# dep_tristate 'foo' CONFIG_FOO m +# +# 23 January 1999, Michael Elizabeth Chastain, +# - Shut vfix the hell up. +# +# 24 January 1999, Michael Elizabeth Chastain, +# - Improve the exit message (Jeff Ronne). + +# +# This is a handy replacement for ".widget cget" that requires neither tk4 +# nor additional source code uglification. +# +proc cget { w option } { + return "[lindex [$w configure $option] 4]" +} + +# +# Function to compensate for broken config.in scripts like the sound driver, +# which make dependencies on variables that are never even conditionally +# defined. +# +proc vfix { var } { + global $var + if [ catch {eval concat $$var} ] { + set $var 0 + } +} + +# +# Constant values used by certain dep_tristate commands. +# +set CONSTANT_Y 1 +set CONSTANT_M 2 +set CONSTANT_N 0 + +# +# Create a "reference" object to steal colors from. +# +button .ref + +# +# On monochrome displays, -disabledforeground is blank by default; that's +# bad. Fill it with -foreground instead. +# +if { [cget .ref -disabledforeground] == "" } { + .ref configure -disabledforeground [cget .ref -foreground] +} + + +# +# Define some macros we will need to parse the config.in file. +# + +proc mainmenu_name { text } { + wm title . "$text" +} + +proc menu_option { w menu_num text } { + global menus_per_column +# if { $menu_num <= $menus_per_column } then { +# set myframe left +# } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { +# set myframe middle +# } else { +# set myframe right +# } + if { $menu_num <= 6 } then { + set myframe arch + } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { + set myframe apps + } else { + set myframe control + } + button .f0.x$menu_num -anchor w -text "$text" \ + -command "$w .$w \"$text\"" + pack .f0.x$menu_num -pady 0 -side top -fill x -in .f0.$myframe +} + +proc load_configfile { w title func } { + catch {destroy $w} + toplevel $w -class Dialog + global loadfile + frame $w.x + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + label $w.x.l -text "Enter filename:" -relief raised + entry $w.x.x -width 35 -relief sunken -borderwidth 2 \ + -textvariable loadfile + pack $w.x.l $w.x.x -anchor w -side left + pack $w.x -side top -pady 10 + wm title $w "$title" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "destroy $w; focus $oldFocus;$func .fileio" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc maybe_exit { w } { + catch {destroy $w} + toplevel $w -class Dialog + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + message $w.m -width 400 -aspect 300 \ + -text "Changes will be lost. Are you sure?" -relief flat + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Are you sure?" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "exit" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc read_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 && [file readable $loadfile] == 1 } then { + read_config $loadfile + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to read file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Bummer" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc write_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 + && ([file writable $loadfile] == 1 || ([file exists $loadfile] == 0 && [file writable [file dirname $loadfile]] == 1)) } then { + writeconfig $loadfile /dev/null + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to write file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc read_config { filename } { + set file1 [open $filename r] + clear_choices + while { [gets $file1 line] >= 0} { + if [regexp {([0-9A-Za-z_]+)=([ynm])} $line foo var value] { + if { $value == "y" } then { set cmd "global $var; set $var 1" } + if { $value == "n" } then { set cmd "global $var; set $var 0" } + if { $value == "m" } then { set cmd "global $var; set $var 2" } + eval $cmd + } + if [regexp {# ([0-9A-Za-z_]+) is not set} $line foo var] { + set cmd "global $var; set $var 0" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)=([0-9A-Fa-f]+)} $line foo var value] { + set cmd "global $var; set $var $value" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { + set cmd "global $var; set $var \"$value\"" + eval $cmd + } + } + close $file1 + update_choices + update_mainmenu .rdupd +} +proc write_comment { file1 file2 text } { + puts $file1 "" + puts $file1 "#" + puts $file1 "# $text" + puts $file1 "#" + puts $file2 "/*" + puts $file2 " * $text" + puts $file2 " */" +} + +proc write_tristate { file1 file2 varname variable dep } { + if { $variable == 0 } \ + then { puts $file1 "$varname=n"; } \ + elseif { $variable == 1 && $dep == 0 } \ + then { puts $file1 "$varname=y"; } \ + elseif { $variable == 1 && $dep == 1 } \ + then { puts $file1 "$varname=y"; \ + puts $file2 "#define $varname 1" } \ + else { \ + puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ + } +} + +#proc write_tristate { file1 file2 varname variable dep } { +# if { $variable == 0 } \ +# then { puts $file1 "# $varname is not set"; \ +# puts $file2 "#undef $varname"} \ +# elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \ +# then { puts $file1 "$varname=m"; \ +# puts $file2 "#undef $varname"; \ +# puts $file2 "#define ${varname}_MODULE 1" } \ +# elseif { $variable == 1 && $dep != 2 } \ +# then { puts $file1 "$varname=y"; \ +# puts $file2 "#define $varname 1" } \ +# else { \ +# puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ +# } +#} + +proc write_int { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname $variable"; \ + } +} + +proc write_hex { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname 0x$variable"; \ + } +} + +proc write_string { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=\"$variable\""; \ + puts $file2 "#define $varname \"$variable\""; \ + } +} + +proc option_name {w mnum line text helpidx} { + button $w.x$line.l -text "$text" -relief groove -anchor w + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] + button $w.x$line.help -text "Help" -relief raised \ + -command "dohelp .dohelp $helpidx" + pack $w.x$line.help -side right -fill y + pack $w.x$line.l -side right -fill both -expand on +} + +proc toggle_switch2 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc toggle_switch3 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + global CONFIG_MODULES + if {($CONFIG_MODULES == 0)} then { + $w.x$line.m configure -state disabled + } + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc bool {w mnum line text variable} { + toggle_switch2 $w $mnum $line $text $variable + $w.x$line.m configure -state disabled + pack $w.x$line -anchor w -fill both -expand on +} + +proc tristate {w mnum line text variable } { + toggle_switch3 $w $mnum $line $text $variable + pack $w.x$line -anchor w -fill both -expand on +} + +proc dep_tristate {w mnum line text variable depend } { + tristate $w $mnum $line $text $variable +} + +proc int { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc hex { w mnum line text variable } { + int $w $mnum $line $text $variable +} + +proc istring { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc minimenu { w mnum line text variable helpidx } { + frame $w.x$line + menubutton $w.x$line.x -textvariable $variable -menu \ + $w.x$line.x.menu -relief raised \ + -anchor w + option_name $w $mnum $line $text $helpidx + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc comment {w line text } { +#nothing done for comments now. +} + +proc dohelp {w var } { + catch {destroy $w} + toplevel $w -class Dialog + + set filefound 0 + set found 0 + set lineno 0 + + if { [file readable config.help] == 1} then { + set filefound 1 + # First escape sed regexp special characters in var: + set var [exec echo "$var" | sed s/\[\]\[\/.^$*\]/\\\\&/g] + # Now pick out right help text: + set message [exec sed -n " + /^$var\[ \]*\$/,\${ + /^$var\[ \]*\$/c\\ +${var}:\\ + + /^#/b + /^\[^ \]/q + s/^ // + p + } + " config.help] + set found [expr [string length "$message"] > 0] + } + + frame $w.f1 + + if { $found == 0 } then { + if { $filefound == 0 } then { + message $w.f1.m -width 750 -aspect 300 -relief flat -text \ + "No help available - unable to open file config.help. This file should have come with your kernel." + } else { + message $w.f1.m -width 400 -aspect 300 -relief flat -text \ + "No help available for $var" + } + label $w.f1.bm -bitmap error + wm title $w "RTFM" + } else { + text $w.f1.m -width 73 -relief flat -wrap word + $w.f1.m insert 0.0 $message + $w.f1.m conf -state disabled -height [$w.f1.m index end] + + label $w.f1.bm -bitmap info + wm title $w "Configuration help" + } + pack $w.f1.bm $w.f1.m -side left -padx 10 + pack $w.f1 -side top + set oldFocus [focus] + + # Do the OK button + # + frame $w.f2 + button $w.f2.ok -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f2.ok -side bottom -pady 6 -anchor n + pack $w.f2 -side bottom -padx 10 -anchor s + + # Finish off the window + # + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc wrapup {w } { + catch {destroy $w} + toplevel $w -class Dialog + + message $w.m -width 400 -aspect 300 -relief raised -justify center -text \ + "Check the top-level Makefile for additional configuration." + + label $w.bm -bitmap info + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "End of L4/KA kernel configuration." + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "exit" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + +} + +# +# Next set up the particulars for the top level menu, and define a few +# buttons which we will stick down at the bottom. +# + +frame .f0 +frame .f0.arch +frame .f0.apps +frame .f0.control + diff --git a/apps/xconfig/kernel.in b/apps/xconfig/kernel.in new file mode 100644 index 0000000..3572e1e --- /dev/null +++ b/apps/xconfig/kernel.in @@ -0,0 +1,13 @@ +mainmenu_option next_comment +comment 'Kernel Configuration' + +choice 'Kernel Interface Specification' \ + 'X.0 CONFIG_VERSION_X0 \ + X.1 CONFIG_VERSION_X1' X.0 + +bool 'Use new sigma0 RPC protocol' CONFIG_L4_NEWSIGMA0 +if [ "$CONFIG_L4_NEWSIGMA0" = "y" -a "$CONFIG_ARCH_X86" = "y" ]; then + bool 'Enable IO-FlexPages' CONFIG_IO_FLEXPAGES n +fi +bool 'Use SYSENTER/SYSEXIT for IPC' CONFIG_L4_SYSENTEREXIT +endmenu diff --git a/apps/xconfig/rewrite.awk b/apps/xconfig/rewrite.awk new file mode 100644 index 0000000..0533353 --- /dev/null +++ b/apps/xconfig/rewrite.awk @@ -0,0 +1,39 @@ +/^CONFIG_ARCH_[^_]*=y/ { + ARCH=$3; +} + +/^CONFIG_ARCH_[^_]*_[^_]*=y/ { + if ($3 == ARCH) { + PLAT=$4; + printf(",s/^PLATFORM=.*/PLATFORM=%s/\n", tolower(PLAT)) + } +} + +/^LBS0_[^_]*=/ { + if ($2 == ARCH) { + printf(",s/^SIGMA0_LINKBASE=.*/SIGMA0_LINKBASE=%s/\n", $3) + } +} + +/^LBS0_[^_]*_[^_]*=/ { + if ($2 == ARCH && $3 == PLAT) { + printf(",s/^SIGMA0_LINKBASE=.*/SIGMA0_LINKBASE=%s/\n", $4) + } +} + +/^LBRT_[^_]*=/ { + if ($2 == ARCH) { + printf(",s/^ROOTTASK_LINKBASE=.*/ROOTTASK_LINKBASE=%s/\n", $3) + } +} + +/^LBRT_[^_]*_[^_]*=/ { + if ($2 == ARCH && $3 == PLAT) { + printf(",s/^ROOTTASK_LINKBASE=.*/ROOTTASK_LINKBASE=%s/\n", $4) + } +} + +END { + printf "wq\n" +} + diff --git a/apps/xconfig/tail.tk b/apps/xconfig/tail.tk new file mode 100644 index 0000000..90f6554 --- /dev/null +++ b/apps/xconfig/tail.tk @@ -0,0 +1,69 @@ +# FILE: tail.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1998, Michael Elizabeth Chastain, +# Arrange buttons in three columns for better screen fitting. +# + +# +# Read the user's settings from .config. These will override whatever is +# in config.in. Don't do this if the user specified a -D to force +# the defaults. +# +if { [file readable .config] == 1} then { + if { $argc > 0 } then { + if { [lindex $argv 0] != "-D" } then { + read_config .config + } + else + { + read_config $defaults + } + } else { + read_config .config + } +} else { + read_config $defaults +} + +update_mainmenu .f0 + +button .f0.control.save -anchor w -text "Save and Exit" \ + -command { writeconfig .config ../include/config.h; read_config .config; \ + writeconfig .config ../include/config.h; exit; wrapup .wrap } + +button .f0.control.quit -anchor w -text "Quit Without Saving" \ + -command { maybe_exit .maybe } + +button .f0.control.load -anchor w -text "Load Configuration from File" \ + -command { load_configfile .load "Load Configuration from file" read_config_file +} + +button .f0.control.store -anchor w -text "Store Configuration to File" \ + -command { load_configfile .load "Store Configuration to file" write_config_file } + +# +# Now pack everything. +# + +pack .f0.control.store .f0.control.load .f0.control.quit .f0.control.save \ + -padx 0 -pady 0 -side bottom -fill x +pack .f0.arch .f0.apps .f0.control -side left -padx 5 -pady 0 -fill y +pack .f0 -padx 5 -pady 5 + +# +# If we cannot write our config files, disable the write button. +# +if { [file exists .config] == 1 } then { + if { [file writable .config] == 0 } then { + .f0.control.save configure -state disabled + } + } else { + if { [file writable .] == 0 } then { + .f0.control.save configure -state disabled + } + } + diff --git a/apps/xconfig/tkcond.c b/apps/xconfig/tkcond.c new file mode 100644 index 0000000..89069da --- /dev/null +++ b/apps/xconfig/tkcond.c @@ -0,0 +1,360 @@ +/* + * tkcond.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * This file takes the tokenized statement list and transforms 'if ...' + * statements. For each simple statement, I find all of the 'if' statements + * that enclose it, and attach the aggregate conditionals of those 'if' + * statements to the cond list of the simple statement. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact if + * you are interested in working on the replacement. + */ + +#include +#include +#include + +#include "tkparse.h" + + + +/* + * Transform op_variable to op_kvariable. + * + * This works, but it's gross, speed-wise. It would benefit greatly + * from a simple hash table that maps names to cfg. + * + * Note well: this is actually better than the loop structure xconfig + * has been staggering along with for three years, which performs + * this whole procedure inside *another* loop on active conditionals. + */ +void transform_to_kvariable( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + struct condition * cond; + + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + if ( cond->op == op_variable ) + { + /* Here's where it gets DISGUSTING. */ + struct kconfig * cfg1; + + for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next ) + { + if ( cfg1->token == token_bool + || cfg1->token == token_choice_item + || cfg1->token == token_dep_tristate + || cfg1->token == token_hex + || cfg1->token == token_int + || cfg1->token == token_string + || cfg1->token == token_tristate ) + { + if ( strcmp( cond->str, cfg1->optionname ) == 0 ) + { + cond->op = op_kvariable; + cond->str = NULL; + cond->cfg = cfg1; + break; + } + } + } + } + +#if 0 + /* + * Maybe someday this will be useful, but right now it + * gives a lot of false positives on files like + * drivers/video/Config.in that are meant for more + * than one architecture. Turn it on if you want to play + * with it though; it does work. -- mec + */ + if ( cond->op == op_variable ) + { + if ( strcmp( cond->str, "ARCH" ) != 0 + && strcmp( cond->str, "CONSTANT_Y" ) != 0 + && strcmp( cond->str, "CONSTANT_M" ) != 0 + && strcmp( cond->str, "CONSTANT_N" ) != 0 ) + { + fprintf( stderr, "warning: $%s used but not defined\n", + cond->str ); + } + } +#endif + } + } +} + + + +/* + * Make a new condition chain by joining the current condition stack with + * the "&&" operator for glue. + */ +struct condition * join_condition_stack( struct condition * conditions [], + int depth ) +{ + struct condition * cond_list; + struct condition * cond_last; + int i; + + cond_list = cond_last = NULL; + for ( i = 0; i < depth; i++ ) + { + struct condition * cond; + struct condition * cnew; + + /* add a '(' */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_lparen; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } + + /* duplicate the chain */ + for ( cond = conditions [i]; cond != NULL; cond = cond->next ) + { + cnew = malloc( sizeof(*cnew) ); + cnew->next = NULL; + cnew->op = cond->op; + cnew->str = cond->str ? strdup( cond->str ) : NULL; + cnew->cfg = cond->cfg; + cond_last->next = cnew; + cond_last = cnew; + } + + /* add a ')' */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_rparen; + cond_last->next = cnew; + cond_last = cnew; + + /* if i have another condition, add an '&&' operator */ + if ( i < depth - 1 ) + { + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_and; + cond_last->next = cnew; + cond_last = cnew; + } + } + + /* + * Remove duplicate conditions. + */ + { + struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f; + + for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next ) + { + if ( cond1->op == op_lparen ) + { + cond1b = cond1 ->next; if ( cond1b == NULL ) break; + cond1c = cond1b->next; if ( cond1c == NULL ) break; + cond1d = cond1c->next; if ( cond1d == NULL ) break; + cond1e = cond1d->next; if ( cond1e == NULL ) break; + cond1f = cond1e->next; if ( cond1f == NULL ) break; + + if ( cond1b->op == op_kvariable + && ( cond1c->op == op_eq || cond1c->op == op_neq ) + && cond1d->op == op_constant + && cond1e->op == op_rparen ) + { + struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f; + + for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next ) + { + if ( cond2->op == op_lparen ) + { + cond2b = cond2 ->next; if ( cond2b == NULL ) break; + cond2c = cond2b->next; if ( cond2c == NULL ) break; + cond2d = cond2c->next; if ( cond2d == NULL ) break; + cond2e = cond2d->next; if ( cond2e == NULL ) break; + cond2f = cond2e->next; + + /* look for match */ + if ( cond2b->op == op_kvariable + && cond2b->cfg == cond1b->cfg + && cond2c->op == cond1c->op + && cond2d->op == op_constant + && strcmp( cond2d->str, cond1d->str ) == 0 + && cond2e->op == op_rparen ) + { + /* one of these must be followed by && */ + if ( cond1f->op == op_and + || ( cond2f != NULL && cond2f->op == op_and ) ) + { + /* nuke the first duplicate */ + cond1 ->op = op_nuked; + cond1b->op = op_nuked; + cond1c->op = op_nuked; + cond1d->op = op_nuked; + cond1e->op = op_nuked; + if ( cond1f->op == op_and ) + cond1f->op = op_nuked; + else + cond2f->op = op_nuked; + } + } + } + } + } + } + } + } + + return cond_list; +} + + + +/* + * This is the main transformation function. + */ +void fix_conditionals( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + /* + * Transform op_variable to op_kvariable. + */ + transform_to_kvariable( scfg ); + + /* + * Transform conditions that use variables from "choice" statements. + * Choice values appear to the user as a collection of booleans, and the + * script can test the individual booleans. But internally, all I have is + * the N-way value of an unnamed temporary for the whole statement. So I + * have to tranform '"$CONFIG_M386" != "y"' + * into '"$tmpvar_N" != "CONFIG_M386"'. + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + struct condition * cond; + + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + if ( cond->op == op_kvariable && cond->cfg->token == token_choice_item ) + { + /* + * Look two more tokens down for the comparison token. + * It has to be "y" for this trick to work. + * + * If you get this error, don't even think about relaxing the + * strcmp test. You will produce incorrect TK code. Instead, + * look for the place in your Config.in script where you are + * comparing a 'choice' variable to a value other than 'y', + * and rewrite the comparison to be '= "y"' or '!= "y"'. + */ + struct condition * cond2 = cond->next->next; + const char * label; + + if ( strcmp( cond2->str, "y" ) != 0 ) + { + fprintf( stderr, "tkparse choked in fix_choice_cond\n" ); + exit( 1 ); + } + + label = cond->cfg->label; + cond->cfg = cond->cfg->cfg_parent; + cond2->str = strdup( label ); + } + } + } + + /* + * Walk the statement list, maintaining a stack of current conditions. + * token_if push its condition onto the stack. + * token_else invert the condition on the top of the stack. + * token_endif pop the stack. + * + * For a simple statement, create a condition chain by joining together + * all of the conditions on the stack. + */ + { + struct condition * cond_stack [32]; + int depth = 0; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_if: + cond_stack [depth++] = cfg->cond; + cfg->cond = NULL; + break; + + case token_else: + { + /* + * Invert the condition chain. + * + * Be careful to transfrom op_or to op_and1, not op_and. + * I will need this later in the code that removes + * duplicate conditions. + */ + struct condition * cond; + + for ( cond = cond_stack [depth-1]; + cond != NULL; + cond = cond->next ) + { + switch( cond->op ) + { + default: break; + case op_and: cond->op = op_or; break; + case op_or: cond->op = op_and1; break; + case op_neq: cond->op = op_eq; break; + case op_eq: cond->op = op_neq; break; + } + } + } + break; + + case token_fi: + --depth; + break; + + case token_bool: + case token_choice_item: + case token_comment: + case token_define_bool: + case token_hex: + case token_int: + case token_mainmenu_option: + case token_string: + case token_tristate: + cfg->cond = join_condition_stack( cond_stack, depth ); + break; + + case token_dep_tristate: + /* + * Same as the other simple statements, plus an additional + * condition for the dependency. + */ + cond_stack [depth] = cfg->cond; + cfg->cond = join_condition_stack( cond_stack, depth+1 ); + break; + } + } + } +} diff --git a/apps/xconfig/tkcond.o b/apps/xconfig/tkcond.o new file mode 100644 index 0000000..2b2a65f Binary files /dev/null and b/apps/xconfig/tkcond.o differ diff --git a/apps/xconfig/tkgen.c b/apps/xconfig/tkgen.c new file mode 100644 index 0000000..d31ca16 --- /dev/null +++ b/apps/xconfig/tkgen.c @@ -0,0 +1,1067 @@ +/* Generate tk script based upon config.in + * + * Version 1.0 + * Eric Youngdale + * 10/95 + * + * 1996 01 04 + * Avery Pennarun - Aesthetic improvements. + * + * 1996 01 24 + * Avery Pennarun - Bugfixes and more aesthetics. + * + * 1996 03 08 + * Avery Pennarun - The int and hex config.in commands work right. + * - Choice buttons are more user-friendly. + * - Disabling a text entry line greys it out properly. + * - dep_tristate now works like in Configure. (not pretty) + * - No warnings in gcc -Wall. (Fixed some "interesting" bugs.) + * - Faster/prettier "Help" lookups. + * + * 1996 03 15 + * Avery Pennarun - Added new sed script from Axel Boldt to make help even + * faster. (Actually awk is downright slow on some machines.) + * - Fixed a bug I introduced into Choice dependencies. Thanks + * to Robert Krawitz for pointing this out. + * + * 1996 03 16 + * Avery Pennarun - basic "do_make" support added to let sound config work. + * + * 1996 03 25 + * Axel Boldt - Help now works on "choice" buttons. + * + * 1996 04 06 + * Avery Pennarun - Improved sound config stuff. (I think it actually works + * now!) + * - Window-resize-limits don't use ugly /usr/lib/tk4.0 hack. + * - int/hex work with tk3 again. (The "cget" error.) + * - Next/Prev buttons switch between menus. I can't take + * much credit for this; the code was already there, but + * ifdef'd out for some reason. It flickers a lot, but + * I suspect there's no "easy" fix for that. + * - Labels no longer highlight as you move the mouse over + * them (although you can still press them... oh well.) + * - Got rid of the last of the literal color settings, to + * help out people with mono X-Windows systems. + * (Apparently there still are some out there!) + * - Tabstops seem sensible now. + * + * 1996 04 14 + * Avery Pennarun - Reduced flicker when creating windows, even with "update + * idletasks" hack. + * + * 1997 12 08 + * Michael Chastain - Remove sound driver special cases. + * + * 1997 11 15 + * Michael Chastain - For choice buttons, write values for all options, + * not just the single chosen one. This is compatible + * with 'make config' and 'make oldconfig', and is + * needed so smart-config dependencies work if the + * user switches from one configuration method to + * another. + * + * 1998 03 09 + * Axel Boldt - Smaller layout of main menu - it's still too big for 800x600. + * - Display help in text window to allow for cut and paste. + * - Allow for empty lines in help texts. + * - update_define should not set all variables unconditionally to + * 0: they may have been set to 1 elsewhere. CONFIG_NETLINK is + * an example. + * + * 1999 01 04 + * Michael Elizabeth Chastain + * - Call clear_globalflags when writing out update_mainmenu. + * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4. + * + * 8 January 1999, Michael Elizabeth Chastain + * - Emit menus_per_column + * + * 14 January 1999, Michael Elizabeth Chastain + * - Steam-clean this file. I tested this by generating kconfig.tk for every + * architecture and comparing it character-for-character against the output + * of the old tkparse. + * - Fix flattening of nested menus. The old code simply assigned items to + * the most recent token_mainmenu_option, without paying attention to scope. + * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu". + * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c + * and bool-d in *menu-2*. This hosed the nested submenus in + * drives/net/Config.in and other places. + * - Fix menu line wraparound at 128 menus (some fool used a 'char' for + * a counter). + * + * 23 January 1999, Michael Elizabeth Chastain + * - Remove bug-compatible code. + */ + +#include +#include +#include "tkparse.h" + + + +/* + * Total number of menus. + */ +static int tot_menu_num = 0; + + + +/* + * Generate portion of wish script for the beginning of a submenu. + * The guts get filled in with the various options. + */ +static void start_proc( char * label, int menu_num, int flag ) +{ + if ( flag ) + printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label ); + printf( "proc menu%d {w title} {\n", menu_num ); + printf( "\tcatch {destroy $w}\n" ); + printf( "\ttoplevel $w -class Dialog\n" ); + printf( "\twm withdraw $w\n" ); + printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" ); + printf( "\t\t\"%s\" -relief raised\n", label ); + printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); + printf( "\twm title $w \"%s\" \n\n", label ); + + /* + * Attach the "Prev", "Next" and "OK" buttons at the end of the window. + */ + printf( "\tset oldFocus [focus]\n" ); + printf( "\tframe $w.f\n" ); + printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); + printf( "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n" ); + printf( "\tbutton $w.f.next -text \"Next\" \\\n" ); + printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 ); + if ( menu_num == tot_menu_num ) + printf( "\t$w.f.next configure -state disabled\n" ); + printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" ); + printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1 ); + if ( menu_num == 1 ) + printf( "\t$w.f.prev configure -state disabled\n" ); + printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); + printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" ); + + /* + * Lines between canvas and other areas of the window. + */ + printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.topline -side top -fill x\n\n" ); + printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.botline -side bottom -fill x\n\n" ); + + /* + * The "config" frame contains the canvas and a scrollbar. + */ + printf( "\tframe $w.config\n" ); + printf( "\tpack $w.config -fill y -expand on\n\n" ); + printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" ); + printf( "\tpack $w.config.vscroll -side right -fill y\n\n" ); + + /* + * The scrollable canvas itself, where the real work (and mess) gets done. + */ + printf( "\tcanvas $w.config.canvas -height 1\\\n" ); + printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" ); + printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" ); + printf( "\tframe $w.config.f\n" ); + printf( "\tpack $w.config.canvas -side right -fill y\n" ); + printf("\n\n"); +} + + + +/* + * Each proc we create needs a global declaration for any global variables we + * use. To minimize the size of the file, we set a flag each time we output + * a global declaration so we know whether we need to insert one for a + * given function or not. + */ +void clear_globalflags( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + cfg->global_written = 0; +} + + + +/* + * Output a "global" line for a given variable. Also include the + * call to "vfix". (If vfix is not needed, then it's fine to just printf + * a "global" line). + */ +void global( const char *var ) +{ + printf( "\tglobal %s; vfix %s\n", var, var ); +} + + + +/* + * This function walks the chain of conditions that we got from cond.c + * and creates a TCL conditional to enable/disable a given widget. + */ +void generate_if( struct kconfig * cfg, struct condition * ocond, + int menu_num, int line_num ) +{ + struct condition * cond; + + /* + * First write any global declarations we need for this conditional. + */ + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_variable: + global( cond->str ); + break; + + case op_kvariable: + if ( ! cond->cfg->global_written ) + { + cond->cfg->global_written = 1; + global( cond->cfg->optionname ); + } + break; + } + } + + /* + * Now write this option. + */ + if ( ! cfg->global_written && cfg->optionname != NULL ) + { + cfg->global_written = 1; + global( cfg->optionname ); + } + + /* + * Generate the body of the conditional. + */ + printf( "\tif {" ); + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", cond->str ); + break; + + case op_kvariable: + printf( "$%s", cond->cfg->optionname ); + break; + + case op_constant: + if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then { " ); + + /* + * Generate a procedure call to write the value. + * This code depends on procedures in header.tk. + */ + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; + + case token_bool: + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state normal;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal;", + menu_num, line_num ); + printf( "set %s [expr $%s&15];", + cfg->optionname, cfg->optionname ); + printf( "} else { "); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;", + menu_num, line_num ); + printf( "set %s [expr $%s|16];}\n", + cfg->optionname, cfg->optionname ); + break; + + case token_choice_header: + fprintf( stderr, "Internal error on token_choice_header\n" ); + exit( 1 ); + + case token_choice_item: + printf(".menu%d.config.f.x%d.x configure -state normal} else { .menu%d.config.f.x%d.x configure -state disabled}\n", + menu_num, cfg->cfg_parent->menu_line, + menu_num, cfg->cfg_parent->menu_line ); + break; + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_define_bool: + printf( "set %s %s } \n", + cfg->optionname, cfg->value ); + break; + + case token_dep_tristate: + case token_tristate: + if ( cfg->token == token_dep_tristate ) + { + global( cfg->depend ); + printf( "if { $%s != 1 && $%s != 0 } then {", + cfg->depend, cfg->depend ); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( "} else {" ); + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num); + printf( "}; " ); + } + else + { + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num ); + } + + printf( ".menu%d.config.f.x%d.n configure -state normal;", + menu_num, line_num ); + printf( "global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal;", + menu_num, line_num ); + + /* + * Or in a bit to the variable - this causes all of the radiobuttons + * to be deselected (i.e. not be red). + */ + printf( "set %s [expr $%s&15];", + cfg->optionname, cfg->optionname ); + printf( "} else { " ); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.m configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;", + menu_num, line_num ); + + /* + * Clear the disable bit to enable the correct radiobutton. + */ + printf( "set %s [expr $%s|16];}\n", + cfg->optionname, cfg->optionname ); + break; + + case token_hex: + case token_int: + case token_string: + printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", + menu_num, line_num); + printf( ".menu%d.config.f.x%d.l configure -state normal; ", + menu_num, line_num); + printf( "} else { " ); + printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ];", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;}\n", + menu_num, line_num ); + break; + + case token_mainmenu_option: + printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", + menu_num, menu_num ); + break; + } +} + + + +/* + * Generate a line that writes a variable to the output file. + */ +void generate_writeconfig( struct kconfig * cfg ) +{ + struct condition * cond; + + /* + * Generate global declaration for this symbol. + */ + if ( cfg->token != token_comment ) + { + if ( ! cfg->global_written ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + } + } + + /* + * Generate global declarations for the condition chain. + */ + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch( cond->op ) + { + default: + break; + + case op_variable: + global( cond->str ); + break; + + case op_kvariable: + if ( ! cond->cfg->global_written ) + { + cond->cfg->global_written = 1; + global( cond->cfg->optionname ); + } + break; + } + } + + /* + * Generate indentation. + */ + if ( cfg->token != token_choice_header ) + printf( "\t" ); + + /* + * Generate the conditional. + */ + if ( cfg->cond != NULL ) + { + printf( "if {" ); + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: break; + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", cond->str ); + break; + + case op_kvariable: + printf( "$%s", cond->cfg->optionname ); + break; + + case op_constant: + if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then {" ); + } + + /* + * Generate a procedure call to write the value. + * This code depends on the write_* procedures in header.tk. + */ + switch ( cfg->token ) + { + default: + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_bool: + case token_tristate: + if ( cfg->cond ) + printf( " " ); + printf( "write_tristate $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_choice_header: + /* + * This is funky code -- it fails if there were any conditionals. + * Fortunately all the conditionals got stripped off somewhere + * else. + */ + { + struct kconfig * cfg1; + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + if (cfg->depend) + printf("\tglobal %s\n\tif { $%s == \"%s\"} then { write_tristate $cfg $autocfg %s 1 $%s } else { write_tristate $cfg $autocfg %s 0 $%s }\n", + cfg->depend, cfg->optionname, cfg1->label, + cfg1->optionname, cfg->depend, + cfg1->optionname, cfg->depend ); + else + printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n", + cfg->optionname, cfg1->label, + cfg1->optionname, + cfg1->optionname ); + + } + } + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_comment: + printf( "write_comment $cfg $autocfg \"%s\"", + cfg->label ); + if ( cfg->cond != NULL ) + printf( "}" ); + printf( "\n" ); + break; + + case token_define_bool: + if (cfg->optionname[0] != '_') + { + if ( cfg->cond == NULL ) + { + printf( "write_tristate $cfg $autocfg %s $%s $notmod\n", + cfg->optionname, cfg->optionname ); + } + else + { + printf( "write_tristate $cfg $autocfg %s %s $notmod }\n", + cfg->optionname, cfg->value ); + } + } + else + printf( " set %s %s }\n", cfg->optionname, cfg->value); + break; + + case token_dep_tristate: + if ( cfg->cond ) + printf( " " ); + printf( "write_tristate $cfg $autocfg %s $%s $%s", + cfg->optionname, cfg->optionname, cfg->depend ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( " \n" ); + break; + + case token_hex: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_hex $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_int: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_int $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_string: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_string $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + } +} + + + +/* + * Generates the end of a menu procedure. + */ +static void end_proc( struct kconfig * scfg, int menu_num ) +{ + struct kconfig * cfg; + + printf( "\n\n\n" ); + printf( "\tfocus $w\n" ); + printf( "\tupdate_menu%d $w.config.f\n", + menu_num ); + printf( "\tglobal winx; global winy\n" ); + printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); + printf( "\twm geometry $w +$winx+$winy\n" ); + + /* + * Now that the whole window is in place, we need to wait for an "update" + * so we can tell the canvas what its virtual size should be. + * + * Unfortunately, this causes some ugly screen-flashing because the whole + * window is drawn, and then it is immediately resized. It seems + * unavoidable, though, since "frame" objects won't tell us their size + * until after an update, and "canvas" objects can't automatically pack + * around frames. Sigh. + */ + printf( "\tupdate idletasks\n" ); + printf( "\t$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" ); + printf( "\t$w.config.canvas configure \\\n" ); + printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" ); + printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" ); + printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" ); + + /* + * If the whole canvas will fit in 3/4 of the screen height, do it; + * otherwise, resize to around 1/2 the screen and let us scroll. + */ + printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" ); + printf( "\tset scry [expr [winfo screenh $w] / 2]\n" ); + printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" ); + printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" ); + printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" ); + printf( "\t\t$w.config.canvas configure -height $canvtotal\n" ); + printf( "\t} else {\n" ); + printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" ); + printf( "\t}\n" ); + + /* + * Limit the min/max window size. Height can vary, but not width, + * because of the limitations of canvas and our laziness. + */ + printf( "\tupdate idletasks\n" ); + printf( "\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" ); + printf( "\twm minsize $w [winfo width $w] 100\n\n" ); + printf( "\twm deiconify $w\n" ); + printf( "}\n\n\n" ); + + /* + * Now we generate the companion procedure for the menu we just + * generated. This procedure contains all of the code to + * disable/enable widgets based upon the settings of the other + * widgets, and will be called first when the window is mapped, + * and each time one of the buttons in the window are clicked. + */ + printf( "proc update_menu%d {w} {\n", menu_num ); + printf( "\tupdate_define\n" ); + + /* + * Clear all of the booleans that are defined in this menu. + */ + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num && cfg->token == token_define_bool + && cfg->optionname != NULL ) + { + if ( ! cfg->global_written ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tset %s 0\n", cfg->optionname ); + } + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num + && cfg->token != token_mainmenu_option +/* && cfg->token != token_choice_item*/) + { + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + else + { + /* + * Treat tristate like conditional here. + */ + if ( cfg->token == token_dep_tristate ) + { + global( cfg->depend ); + printf( "\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n", + cfg->depend, cfg->depend, + menu_num, cfg->menu_line, + menu_num, cfg->menu_line ); + } + } + } + } + + printf("\n\tupdate_mainmenu $w\n"); + printf("}\n\n\n"); +} + + + +/* + * This is the top level function for generating the tk script. + */ +void dump_tk_script( struct kconfig * scfg ) +{ + int menu_depth; + int menu_num [64]; + struct kconfig * menu_first [256]; + struct kconfig * menu_last [256]; + int imenu; + struct kconfig * cfg; + struct kconfig * cfg1 = NULL; + const char * name = "No Name"; + + /* + * Thread the menu pointers so I can walk each menu separately. + */ + tot_menu_num = 0; + menu_depth = 0; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_mainmenu_name: + name = cfg->label; + break; + + case token_mainmenu_option: + if ( ++menu_depth >= 64 ) + { fprintf( stderr, "menus too deep\n" ); exit( 1 ); } + if ( ++tot_menu_num >= 256 ) + { fprintf( stderr, "too many menus\n" ); exit( 1 ); } + menu_num [menu_depth] = tot_menu_num; + menu_first [tot_menu_num] = cfg; + menu_last [tot_menu_num] = cfg; + break; + + case token_endmenu: + /* flatten menus with proper scoping */ + if ( --menu_depth < 0 ) + { fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); } + break; + + case token_bool: + case token_choice_header: + case token_choice_item: + case token_dep_tristate: + case token_hex: + case token_int: + case token_string: + case token_tristate: + if ( menu_depth == 0 ) + { fprintf( stderr, "statement not in menu\n" ); exit( 1 ); } + menu_last [menu_num [menu_depth]]->menu_next = cfg; + menu_last [menu_num [menu_depth]] = cfg; + cfg->menu_next = NULL; + break; + + case token_define_bool: + break; + } + } + + /* + * Generate menus per column setting. + * There are: + * four extra buttons for save/quit/load/store; + * one blank button + * add two to round up for division + */ + printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 ); + + /* + * Generate the menus. + */ + printf( "mainmenu_name \"%s\"\n", name ); + for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) + { + int menu_line = 0; + + clear_globalflags( scfg ); + start_proc( menu_first[imenu]->label, imenu, 1 ); + + for ( cfg = menu_first[imenu]; cfg != NULL; cfg = cfg->menu_next ) + { + cfg->menu_number = imenu; + + switch ( cfg->token ) + { + default: + break; + + case token_bool: + cfg->menu_line = menu_line++; + printf( "\tbool $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_choice_header: + /* + * I need the first token_choice_item to pick out the right + * help text from Documentation/Configure.help. + */ + cfg->menu_line = menu_line++; + printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tminimenu $w.config.f %d %d \"%s\" %s %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname, cfg->next->optionname ); + printf( "\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line ); + cfg1 = cfg; + break; + + case token_choice_item: + /* note: no menu line; uses choice header menu line */ + printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n", + cfg1->menu_line, cfg->label, cfg1->optionname, + cfg->label, cfg1->menu_number, cfg1->menu_number ); + break; + + case token_dep_tristate: + cfg->menu_line = menu_line++; + printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname, cfg->depend ); + break; + + case token_hex: + cfg->menu_line = menu_line++; + printf( "\thex $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_int: + cfg->menu_line = menu_line++; + printf( "\tint $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_string: + cfg->menu_line = menu_line++; + printf( "\tistring $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_tristate: + cfg->menu_line = menu_line++; + printf( "\ttristate $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + } + } + + end_proc( scfg, imenu ); + } + + /* + * The top level menu also needs an update function. When we exit a + * submenu, we may need to disable one or more of the submenus on + * the top level menu, and this procedure will ensure that things are + * correct. + */ + clear_globalflags( scfg ); + printf( "proc update_mainmenu {w} {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_mainmenu_option && cfg->cond != NULL ) + generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + } + printf( "}\n\n\n" ); + +#if 0 + /* + * Generate code to set the variables that are "defined". + */ + for ( cfg = config; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_define_bool ) + { + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); + else + printf( "\twrite_define %s %s\n", cfg->optionname, cfg->value ); + } + } + #endif + + /* + * Generate code to load the default settings into the variables. + * The script in tail.tk will attempt to load .config, + * which may override these settings, but that's OK. + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_item: + case token_dep_tristate: + case token_tristate: + printf( "set %s 0\n", cfg->optionname ); + break; + + case token_choice_header: + printf( "set %s \"(not set)\"\n", cfg->optionname ); + break; + + case token_hex: + case token_int: + printf( "set %s %s\n", cfg->optionname, cfg->value ? cfg->value : "0"); + break; + + case token_string: + printf( "set %s \"%s\"\n", cfg->optionname, cfg->value ? cfg->value : ""); + break; + } + } + + /* + * Generate a function to write all of the variables to a file. + */ + printf( "proc writeconfig {file1 file2} {\n" ); + printf( "\tset cfg [open $file1 w]\n" ); + printf( "\tset autocfg [open $file2 w]\n" ); + printf( "\tset notmod 1\n" ); + printf( "\tset notset 0\n" ); + printf( "\tputs $cfg \"#\"\n"); + printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n"); + printf( "\tputs $cfg \"#\"\n" ); + + printf( "\tputs $autocfg \"/*\"\n" ); + printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" ); + printf( "\tputs $autocfg \" */\"\n" ); + printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" ); + + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_header: + case token_comment: + case token_define_bool: + case token_dep_tristate: + case token_hex: + case token_int: + case token_string: + case token_tristate: + generate_writeconfig( cfg ); + break; + } + } + printf( "\tclose $cfg\n" ); + printf( "\tclose $autocfg\n" ); + printf( "}\n\n\n" ); + + /* + * Generate a simple function that updates the master choice + * variable depending upon what values were loaded from a .config + * file. + */ + printf( "proc clear_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s; set %s 0\n", + cfg1->optionname, cfg1->optionname ); + } + } + } + printf( "}\n\n\n" ); + + printf( "proc update_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + printf( "\tglobal %s\n", cfg->optionname ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s\n", cfg1->optionname ); + printf( "\tif { $%s == 1 } then { set %s \"%s\" }\n", + cfg1->optionname, cfg->optionname, cfg1->label ); + } + } + } + printf( "}\n\n\n" ); + + printf( "proc update_define { } {\n" ); + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_define_bool ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if( cfg->token == token_define_bool ) + { + if ( cfg->cond == NULL ) + printf( "\tset %s %s\n", cfg->optionname, cfg->value ); + else + generate_if( cfg, cfg->cond, -1, 0 ); + } + } + printf( "}\n\n\n" ); + + /* + * That's it. We are done. The output of this file will have header.tk + * prepended and tail.tk appended to create an executable wish script. + */ +} diff --git a/apps/xconfig/tkgen.o b/apps/xconfig/tkgen.o new file mode 100644 index 0000000..798d0ad Binary files /dev/null and b/apps/xconfig/tkgen.o differ diff --git a/apps/xconfig/tkparse b/apps/xconfig/tkparse new file mode 100755 index 0000000..3cd8dd3 Binary files /dev/null and b/apps/xconfig/tkparse differ diff --git a/apps/xconfig/tkparse.c b/apps/xconfig/tkparse.c new file mode 100644 index 0000000..5a0ecf3 --- /dev/null +++ b/apps/xconfig/tkparse.c @@ -0,0 +1,619 @@ +/* + * tkparse.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * Parse a config.in file and translate it to a wish script. + * This task has three parts: + * + * tkparse.c tokenize the input + * tkcond.c transform 'if ...' statements + * tkgen.c generate output + * + * Change History + * + * 7 January 1999, Michael Elizabeth Chastain, + * - Teach dep_tristate about a few literals, such as: + * dep_tristate 'foo' CONFIG_FOO m + * Also have it print an error message and exit on some parse failures. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * 23 January 1999, Michael Elizabeth Chastain, + * - Remove bug-compatible code. + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact if + * you are interested in working on the replacement. + */ + +#include +#include +#include + +#include "tkparse.h" + +static struct kconfig * config_list = NULL; +static struct kconfig * config_last = NULL; +static const char * current_file = ""; +static int lineno = 0; + +static void do_source( const char * ); + +#undef strcmp +int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } +#define strcmp my_strcmp + + + +/* + * Report a syntax error. + */ +static void syntax_error( const char * msg ) +{ + fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); + exit( 1 ); +} + + + +/* + * Get a string. + */ +static const char * get_string( const char * pnt, char ** label ) +{ + const char * word; + + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' ) + break; + pnt++; + } + + *label = malloc( pnt - word + 1 ); + memcpy( *label, word, pnt - word ); + (*label)[pnt - word] = '\0'; + + if ( *pnt != '\0' ) + pnt++; + return pnt; +} + + + +/* + * Get a quoted string. + * Insert a '\' before any characters that need quoting. + */ +static const char * get_qstring( const char * pnt, char ** label ) +{ + char quote_char; + char newlabel [1024]; + char * pnt1; + + /* advance to the open quote */ + for ( ; ; ) + { + if ( *pnt == '\0' ) + return pnt; + quote_char = *pnt++; + if ( quote_char == '"' || quote_char == '\'' ) + break; + } + + /* copy into an intermediate buffer */ + pnt1 = newlabel; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated quoted string" ); + if ( *pnt == quote_char && pnt[-1] != '\\' ) + break; + + /* copy the character, quoting if needed */ + if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' ) + *pnt1++ = '\\'; + *pnt1++ = *pnt++; + } + + /* copy the label into a permanent location */ + *pnt1++ = '\0'; + *label = (char *) malloc( pnt1 - newlabel ); + memcpy( *label, newlabel, pnt1 - newlabel ); + + /* skip over last quote and next whitespace */ + pnt++; + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + return pnt; +} + + +/* + * Tokenize an 'if' statement condition. + */ +static struct condition * tokenize_if( const char * pnt ) +{ + struct condition * list; + struct condition * last; + + /* eat the open bracket */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt != '[' ) + syntax_error( "bad 'if' condition" ); + pnt++; + + list = last = NULL; + for ( ; ; ) + { + struct condition * cond; + + /* advance to the next token */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + syntax_error( "unterminated 'if' condition" ); + if ( *pnt == ']' ) + return list; + + /* allocate a new token */ + cond = malloc( sizeof(*cond) ); + memset( cond, 0, sizeof(*cond) ); + if ( last == NULL ) + { list = last = cond; } + else + { last->next = cond; last = cond; } + + /* determine the token value */ + if ( *pnt == '-' && pnt[1] == 'a' ) + { cond->op = op_and; pnt += 2; continue; } + + if ( *pnt == '-' && pnt[1] == 'o' ) + { cond->op = op_or; pnt += 2; continue; } + + if ( *pnt == '!' && pnt[1] == '=' ) + { cond->op = op_neq; pnt += 2; continue; } + + if ( *pnt == '=' ) + { cond->op = op_eq; pnt += 1; continue; } + + if ( *pnt == '!' ) + { cond->op = op_bang; pnt += 1; continue; } + + if ( *pnt == '"' ) + { + const char * word; + + /* advance to the word */ + pnt++; + if ( *pnt == '$' ) + { cond->op = op_variable; pnt++; } + else + { cond->op = op_constant; } + + /* find the end of the word */ + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated double quote" ); + if ( *pnt == '"' ) + break; + pnt++; + } + + /* store a copy of this word */ + { + char * str = malloc( pnt - word + 1 ); + memcpy( str, word, pnt - word ); + str [pnt - word] = '\0'; + cond->str = str; + } + + pnt++; + continue; + } + + /* unknown token */ + syntax_error( "bad if condition" ); + } +} + + + +/* + * Tokenize a choice list. Choices appear as pairs of strings; + * note that I am parsing *inside* the double quotes. Ugh. + */ +static const char * tokenize_choices( struct kconfig * cfg_choose, + const char * pnt ) +{ + for ( ; ; ) + { + struct kconfig * cfg; + + /* skip whitespace */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + return pnt; + + /* allocate a new kconfig line */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* fill out the line */ + cfg->token = token_choice_item; + cfg->cfg_parent = cfg_choose; + pnt = get_string( pnt, &cfg->label ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + pnt = get_string( pnt, &cfg->optionname ); + } + + return pnt; +} + + + + + +/* + * Tokenize one line. + */ +static void tokenize_line( const char * pnt ) +{ + static struct kconfig * last_menuoption = NULL; + enum e_token token; + struct kconfig * cfg; + + /* skip white space */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + /* + * categorize the next token + */ + +#define match_token(t, s) \ + if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; } + + token = token_UNKNOWN; + switch ( *pnt ) + { + default: + break; + + case '#': + case '\0': + return; + + case 'b': + match_token( token_bool, "bool" ); + break; + + case 'c': + match_token( token_choice_header, "choice" ); + match_token( token_comment, "comment" ); + break; + + case 'd': + match_token( token_define_bool, "define_bool" ); + match_token( token_dep_tristate, "dep_tristate" ); + break; + + case 'e': + match_token( token_else, "else" ); + match_token( token_endmenu, "endmenu" ); + break; + + case 'f': + match_token( token_fi, "fi" ); + break; + + case 'h': + match_token( token_hex, "hex" ); + break; + + case 'i': + match_token( token_if, "if" ); + match_token( token_int, "int" ); + break; + + case 'm': + match_token( token_mainmenu_name, "mainmenu_name" ); + match_token( token_mainmenu_option, "mainmenu_option" ); + break; + + case 's': + match_token( token_source, "source" ); + match_token( token_string, "string" ); + break; + + case 't': + match_token( token_then, "then" ); + match_token( token_tristate, "tristate" ); + break; + + case 'u': + match_token( token_unset, "unset" ); + break; + } + +#undef match_token + + if ( token == token_source ) + { + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + do_source( pnt ); + return; + } + + if ( token == token_then ) + { + if ( config_last != NULL && config_last->token == token_if ) + return; + syntax_error( "bogus 'then'" ); + } + + if ( token == token_unset ) + { + fprintf( stderr, "Ignoring 'unset' command\n" ); + return; + } + + if ( token == token_UNKNOWN ) + syntax_error( "unknown command" ); + + /* + * Allocate an item. + */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* + * Tokenize the arguments. + */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + cfg->token = token; + switch ( token ) + { + default: + syntax_error( "unknown token" ); + + case token_bool: + case token_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + break; + + case token_choice_header: + { + static int choose_number = 0; + char * choice_list; + + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_qstring ( pnt, &choice_list ); + pnt = get_string ( pnt, &cfg->value ); + if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->depend ); + } + + cfg->optionname = malloc( 32 ); + sprintf( cfg->optionname, "tmpvar_%d", choose_number++ ); + + tokenize_choices( cfg, choice_list ); + free( choice_list ); + } + break; + + case token_comment: + pnt = get_qstring(pnt, &cfg->label); + if ( last_menuoption != NULL ) + { + pnt = get_qstring(pnt, &cfg->label); + last_menuoption->label = cfg->label; + last_menuoption = NULL; + } + break; + + case token_define_bool: + pnt = get_string( pnt, &cfg->optionname ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0"; + else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1"; + else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2"; + else + { + syntax_error( "unknown define_bool value" ); + } + break; + + case token_dep_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + /* dep_tristate 'foo' CONFIG_FOO m */ + if ( pnt[0] == 'Y' || pnt[0] == 'y' ) + cfg->depend = strdup( "CONSTANT_Y" ); + else if ( pnt[0] == 'M' || pnt[0] == 'm' ) + cfg->depend = strdup( "CONSTANT_M" ); + else + cfg->depend = strdup( "CONSTANT_N" ); + pnt++; + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->depend ); + } + else + { + syntax_error( "can't handle dep_tristate condition" ); + } + + /* + * Create a conditional for this object's dependency. + */ + { + char fake_if [1024]; + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then", + cfg->depend, cfg->depend ); + cfg->cond = tokenize_if( fake_if ); + } + break; + + case token_else: + case token_endmenu: + case token_fi: + break; + + case token_hex: + case token_int: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_string ( pnt, &cfg->value ); + break; + + case token_string: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_qstring ( pnt, &cfg->value ); + break; + + case token_if: + cfg->cond = tokenize_if( pnt ); + break; + + case token_mainmenu_name: + pnt = get_qstring( pnt, &cfg->label ); + break; + + case token_mainmenu_option: + if ( strncmp( pnt, "next_comment", 12 ) == 0 ) + last_menuoption = cfg; + else + pnt = get_qstring( pnt, &cfg->label ); + break; + } + + return; +} + + + +/* + * Implement the "source" command. + */ +static void do_source( const char * filename ) +{ + char buffer [1024]; + FILE * infile; + const char * old_file; + int old_lineno; + int offset; + + /* open the file */ + if ( strcmp( filename, "-" ) == 0 ) + infile = stdin; + else + infile = fopen( filename, "r" ); + + /* if that failed, try ../filename */ + if ( infile == NULL ) + { + sprintf( buffer, "../%s", filename ); + infile = fopen( buffer, "r" ); + } + + if ( infile == NULL ) + { + sprintf( buffer, "unable to open %s", filename ); + syntax_error( buffer ); + } + + /* push the new file name and line number */ + old_file = current_file; + old_lineno = lineno; + current_file = filename; + lineno = 0; + + /* read and process lines */ + for ( offset = 0; ; ) + { + char * pnt; + + /* read a line */ + fgets( buffer + offset, sizeof(buffer) - offset, infile ); + if ( feof( infile ) ) + break; + lineno++; + + /* strip the trailing return character */ + pnt = buffer + strlen(buffer) - 1; + if ( *pnt == '\n' ) + *pnt-- = '\0'; + + /* eat \ NL pairs */ + if ( *pnt == '\\' ) + { + offset = pnt - buffer; + continue; + } + + /* tokenize this line */ + tokenize_line( buffer ); + offset = 0; + } + + /* that's all, folks */ + if ( infile != stdin ) + fclose( infile ); + current_file = old_file; + lineno = old_lineno; + return; +} + + + +/* + * Main program. + */ +int main( int argc, const char * argv [] ) +{ + do_source ( "-" ); + fix_conditionals ( config_list ); + dump_tk_script ( config_list ); + return 0; +} diff --git a/apps/xconfig/tkparse.h b/apps/xconfig/tkparse.h new file mode 100644 index 0000000..0478eff --- /dev/null +++ b/apps/xconfig/tkparse.h @@ -0,0 +1,104 @@ +/* + * tkparse.h + */ + +/* + * Token types (mostly statement types). + */ + +enum e_token +{ + token_UNKNOWN, + token_bool, + token_choice_header, + token_choice_item, + token_comment, + token_define_bool, + token_dep_tristate, + token_else, + token_endmenu, + token_fi, + token_hex, + token_if, + token_int, + token_mainmenu_name, + token_mainmenu_option, + token_source, + token_string, + token_then, + token_tristate, + token_unset, +}; + +/* + * Operator types for conditionals. + */ + +enum operator +{ + op_eq, + op_neq, + op_and, + op_and1, + op_or, + op_bang, + op_lparen, + op_rparen, + op_constant, + op_variable, + op_kvariable, + op_nuked +}; + +/* + * Conditions come in linked lists. + * Some operators take strings: + * + * op_constant "foo" + * op_variable "$ARCH", "$CONFIG_PMAC" + * op_kvariable "$CONFIG_EXPERIMENTAL" + * + * Most "$..." constructs refer to a variable which is defined somewhere + * in the script, so they become op_kvariable's instead. Note that it + * is legal to test variables which are never defined, such as variables + * that are meaningful only on other architectures. + */ + +struct condition +{ + struct condition * next; + enum operator op; + const char * str; /* op_constant, op_variable */ + struct kconfig * cfg; /* op_kvariable */ +}; + +/* + * A statement from a config.in file + */ + +struct kconfig +{ + struct kconfig * next; + enum e_token token; + char * optionname; + char * label; + char * value; + struct condition * cond; + char * depend; /* token_dep_tristate */ + struct kconfig * cfg_parent; /* token_choice_item */ + + /* used only in tkgen.c */ + char global_written; + int menu_number; + int menu_line; + struct kconfig * menu_next; +}; + + + +/* + * Prototypes + */ + +extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */ +extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */ diff --git a/apps/xconfig/tkparse.o b/apps/xconfig/tkparse.o new file mode 100644 index 0000000..f80af97 Binary files /dev/null and b/apps/xconfig/tkparse.o differ diff --git a/doc/DECISIONS b/doc/DECISIONS new file mode 100644 index 0000000..db1dd91 --- /dev/null +++ b/doc/DECISIONS @@ -0,0 +1 @@ +* sigma0 external diff --git a/doc/TODO b/doc/TODO new file mode 100644 index 0000000..2ba7607 --- /dev/null +++ b/doc/TODO @@ -0,0 +1,16 @@ +* kernel memory layout +* sigma0 memory layout +* kernel frame allocator +* wake-up queue[s] ??? +* thread state ??? + + + + + + + + + +###################################################################### +arch/config.h contains KERNEL_PHYS ---> this should go into the linker scripts diff --git a/doc/design.old/Design-Outline b/doc/design.old/Design-Outline new file mode 100644 index 0000000..2dfcc4a --- /dev/null +++ b/doc/design.old/Design-Outline @@ -0,0 +1,296 @@ +Current Design ideas +==================== + +Memory Allocation: (Espen) +------------------ + +3 general frame sizes must be allocatable: + 16KB frames for page table directories + 4KB frames for TCB's + 1KB frames for page table leaves + +3 Other frame sizes are required for the mapping database: + 256B frames for 64KB/4KB mapping arrays nodes + 32B frames for 1KB mapping arrays nodes + 8B for single mapping nodes + +Currently we have a once-off allocator that can allocate (2^n)KB frames. We can use this and have a suballocator in the mapping database for its smaller frame sizes but its only temporary since its once off. Ideally we want to be able to free allocations and have smaller frame sizes merge when we run out of larger frame sizes. A buddy system is idea for this type of slab allocation. Once we can free allocations (fpage_unmap frees mapping database allocations/task delete frees the other 1/4/16KB allocations) a buddy system allocator should be implemented for the 1/4/16KB allocations and a sub-allocator for the smaller mapping db sizes should cluster the mapping nodes (for cache line utility) and get 4KB frames from the general allocator. + +Wake up queue: +-------------- + +A single ordered wake up queue could be used as a starting point but when large it might become a bottle neck. +A 'Real' design is needed here... (optimization!) + +Present List: (Adam) +------------- + +The present list is used for task delete, it is a doubly linked circular list with partial ordering. The partial ordering is that for any task if we start at lthread0 then to our right are all the threads of our task once the task id changes we are at the end of our tasks threads. This way starting at lthread0 we can find and kill all threads in our task in one sweep. To the left of the lthread0 we have all our child tasks until we hit a task depth that is equal to or less than our own. This way we can search for lthread0's of our child tasks by looking for task depths one less then ours and getting them to start task delete. + +The ordering is maintained by adding new threads to the right (via lthread_ex_regs) and adding new tasks (lthread0's via task_new) to the left. These are relative to the lthread0 of the task/chief. + +Mapping Database: (Adam/Espen) +----------------- + +The mapping database design can support the mixed page sizes of the ARM. The way +this is done is to start with a root frame table of 1MB sections (32KB). Each +1MB node contains the following information in a dword: + Task: Which task owns this mapping + Depth: The depth of this mapping (0 in the frame table) + Address: The virtual address of the 1MB mapping + Size_next: Whether next points to a single 1MB node or 64KB array node + Next: A pointer to the next 1MB single node or 64KB array node + Perms: Permission bits (for ARM we need grant bit, r/w bit, cache + bit and buffer bit) The r/w, c and b bits can be obtained + from the page table + +Once a 1MB section is split the Next pointer of the 1MB single node it was split +from points to a 64KB array node. This is an array of 16 64KB single mapping +nodes each containing the following information in a dword: + Task: Which task owns this mapping + Depth: The depth of the mapping + Address: The virtual address of the 64KB mapping + Size_next: Whether next points to a single 64KB node or a 4KB array node + Next: A pointer to the next 64KB single node or 4KB array node + Perms: Same as above + +To support the future 1KB page sizes of the ARM the 4KB node is similar to the +1MB and 64KB ones. 16 4KB single mapping nodes make up a 4KB array node, each +contains the following info in a dword: + Task: Which task owns this mapping + Depth: The depth of the mapping + Address: The virtual address of the 4KB mapping + Size_next: Whether next points to a single 4KB node or a 1KB array node + Next: A pointer to the next 4KB single node or 1KB array node + Perms: Same as above + +Finally 4 1KB single nodes make up a 1KB array node. Each 1KB single node +contains the following info in a dword: + Task: Which task owns this mapping + Depth: The depth of the mapping + Address: The virtual address of the 1KB mapping + Next: A pointer to the next 1KB single node + Perms: Same as above + +NOTE: 1k pags are suppored only on newer ARM9 cores which we don't have access +to. + +This design allows page sizes to be split into sub size mappings. Of course if a mapping is split directly to a size smaller then the next one intermediate arrays must be used. + +The single pointer and the depth field allow the frame mapping tree to be stored logically in a linked list (even though its a tree to support the splitting of mapping sizes). This is similar to the Fiasco design but we use a linked list +instead of a pointer which only costs an extra 3 bytes (8 vs fiasco's 5) but +adds the bonus that we are then aligned with the caches and still fit 4 entries +in one cache line. + +The mapping database should maintain its own 8/32/256 byte freelists and try to +cluster nodes together so as to fit paths of the tree into single cache lines. + +Task Deletion Path: (Based on fiasco's design) +------------------- + +This task delete design can be easily made preemptable: + +* Switch to lthread0 context of task to be deleted +* Make lthread0 busy +* Follow tcb->present_next links marking threads as busy until we hit a thread of a different task +* Follow tcb->present_prev signalling lthread0's as busy until we hit a thread depth equal to or less then our own. Wait for them all to signal they are done. +* Loop through page table, find mapping node for each valid page table entry and execute fpage_flush on it +* Loop through page table, free all page table leaf (1KB frames) +* Free page directory (16KB frame) +* Loop through kernel page table freeing all tcb mappings for task (and relevant page table leafs +* Signal to caller that we are done + +Thread Switch Path: (Adam/Uwe) +------------------- + +Ideally this should include some form of Fast Address Space Switching later - for now its just the brain dead way of doing it (which linux uses) + +- Switch internal (to kernel) context + * Stack current thread context + * Switch Kernel stack to the new thread +- Switch task context (if required) + * Change pagetable pointers + * Clean DCache + * Invalidate Caches + * Invalidate TLBs +- Switch to new thread + * Top of stack contains address of unstacking procedure + * Unstack threads context + + +Map (Memory) Operation: (Espen) +----------------------- + +To be done + +Grant (Memory) Operation: (Espen) +------------------------- + +To be done + +Flush (Memory) Operation: (Espen) +------------------------- + +To be done + +Data Abort Dispatching: (Adam) +---------------- +The data abort dispatching path is used for user level paging and for paging +TCBs. The path is as follows: + +FAR = Fault Address Register +FSR = Fault Status Register +SPSR = Save Program Status Register + +(See ARM ARM for more info) + +Data_Abort_Dispatch +{ + if(SPSR & MODE_MASK) / Abort generated in a Kernel Mode + if((FAR >= TCB_START) && (FAR < TCB_LIMIT)) + switch (FSR.Status) { + case TRANSLATION_SECTION: // Map Page Table Leaf, execute next case too + Add_Page_Table_Leaf(FAR); + case TRANSLATION_PAGE: // Map Null TCB frame + Map_Null_TCB(FAR); + break; + case PERMISSION_PAGE: // Map fresh TCB frame + Map_Fresh_TCB(FAR); + break; + default: // Kernel should not raise other abort status in TCB space + Kernel_Panic(GENERAL_DATA_ABORT); + } + else // Kernel should not raise data aborts anywhere else (until Long IPC) + Kernel_Panic(GERERAL_DATA_ABORT); + else // Abort generated in User Mode + switch (FSR.Status) { + case TRANSLATION_SECTION: // User Page Fault + case TRANSLATION_PAGE: + case PERMISSION_SECTION: + case PERMISSION_PAGE: + User_Page_Fault(FAR, FSR); + break; + default: // User Exception + User_Exception(FAR, FSR); + } +} + +PROBLEM: How do we keep kernel mappings (ie TCBs since they are the only ones that change) consistent across task page tables. Page table leafs for TCBs should be shared, how to enforce this? + +Solution: Have all kernel mappings added to Sigma0's page table as well, then + we check sigma0's page table before we add mappings page table leaves. + we then add the page table leaf to the sigma0 page table as well. This + way page table leaves of the kernel are shared across task page + tables. + +Prefetch Abort Path: (Adam) +-------------------- + +Prefetch Aborts should only signal user page faults otherwise kernel bug. The +path is as follows with the defines from above: + +- check if user or kernel aborted +if(SPSR indicates user mode) + - check abort reason + if(if page table indicates Translation/Permission fault) + * Generate a pager ipc to threads pager_tid + else(page table indicates otherwise) + * Generate a exception ipc to threads excpt_tid +else(SPSR indicates kernel mode) + * Kernel Panic (should never prefetch abort in the kernel) + +Preemption: (Adam/Uwe) +---------------------- + + Kernel Code fits in general into two catagories. Preemptable sections +and non-preemptable critical sections. Preemptable is fine, we unmask both IRQs +and FIQs and the kernel can be interrupted at any time. For non-preemptable time +bound operations (if the operations time is bound and fast the kernel is +suitable for real time systems) we mask both IRQs and FIQs. + IRQ's are not a problem since on any exception they are masked out by +the hardware. However between the exception and the code masking the FIQ we can +have a FIQ since the user state may not be stacked we must either either stack +the whole of the register set (the unbanked registers, the user bank and the +interrupted exception bank) which is very expensive or come up with something +else. Since FIQ's are supposed to be for very time critical interrupts this is +not a good option. + On the SA-1100 the simple solution to direct all interrupts to IRQs +then the FIQ is never an issue. However some ARM micro's like the 7110 (ARM7) +hardwire some interrupts to IRQs and the rest to FIQs so we cannot solve the FIQ +problem by ignoring it. What we can do is get the FIQ dispatcher/handler to work +out what state it interrupted and if the kernel was interrupted in a before it +stacked the user state we return to it and allow it to finish stacking until +its in a preemptable state. The simple solution is as follows + + On entry to the kernel the F=0 (FIQ mask), I=1 (IRQ mask). The kernel +then stacks the user state and then sets the F/I bits to either 0 (preemptable) +or 1 (non-preemtable) once the F/I bits are set the kernel code is in safe +state. + + The FIQ dispatcher on entry (FIQ exceptions mask both IRQs/FIQs) checks +the SPSR for the mode of the cpu. If user mode was preempted we just go about +handling the FIQ. If kernel mode was preempted we have to check the F/I bits: + + F=0,I=0: Kernel is in a safe preemtable state so go about handling FIQ + F=0,I=1: Kernel is stacking user state so we switch back to it masking +the FIQ in the process so F=1,I=1 and no FIQ can preempt the kernel until it +unmasks interrupts at which time the FIQ handler will be invoked again (since +the interrupt was not cleared) + F=1,I=0: N/A + F=1,I=1: N/A since by definition the FIQ handler can not be entered + + So all we really have to do is check the I bit. This solution has a nice +bound overhead since the worst case is a single FIQ being generated in the +'unsafe' state and we return straight away until we are ready to be preeptable. In most cases the cost of setting the CPSR (To update the F/I bits) is required +anyway to change to the abort mode of the cpu (for our ignore ARMs exsesive +banked modes mentality) it also adds minimal overhead in the FIQ path to keep +FIQ's in the user state and preemptable kernel state fast. + In the case of the SA-1100 where we can route interrupts to either FIQs +or IRQs it is still a little up in the air what to do. Routing all to IRQs means +the kernel can not be preempted in the unsafe state so it saves us the cost of +trapping the FIQ returning and then trapping again later. Routing all to FIQs +means the interrupt handler code has more banked registers to play with. +Spliting the routing allows us to do something like route all user interrupts to +the one handler and kernel interrupts to the other. This would allowing simpler +handlers and allow the more register intensive one to have the banked registers +while the less register intensive one avoids the overhead of the double trap. + +ARM Register Banking: +--------------------- + +The ARM architecture provides 6 sets of banked registers. The normal user set, +as well as the abort, IRQ, FIQ, supervisor and undefined sets. The lr is set by +exception entry to the pc at the time of the exception so its not interesting +however the sp (stack pointer) is also banked and is of interest to use. The +idea of this is that each exception has its own stack so we don't need to load +or store it between exceptions. However L4 uses a kernel stack per thread and no +matter what exception arrises we want to stack the interrupted state on the +interrupted threads stack so the banked sp is more a hinderance then a help. + Three solutions exsit to this problem. One is to ignore the banked +registers and use only the abort mode. This can be done by uses prefetch aborts +to generate syscalls in the abort mode. Prefetch/Data aborts execute in the +abort mode already so the cases requiring speed all can enter the kernel with +the current threads kernel stack already set up in the abort_sp. SWI and +undefined instruction exceptions are not so time critical so they can switch to +the abort mode, IRQs and FIQs however do take a penalty and we lose most of the +benifits of the extra 5 banked registers in the FIQ mode. + The second solution is to use a non-banked register as the kernel stack.This costs the setup time of loading the current threads kernel stack pointer +whenever we first enter the kernel from the user mode but has the advantage that +the kernel stack is accessable from any mode so preemption in the kernel is fast +and the IRQs/FIQs get a worthwhile benifit. We also free up a banked register +which we can store data in that will remain unchanged during exceptions that +put the kernel into a different cpu mode. An added cost the unbanked kernel +stack pointer registers must moved to a temp register if an exception (other then a syscall) is raised in the user mode. This solution is nice for an ASM implimentation but has problems with standard C/gcc, however certain registers could be assigned invariant values so while we are in the kernel they have fixed +allocations. This might be a nice property but it requires gcc hacking to avoid +stacking and to associate the registers with variables (this may just require +some ASM glue in the C functions) + The last solution is to use the sp of the current mode and load it +before switching to the user mode. This however requires switching to the mode +we want it to be in (swi is the most profitable probably to keep syscalls fast) +and we have to manually load it at the start of any other exception. A real +complication arrises when exceptions are generated in the kernel. We then have +to switch modes to access the interrupted modes sp and this leads to the same +overheads at the first solution so its probably the least attractive option +since it only saves us moving the unbanked register that would be the kernel +stack pointer for exceptions user mode exceptions. The costs would outway the +benifit. diff --git a/doc/design.old/a4.sty b/doc/design.old/a4.sty new file mode 100644 index 0000000..8ba5717 --- /dev/null +++ b/doc/design.old/a4.sty @@ -0,0 +1,34 @@ +% +% "a4" document style option. +% John Pavel, May 1987 +% +% Redefines the \textheight and \topmargin for A4 paper, as opposed to US paper. + +% \textwidth is not altered because A4 is narrower than US paper. +% +% \textheight is the height of text (including footnotes and figures, +% excluding running head and foot). +% +% Adjusting \textheight will adjust position of the bottom of the page. +% Must preserve "(\textheight - \topskip) divides \baselineskip". +% \topskip always appears to be 10pt. +% +% +% Following Lamport's change to other style files on 24 Jun 86, +% changed to explicitly compute \textheight to avoid roundoff. The +% value of the multiplier was calculated as the floor of the old +% \textheight minus \topskip, divided by \baselineskip for +% \normalsize. +% +% +% +\topmargin 0 pt % Nominal distance from top of paper to top of page +\ifcase \@ptsize + % mods for 10 pt + \textheight 53\baselineskip +\or % mods for 11 pt + \textheight 46\baselineskip +\or % mods for 12 pt + \textheight 42\baselineskip +\fi +\advance\textheight by \topskip diff --git a/doc/design.old/a4wide.sty b/doc/design.old/a4wide.sty new file mode 100644 index 0000000..2985221 --- /dev/null +++ b/doc/design.old/a4wide.sty @@ -0,0 +1,36 @@ +% +% "moretext" document style option. +% Jean-Francois Lamy, July 86 +% +% Redefines the margins so that they are more in line with +% what we are used to see. +% + +\input a4.sty + +\ifcase \@ptsize + % mods for 10 pt + \oddsidemargin 0.15 in % Left margin on odd-numbered pages. + \evensidemargin 0.35 in % Left margin on even-numbered pages. + \marginparwidth 1 in % Width of marginal notes. + \oddsidemargin 0.25 in % Note that \oddsidemargin = \evensidemargin + \evensidemargin 0.25 in + \marginparwidth 0.75 in + \textwidth 5.875 in % Width of text line. +\or % mods for 11 pt + \oddsidemargin 0.1 in % Left margin on odd-numbered pages. + \evensidemargin 0.15 in % Left margin on even-numbered pages. + \marginparwidth 1 in % Width of marginal notes. + \oddsidemargin 0.125 in % Note that \oddsidemargin = \evensidemargin + \evensidemargin 0.125 in + \marginparwidth 0.75 in + \textwidth 6.125 in % Width of text line. +\or % mods for 12 pt + \oddsidemargin -10 pt % Left margin on odd-numbered pages. + \evensidemargin 10 pt % Left margin on even-numbered pages. + \marginparwidth 1 in % Width of marginal notes. + \oddsidemargin 0 in % Note that \oddsidemargin = \evensidemargin + \evensidemargin 0 in + \marginparwidth 0.75 in + \textwidth 6.375 true in % Width of text line. +\fi diff --git a/doc/design.old/design.tex b/doc/design.old/design.tex new file mode 100644 index 0000000..b1666fc --- /dev/null +++ b/doc/design.old/design.tex @@ -0,0 +1,805 @@ +\documentclass[a4paper,10pt,twoside]{article} + +\usepackage{draftcopy} +\usepackage{latexsym} +\usepackage{a4wide} +\usepackage{fancyhdr} +\usepackage{verbatim} +\usepackage[dvips]{graphicx} +\usepackage[center]{subfigure} +\usepackage{hhline} +\fussy +\raggedbottom{} + +\newcommand{\sigmaz}{\mbox{$\sigma_0$}} + +\newcommand{\mkl}{\mbox{L4$\mu$K}} +\newcommand{\Strong}{\mbox{StrongARM}} +\newcommand{\SA}{\mbox{\Strong\ SA-1100}} +\newcommand{\Problem}{\begin{bf}Problem:\end{bf}\ } +\newcommand{\Note}{\begin{bf}Note:\end{bf}\ } +\newcommand{\Pseudo}[1]{\verbatiminput{pseudo/#1}} +\newcommand{\Fu}[2][]{\texttt{#2(#1)}} % Functions +\newcommand{\Va}[1]{\texttt{#1}} % Variables + +%% Create top of memlayout table +\newcommand{\Tmemtop}[1]{% + \multicolumn{1}{r}{\raisebox{0pt}[0pt][0pt]{\raisebox{-.6em}{#1}}}&% + \multicolumn{2}{c}{}} + +%% Create a memlayout cell in a table +\newcommand{\Tmem}[3]{% + \raisebox{0pt}[0pt][0pt]{\raisebox{-.3em}{% + \parbox[r][#1][b]{8em}{\hfill #2}}}&% + \parbox[c][#1][c]{10em}{\hfil\mbox{#3}\hfill}} + +%% Make a large rightbrace +\newcommand{\rbr}[1]{$\left.\vbox to #1{} \right\}$} + + +% From Anders Andersen (AAndersen@ACM.org) +% A much nicer footnote. +\makeatletter +\let\fnote\footnote +\def\footnote#1{\@ifnextchar.{\@afootnote{#1}}{% +\@ifnextchar,{\@afootnote{#1}}{\fnote{#1}}}} +\def\@afootnote#1{\makebox[0pt][l]{\footnotemark}\footnotetext{#1}} +\makeatother + +\pagestyle{fancyplain} + +\renewcommand{\sectionmark}[1]{\markright{\thesection{} #1}} + +\lhead[\fancyplain{}{\bfseries\thepage}] + {\fancyplain{}{\bfseries\rightmark}} +\rhead[\fancyplain{}{\bfseries\rightmark}] + {\fancyplain{}{\bfseries\thepage}} +\cfoot[]{} +\renewcommand{\cleardoublepage} + {\clearpage\if@twoside \ifodd\c@page\else + \hbox{}\thispagestyle{empty}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi} + +\setlength{\parskip}{1em plus 0.5ex} +\setlength{\parindent}{0pt} + + + + + +\begin{document} + +\newlength{\centeroffset} +\setlength{\centeroffset}{-0.5\oddsidemargin} +\addtolength{\centeroffset}{0.5\evensidemargin} + +\thispagestyle{empty} +\vspace*{\stretch{1}} +\noindent\hspace*{\centeroffset} + +\begin{minipage}{\textwidth} + \flushright + {\Huge\bfseries Karlsruhe - L4 on ARM\\} + \vspace*{\stretch{2}} + \noindent\rule[-1ex]{\textwidth}{5pt}\\[2.5ex] + \hfill\emph{\Large Design Draft -\today-}\\[2ex] +\end{minipage} + +\vspace{\stretch{1}} +\noindent\hspace*{\centeroffset} + +\begin{minipage}{\textwidth} + \flushright + \ +\end{minipage} +\vspace{\stretch{2}} + +\newpage + +\tableofcontents + +\cleardoublepage + +\section{Introduction} + +This document outlines the current Karlsruhe design of the L4 Micro-Kernel for the ARM Architecture (L4/ARM). + +This document assumes familiarity with the \mkl, the 'ARM Architecture Version 4' (See ARM ARM) and the 'Intel SA-1100 CPU' (See SA-1100 TRM). + +\newpage +\section{Design Structure} + +This section discusses the major design structures of the kernel. + +\subsection{ARM Register Banking} + +The ARM architecture provides 6 sets of banked registers for different +exceptions. The normal user set, as well as the abort, IRQ, FIQ, supervisor +and undefined sets. The LR (link registers) is set by exception entry to the +PC (program counter) at the time of the exception so its not so interesting +however the SP (stack pointer) is also banked and is of interest to us +immediately after an exception. The idea of this SP banking is that each +exception has its own stack so the a kernel doesn't need to load or store it +between exceptions. However L4 uses a kernel stack per thread and no matter +what exception arises L4 wants to stack the interrupted state on the +interrupted threads kernel stack so the banked SP is more a hindrance +than a help. + +There are three ways to deal with this banking of the SP. The first is to +ignore the banked registers and use only a single mode for the kernel. By +using just the abort mode we can minimize the need to switch modes often. +This can be done by using prefetch aborts to generate syscalls in the abort +mode. The prefetch abort handler simply checks where the abort occurred and +if it is a special address it is treated as a syscall, the cost of this is +approximately the same as a SWI instruction with the syscall number in a +register. Prefetch/Data aborts execute in the abort mode already so the +cases requiring speed (Syscalls and page faults) all enter the kernel with +the current threads kernel stack already set up in the abort SP. SWI and +undefined instruction exceptions are not so time critical (they result in an +exception IPC to the threads exception handler) so they can switch to the +abort mode manually, IRQs and FIQs however do take a penalty to manually +switch and we lose most of the benefits of the extra 5 banked registers in +the FIQ mode. + +The second method is to use a non-banked register as the kernel stack. +This costs the setup time of loading the current threads kernel stack pointer +whenever we first enter the kernel from the user mode but has the advantage +that the kernel stack is accessible from any mode so preemption within the +kernel is fast (the kernel stack is already loaded) and the IRQs/FIQs get the +benefit of not requiring to switch modes as well as FIQs having the extra +5 banked registers to allow fast FIQ handling. We also free up a banked +register (the SP) which we can store data in that will remain unchanged +during exceptions that put the kernel into a different CPU mode or during +the user mode for example we could load the kernel miscellaneous data pointer +in here. An added cost the unbanked kernel stack pointer registers must moved +to a temporary register if an exception (other than a syscall. syscalls could +use this register as the syscall number which can be trashed after the syscall +is dispatched) is raised in the user mode. This method is nice for an assembly +implementation but has problems with standard C/gcc, however certain registers +could be assigned invariant values so while we are in the kernel. This might +be a nice property but it requires hacking gcc to change the register used for +the stack pointer and to associate the registers with variables (this may just +require some ASM glue in the C functions). + +The last method is to use the SP of the supervisor mode and load it before +switching to the user mode (so its already loaded for syscalls). This however +requires switching to the supervisor mode (when the kernel is preempted) and +then using that mode to handle the exception. If the user is preempted their +stack is empty so we can just load it and stay in the current mode. This +method is essentially the same as the first but lacks the benefits of having +page faults fast (since they share the same mode as the syscalls do) so its +probably not worth considering. + +While the first method is attractive for a C implementation it has +implementation difficulties which make it a little doubtful whether any real +gains are made and if it doesn't indeed cost more than the second method. +For now we are using the first method since the second would require gcc +modification. + +\subsection{Quality of Service Scheduling (Adam's Random Jiberish)} + +To support the implementation of any scheduling policy all time must be +accounted for and strict priorities maintained. Since the kernel executes in +the context (on the kernel stack of at least) of the currently running thread +(the last thread an exception was raised in, be it a syscall or not) or the +thread currently being switched to we can simply extend this so that the +kernel operation runs under the time slice and the priority of the current +thread as well. Then if the time slice runs out or a higher priority thread +becomes ready the current kernel context is stacked and we switch to the new +thread. This system does have problems if the kernel is in a non-preemptable +state and the time slice runs out or a higher priority thread becomes ready, +since it will be delayed until the kernel enters a preemptable state again. + +$<$Adam: So I'm not sure how much of a problem this is or what potential +solutions exist$>$ + +Another issue with a fully preemptable kernel is how to handle locked data +structures. One possible method is to use something similar to Fiasco's +transaction scheme. For quick operations interrupt masking can be used (on a +uni-processor system) to lock critical sections. While the the transaction +scheme could be used for time intensive operations that aren't as critical +(for example, task deletion, flushing of mappings and possibly long IPC). So +with the long operations the thread wanting the lock can donate its time +slice/priority to the preempted thread that has the lock. + +\subsection{Kernel Preemption} + +One of the goals of the kernel design is to have a kernel suitable for real +time systems. This requires a bound maximum time that the kernel is not +preemptable. + +Kernel Code fits into two general categories: + +\begin{itemize} +\item Preemptable sections, and +\item Non-Preemptable sections +\end{itemize} + +Preemptable section are fine, we unmask both IRQs and FIQs and the kernel can +be interrupted at any time. For non-preemptable time bound operations (if the +operation time is bound and fast the kernel is suitable for real time systems) +we need to mask both IRQs and FIQs. IRQs are not a problem since on the +generation of any exception they are masked out by the hardware. However FIQs +are not masked for any exception (except and FIQ) so between the exception +and the code masking the FIQ bit an FIQ may be raised. Since the user state +may not be stacked at this stage we must either either stack the whole of the +register set (the unbanked registers r0-r12, the user bank +$<$user\_mode$>$\_SP/\_lr) and the interrupted exception bank +$<$exception\_mode$>$\_SP/\_lr) which is very expensive (while we can use +store multiple to access the user bank the exception bank can only be saved +by switching to it which is expensive) or come up with something else. Since +FIQs are supposed to be for very time critical interrupts this would not be +a good option. + +On the SA-1100 (and other ARM CPUs/Platforms with an interrupt controller +which can direct to either the IRQ or FIQ) the simple solution to direct all +interrupts to IRQ signal then the FIQ exception is never raised and is not an +issue. However some ARM CPUs/Platforms like the 7110 (ARM7) hardwire some +interrupts to the IRQ signal and the rest to FIQ signal so we cannot solve +the FIQ exception problem by ignoring it. What we can do is get the FIQ +dispatcher/handler to work out what state it interrupted and if it was a +kernel mode that was interrupted before it could mask IRQ/FIQ we return to it +and allow it to finish what it was until its in a preemptable state. The +simple solution is as follows. + +On exception entry to the kernel F=0 (FIQ mask bit), I=1 (IRQ mask bit). The +kernel then either sets the F/I bits (non-preemptable) OR stacks the user +state and then clears the F/I bits (preemptable) once the F/I bits are set +the kernel code is in 'safe' state. + +The FIQ dispatcher on entry (FIQ exceptions mask both IRQs/FIQs) checks the +SPSR for the mode of the CPU which was preempted. If user mode was preempted +we just go about handling the FIQ (we can always preempt the user). If kernel +mode was preempted we have to check the F/I bits: + +\begin{itemize} +\item F=0/I=0: Kernel is in a 'safe' preemptable state so go about handling FIQ +\item F=0/I=1: Kernel is not in the 'safe' state so switch back to it masking +the FIQ in the process. Then F=1,I=1 and no FIQ can preempt the kernel until +it unmasks interrupts at which time the FIQ handler will be invoked again +(since the interrupt was not cleared) +\item F=1/I=X: N/A, since by definition the FIQ handler can not be entered +\end{itemize} + +So all the FIQ dispatcher needs to do is check the state of the I bit. This +solution has a nice bound overhead since the worst case is a single FIQ being +generated in the 'unsafe' state returning straight away until the kernel is +ready to be preemptable. This worst case is the non-preemptable time plus the +time for an FIQ to trap and return quickly with this masking. In all cases +the SPSR must be loaded into a register so the only cost is checking the +mode/I states of the SPSR. This way minimal overhead is added to the FIQ path +keeping FIQs in the user state and preemptable kernel state fast. + +In the case of the SA-1100 (and other ARM systems) where we can route +interrupts to either FIQs or IRQs it is still a little up in the air what to +do. Routing all interrupts to IRQs means the kernel can not be preempted in +the 'unsafe' state so it saves us the cost of trapping the FIQ, returning and +then trapping again later. Routing all to FIQs means the interrupt handler +code has more banked registers to play with. Splitting the routing allows us +to do something like route all user interrupts to the one handler and kernel +interrupts to the other. This would allowing simpler handlers (in terms of +implementation) and allow the more register intensive of the two to have the +banked registers while the less register intensive one avoids the overhead of +the double trap. + + +\subsection{Kernel memory management} +\label{sec:kmem-management} + +Some mechanism must exist inside the kernel for dynamically allocating +and freeing memory. More precisely, management of 1KB, 4KB, and 16KB +chunks of memory (frames) must be supported. These frames are needed +by the following kernel mechanisms: + +\begin{description} +\item{\bf TCB management:} requires allocation and freeing of 4KB + frames for holding TCBs. +\item{\bf Page table management:} requires allocation and freeing of + 16KB for holding first level page tables, and 1KB frames for holding + second level page tables. +\item{\bf Mapping database:} requires allocation and freeing of 8 + byte, 16 byte, and 128 byte buffers. Management of these fine + grained buffers however, are handled by the mapping database itself + (see Section~\ref{sec:mapping-db-alloc}). Coarse grained allocation + is always performed in chunks of 4KB frames. +\end{description} + +When designing the memory management system we should try to optimize +for \emph{allocation} of frames; the reason being that frame +allocation may be used in an IPC map operation (i.e.\ by the page +table manager and the mapping database). As such, we keep a separate +frame list for each of the different frame sizes. Freeing frames on +the other hand, is not very time critical. The operation should +however---if it is time consuming---be made preemptable in order to +make the kernel suitable for real-time systems. + +We should also allow for movement of frames between the different +frame lists so as to avoid the situation where we have sufficient 4KB +frames to make a 16KB frame, but since the 16KB frame list is empty +the operation to allocate a 16KB frame fails (the same goes for +allocating a 4KB frame when there are available 16KB frames). Now, +moving frames from the 16KB frame list into the 4KB frame list is +easy. It is a simple matter of splitting the 16KB frames. +Concatenating four 4KB frames into a 16KB frames is somewhat tricker +since we have to find four consecutive frames in the 4KB frame list. +One solution to the problem is to search through the whole frame lists +in order to find four consecutive pages. This is obviously too +inefficient, especially if we take into consideration that the map +operation---which may require frames to be allocated---is to be fast. +Another solution to the problem is to always keep frame lists sorted. +This will however require far too much overhead when freeing frames, +and even though freeing frames is not such a time critical operation, +the operation will be difficult to make preemptable. + +Our solution to the problem is to keep parts of the frame lists +ordered. We keep clusters of four consecutive and properly aligned +frames in the end of the frame lists (see +Figure~\ref{fig:clustering}). A \emph{cluster pointer} points to the +first frame in the frame list belonging to a cluster. When, say a +16KB frame needs to be allocated from the 4KB frame list, the frames +in the first cluster in the 4KB frame list are removed, and the +cluster pointer is updated to point to the next cluster. The +invariant is that all frames in a frame list following a cluster +pointer are organized in clusters. Keeping clusters in the end of the +frame lists also ensures that clusters are not unnecessarily split up +if there are free frames elsewhere in the system. + +\begin{figure}[tbp] + \begin{center} + \includegraphics{fig/figure.1} + \caption{Frame lists and clustering} + \label{fig:clustering} + \end{center} +\end{figure} + +It is the responsibility of the free operation to organize the +clusters in the frame lists. This is accomplished by checking the +surrounding frames which makes up a cluster each time a frame is being +freed. If all three surrounding frames are found to be non-allocated, +the four frames are concatenated and moved back into the cluster area +of the frame list. + +As of today, a fixed amount of memory is dedicated to the kernel +memory allocation. One possible extension of memory allocator is +therefore to have a protocol between \sigmaz\ and the kernel in order +to allow free frames to flow between the two. This allows dynamic +balancing of memory allocation between the kernel and the user space, +and avoids compile (or boot) time parameterization of the kernel/user +memory allocation ratio. + + +\subsection{Mapping database} +\label{sec:mapping-db} + +To support mapping/granting of pages (whether by \Fu{ipc} or a pager) +and flushing of pages (whether by \Fu{fpage\_unmap} or task deletion) +a record of the hierarchical mappings/grantings must be maintained. +This is accomplished using a mapping database. For the ARM +implementation, three specific design problems regarding the mapping +database should be considered: + +\begin{enumerate} +\item How to keep the mapping database as small as possible (because + the typical ARM platforms supply limited memory). +\item How to maintain support for real time systems via time bound or + preemptable operations (because the typical application areas of ARM + require speed and often some form of quality of service or real-time + guarantees). +\item How can the mixed page sizes of the ARM (or any other CPU for + that matter) be supported. +\end{enumerate} + +\begin{figure}[tbp] + \begin{center} + \subfigure[Prior to flushing]{% + \includegraphics[scale=1]{fig/figure.2}}% + \label{fig:mapsplit-1}% + \hspace{1cm}% + \subfigure[After flushing]{% + \includegraphics[scale=1]{fig/figure.3}}% + \label{fig:mapsplit-2}% + \caption{Mapping tree replication due to flushing a + single page within a larger page. The grey box marks the page + that has been flushed.} + \label{fig:mapsplit} + \end{center} +\end{figure} + +Beyond pure implementation issues, the only conceptual hard problem of +these is to support multiple page sizes. The essence of the problem +can be illustrated by the following example: A task, $A$, has mapped a +64KB page to task $B$, which subsequently has mapped the page to tasks +$C$ and $D$ (Figure~\ref{fig:mapsplit}(a)). Now, task $A$ wants to +flush a single 4KB page within the page. In order to accomplish this, +the 64KB page must first be split into sixteen 4KB pages +(Figure~\ref{fig:mapsplit}(b)). The splitting of the 64KB page also +involves replicating the mapping three below task $A$ fifteen times. + +Unfortunately, the example above also applies if task $A$ wants to map +or grant one 4KB page within the larger page. This is not acceptable +because it; (1) requires too much overhead, and (2) is difficult to +make preemptable. We can however overcome the problem of replication +if we allow mapping trees to be shared between different mappings. +Figure~\ref{fig:mapshare} illustrates how this works. First, to find +the mappings of a specific task, the physical address of the mapping +is used to index into a set of tables (in much the same way that +physical addresses in a page table are found using the virtual address +for indexing). The result of this lookup is a pointer to a mapping +tree, which is parsed in order to find a specific mapping node. Now, +A task, $A$, has mapped a 64KB page to tasks $B$ and $C$ +(Figure~\ref{fig:mapshare}(a)). The task then wants to flush all its +mappings in the last 4KB page of the 64KB page. This is accomplished +by first splitting the 64KB page into 4KB pages, and then using the +\emph{old} mapping tree for all but the last 4KB page +(Figure~\ref{fig:mapshare}(b)). The only mapping tree that has to be +created/replicated, is the one below $R^{2.15}_{4k}$. + +\begin{figure}[tbp] + \begin{center} + \subfigure[Prior to flushing]{% + \includegraphics[scale=1]{fig/figure.4}}% + \label{fig:mapsshare-1}% + \hspace{1cm}% + \subfigure[After flushing]{% + \includegraphics[scale=1]{fig/figure.5}}% + \label{fig:mapshare-2}% + \caption{Mapping tree sharing due to flushing a smaller page + within a large page. Only one new mapping tree (the one below + $R^{2.15}_{4k}$) has to be created.} + \label{fig:mapshare} + \end{center} +\end{figure} + +The trick to enabling a mapping tree to be shared between different +mappings is to differ between root nodes ($R$-nodes in the figure) and +mapping nodes. Mapping nodes must not contain information that is +valid for only one mapping (e.g.\ the virtual memory location of the +mapping). Root nodes must not contain information which is not valid +for all mappings below it (e.g.\ the task owning the mapping). + +To figure out the virtual memory location of a mapping, a memory +offset is stored in the mapping node instead of a memory location. +The offset is relative to a physical memory location associated with +the root node. The memory location of the mapping is calculated by: +\[ +virtual\ address = physical\ address + offset\ in\ mapping\ node +\] + +Using this mapping scheme, the mapping tree of a split node may be +shared by all root nodes in the newly created root node table. +However, the mapping tree can not be shared if, say task $C$ wishes to +change the virtual memory address of one of its 4KB mappings. This +does not make much sense though. + +In order to keep track of the number of root nodes which uses a +mapping tree, the mapping node in the root of the mapping tree +contains a reference counter. The reference counter is large enough +to support sharing between all nodes after a split operation (i.e\ 16 +nodes), but not large enough to support sharing of cascading split +operations (e.g.\ a 64KB node which is split to 16KB nodes which is +subsequently split into 4KB nodes). A larger reference counter would +allow for this sort of sharing, but would also make the mapping node +larger, hence requiring more memory for a mapping tree. It is still +unclear which of the two schemes which are the better. + + +\subsubsection{Mapping database memory management} +\label{sec:mapping-db-alloc} + +In Section~\ref{sec:kmem-management}, we mentioned that the mapping +database is itself responsible for allocating the fine grained buffers +used for the different mapping database structures. The different +buffer sizes required by the mapping database are: 8 bytes for mapping +nodes, 16 bytes for 1KB root node tables, and 128 bytes for 4KB and +64KB root node tables. + +Each of the different buffer sizes have an associated list of frames +containing free buffers (see Figure~\ref{fig:mdb-mem}). The first few +bytes of each of these frames are dedicated to management structures. +The rest of the frames contains the buffers proper. The management +structure is used to keep track of the free buffers in the frame. It +contains: a pointer pointing to a list of free buffers, a counter +keeping track of the number of free buffers, and a pointer to the next +frame of free buffers. + +When a buffer is allocated from a frame, the buffer is removed from +the list of free buffers, and the counter for the number of free +buffers is updated. If the counter reaches zero, the whole frame is +removed from the frame list. This avoids further accesses to the +frame when a new buffer is to be allocated. + +When a buffer is de-allocated, it is hooked into the list of the frame +it belongs to, and the counter of free buffers is updated. If the new +counter value equals to one, it indicates that all the buffers in the +frame was previously allocated. This in turn implies that the frame +has been removed from the frame list. As such, we will have to hook +it into the frame list again\footnote{We may also choose to hook the + frame into the frame list when the counter reaches some higher + value. This will prohibit the next allocate buffer operation to + empty the buffer list and remove the frame from the frame list. + Using such a scheme, there will be less insertion/removal operations + on the frame list.}. If the new counter value reaches its maximum +(determined by the buffer size), it indicates that all the buffers in +the frame has been freed. The frame may then be handed back to the +kernel memory allocator, or it may be moved to the back of the frame +list to make the frame less likely to be allocated from in the future. +This latter option is useful if we want to free the frame at some +later stage. + +\begin{figure}[tbp] + \begin{center} + \includegraphics{fig/figure.6} + \caption{Memory management in mapping database} + \label{fig:mdb-mem} + \end{center} +\end{figure} + +Another feature of the mapping database memory manager is that it +tries to keep adjacent mapping nodes in the same cache line (32 +bytes). This is accomplished by allocating buffers at 32 bytes +granularity. Such a buffer is able to hold four mapping nodes of 8 +bytes each. When a mapping node is allocated in a new cache line, a +32 byte buffer is allocated, and the first word in each of the mapping +nodes (i.e.\ bytes 8--12, 16--20, and 24--28) are zeroed. Bytes 0--8 +are then used for holding the new mapping node. Upon allocating an +adjacent mapping node, the first word in the three surrounding mapping +nodes are examined. If any of these words is zeroed, it means that +the buffer is not allocated, and may be used for holding the adjacent +node. If none of the words are zeroed, a new cache line has to be +allocated. Using a zeroed first word in the buffer to indicate that +the buffer is free can only work if the an allocated buffer does not +ever have the first word zeroed. This can be assured because the +first word of the mapping node contains the task id of the mapping, +which may not be a zero one. + + +\subsection{Memory Layout} + +The L4/ARM kernel is currently developed on two different platforms: +the ``Brutus'' evaluation board (SA-1100), and the DNARD (SA-110). As +seen in Figure~\ref{fig:memlayout-physical}, there is a considerably +difference in the physical memory layout for the two platforms. In +order to ease cross platform development---in particular with respect +to the physical DRAM locations---the physical memory layout is +virtualized as seen in Figure~\ref{fig:memlayout-virtual}. + +\begin{figure}[tbp] + \begin{center} + \subfigure[Brutus]{% + \scalebox{.6}{% + \begin{tabular}{r|c|l} + \Tmemtop{0xFFFF~FFFF} \\ + \hhline{~-} + \Tmem{2.5em}{0xE800~0000}{Reserved} \\ + \hhline{~-} + \Tmem{1.5em}{0xE000~0000}{Zero bank} & \raisebox{0pt}[0pt][0pt]{ + \rbr{.9em} \parbox[l]{10em}{Used for cache flushing}} \\ + \hhline{~-} + \Tmem{4.5em}{0xC000~0000}{DRAM space} & \raisebox{0pt}[0pt][0pt]{ + \rbr{2.3em} \parbox[l]{10em}{\flushleft Split into 4 + equally sized banks at $x \times 128 \rm MB$}} \\ + \hhline{~-} + \Tmem{4em}{0x8000~0000}{I/O register space} \\ + \hhline{~-} + \Tmem{4em}{0x2000~0000}{PCMCIA space} \\ + \hhline{~-} + \Tmem{2em}{0x0000~0000}{SRAM space} \\ + \hhline{~-} + \end{tabular} + }}% + \label{fig:memlayout-brutus}% + \subfigure[DNARD]{% + \scalebox{.6}{% + \begin{tabular}{r|c|l} + \Tmemtop{0xFFFF~FFFF} \\ + \hhline{~-} + \Tmem{3em}{(\emph{unknown})}{(\emph{unknown})} \\ + \hhline{~-} + \Tmem{3em}{0x4000~0000}{I/O register space} \\ + \hhline{~-} + \Tmem{3em}{0x1000~0000}{(\emph{unknown})} \\ + \hhline{~-} + \Tmem{4.5em}{0x0C00~0000}{DRAM space} & \raisebox{0pt}[0pt][0pt]{ + \rbr{2.3em} \parbox[l]{10em}{\flushleft Split into 4 + equally sized banks at $x \times 32 \rm MB$}} \\ + \hhline{~-} + \Tmem{3em}{0x0000~0000}{(\emph{unknown})} \\ + \hhline{~-} + \end{tabular}% + }}% + \label{fig:memlayout-dnard}% + \caption{Physical memory layout} + \label{fig:memlayout-physical} + \end{center} +\end{figure} + +\begin{figure}[tbp] + \begin{center} + \begin{tabular}{r|c|l} + \Tmemtop{0xFFFF~FFFF} \\ + \hhline{~-} + \Tmem{2.1em}{0xFFFF~1000}{Kernel} & \raisebox{-7em}[0pt][0pt]{ + \rbr{8.2em} \parbox{10em}{Shared by all address spaces (512MB)}}\\ + \hhline{~-} + \Tmem{1em}{0xFFFF~0000}{Expt.\ vec.\ (relocated)} \\ + \hhline{~-} + \Tmem{3.2em}{0xFFF0~0000}{I/O mappings} \\ + \hhline{~-} + \Tmem{4.2em}{0xF000~0000}{Contiguous RAM} \\ + \hhline{~-} + \Tmem{5.3em}{0xE000~0000}{TCBs} \\ + \hhline{~-} + \Tmem{8em}{0x0000~1000}{User memory} \\ + \hhline{~-} + \Tmem{1em}{0x0000~0000}{Exception vector} & \raisebox{0pt}[0pt][0pt]{ + \rbr{.5em} \parbox{10em}{Shared by all address spaces (4KB)}} \\ + \hhline{~-} + \end{tabular} + \caption{Virtual memory layout} + \label{fig:memlayout-virtual} + \end{center} +\end{figure} + +%\begin{table}[ht]{\centering +%\begin{tabular}{|c|c|} +%\hline +%0x0000.0000 - 0x1FFF.FFFF & SRAM space (512MB)\\ +%0x2000.0000 - 0x3FFF.FFFF & PCMCIA space (512MB)\\ +%0x8000.0000 - 0xBFFF.FFFF & I/O register space (1GB)\\ +%0xC000.0000 - 0xDFFF.FFFF & DRAM space (512MB, split into four equally sized banks, at x*128MB)\\ +%0xE000.0000 - 0xE7FF.FFFF & Zero bank (128MB)\\ +%\hline +%\end{tabular} +%\caption{Brutus' Physical Memory Layout - 32MB DRAM installed } +%}\end{table} + +%\begin{table}[ht]{\centering +%\begin{tabular}{|c|c|} +%\hline +%0x0c00.0000 - 0x0FFF.FFFF & DRAM space (512MB, split into four equally sized banks, at x*32MB)\\ +%0x4000.0000 - ? & I/O register space\\ +%\hline +%\end{tabular} +%\caption{DNARD's Physical Memory Layout - 32MB DRAM installed } +%}\end{table} + +%\begin{table}[ht] +%\begin{tabular}{|c|c|} +%\hline +%0x0000.0000 - 0x0000.03FF & exception vector page (non relocated)\\ +%0xE000.0000 & TCB array\\ +%0xF000.0000 & DRAM - mapped as a contiguous area - XXX: is this ok?\\ +%0xFFF0.0000 & kernel IO mappings (timers, kdebug's serial ports, ...)\\ +%0xFFFF.0000 - 0xFFFF.0FFF & exception vector page (relocated)\\ +%0xFFFF.1000 - 0xFFFF.FFFF & kernel code/data/misc\\ +%\hline +%\end{tabular} +%\caption{Virtual Memory Layout} +%\label{tab:kernel-virt-mem} +%\end{table} + +Some words on the virtual memory layout is probably in place here. +First of all, the upper 1MB is dedicated to holding the kernel's code +and static data. We estimate this to be less than 60KB. The first +4KB of the upper 1MB is also used for holding the relocated exception +vector. Being able to relocate the exception vector is a feature of +the SA-1100. It is useful for three reasons: + +\begin{enumerate} +\item User-level programs may be located at address zero and upwards + (the default behavior for most compilers). +\item The code within the exception vector page may use short jumps to + anywhere within the kernel. If the exception vector is located at + address zero, this is not possible. +\item The kernel code (and static data) will require only one TLB + entry (the page table entry for the topmost 1MB section). If the + exception vector is located at address zero, the kernel will require + two TLB entries (one for the zero page, and one for the topmost 1MB + section). +\end{enumerate} + +If we are not able to relocate the exception vector, an optimization +for the latter case is to keep the the most time critical kernel code +(i.e.\ the short IPC path) in the same 4KB page as the exception +vector. This will ensure that we get at most one TLB miss when doing +short IPC. + +We also keep all available DRAM in the system in one contiguous block +of virtual memory. This makes memory management much simpler. +Moreover, since the contiguous ``physical'' RAM area is shared by all +address spaces, all dynamic kernel memory should be accessed using the +``physical'' address. + +The contiguous RAM is all mapped as 1MB sections. This enables the +dynamic kernel memory to occupy few page table entries. As such, the +number of TLB misses caused by the kernel (e.g.\ when walking the page +tables, or accessing the mapping database) is minimized. + +$<$We should have something on the TCB array here.$>$ + +\newpage +\section{Data Structures} + +This section introduces the kernel data structures and their use. + +\subsection{Kernel Miscellaneous Data} + +The kernel miscellaneous data contains miscellaneous information required by the kernel that doesn't fit in any other data structure. Things like the the heads of the ready queues and present list as well as the memory allocator information. + +$<$Adam: show the items from the kernel miscellaneous data and explain their use/need$>$ + +\subsection{Task Table} + +The task table is needed to keep track of a minimal set of task information since when a task is inactive is has no TCBs associated with it. The minimal information needed is the tasks state (a single bit) to indicate if the task is active or not as well as the task number of the chief (owner) of the task. The remaining bits can contain other task info that changes often. + +\subsection{Task Page Tables} + +The task page tables are simply the hardware loaded page tables specified by ARM. The Page directory pointer for each task is stored in the TCB of each thread in the given task. + +Since the kernel mappings are a reserved part of the address space all task page tables must have a copy of the kernel mappings. Consistency is maintained by adding new mappings to the kernel page table and lazily adding the mappings to other address spacing upon kernel faults. + +\Problem How do we keep mappings consistent when they are removed? Do we have to examine every task page table??? + +When flushing a task's TCBs on task\_delete, we do not remove the 2nd level page tables, we just invalidate all 2nd level entries. Doing reference counting on that 2nd level page tables to find unused pages might be a job for a kernel garbage collector. + +\subsection{Thread Control Blocks} + +Thread control blocks contain all information associated with a particular thread including the kernel stack for that thread. A large virtual array is used to allow fast lookup of a TCB from the threads TID (Thread ID). TCB's are demand paged. A read fault on a TCB block first checks if the TCB is mapped in (via checking for a mapping in the sigma0 page table) if not allocates a read only zeroed page (a Null TCB), write faults after checking for the same 'is the TCB mapped in' situation map in a fresh zeroed 4KB frame since write faults are only generated from thread creation (via lthread\_ex\_regs). + +$<$Adam: fill in the contents of the TCB and use/etc$>$ + +$<$Uwe: Null TCB sounds somewhat strange. A single zeroed page mapped to the various places should do the job. + + +\subsection{Present List} + +The present list is used for task delete, it is a doubly linked circular list with partial ordering. The partial ordering is that for any task if we start at lthread0 then to our right are all the threads of our task once the task id changes we are at the end of our tasks threads. This way starting at lthread0 we can find and kill all threads in our task in one sweep. To the left of the lthread0 we have all our child task threads until we hit a task depth that is equal to or less than our own. This way we can search for lthread0's of our child tasks by looking for task depths one less than or equal to ours and getting them to start task delete. + +The ordering is maintained by adding new threads to the right (via lthread\_ex\_regs) of the caller thread and adding new tasks (lthread0's via task\_new) to the left of the caller task's lthread0. + +\subsection{Ready Queues} + +Runnable threads are in the ready queues. Ready queues are (doubly linked?) circular lists to implement round robin scheduling. There's a ready queue per priority. The pointers to the next runnable threads are stored in an array. Once a certain thread has been selected to be run, the ready queue pointer for that priority is advanced. + +For a scheduling decision, the array is searched for an entry, starting from the highest priority. An optimization would be to store the highest existing/runnable priority. (Keeping track of that would require monitoring of the following events: Create a thread, enqueue/dequeue from ready queue, ... what else?) + +$<$Adam: should we put something more here?$>$ + +\subsection{Wakeup Queue} + +A single ordered wake up queue could be used as a starting point but when large it might become a bottle neck. + +A 'Real' design is needed here... (optimization!) + +\subsection{Mapping database} + + + +\newpage +\section{Kernel Procedures} + +This section outlines the operations the kernel performs. + +\subsection{Exception Entry/Exit} + +\subsection{Data Aborts} + +\subsection{Prefetch Aborts} + +\subsection{Undefined Instructions} + +\subsection{Software Interrupts} + +\subsection{IRQ Interrupts} + +\subsection{FIQ Interrupts} + + +\subsection{Test Zone - do not read} +\cite{ARMARM} + +\bibliographystyle{alpha} +\bibliography{arm} + +\end{document} + + diff --git a/doc/design.old/draftcopy.sty b/doc/design.old/draftcopy.sty new file mode 100644 index 0000000..2959391 --- /dev/null +++ b/doc/design.old/draftcopy.sty @@ -0,0 +1,8 @@ + +% Prints a large "DRAFT" diagonally across each page +% Does not show up in TeXview + +\typeout{Prints "DRAFT" on each page; does not show in TeXView} +\special{!userdict begin /bop-hook{gsave 200 30 translate +65 rotate /Times-Roman findfont 200 scalefont setfont +0 0 moveto 0.85 setgray (DRAFT) show grestore}def end} diff --git a/doc/design.old/fancyhea.sty b/doc/design.old/fancyhea.sty new file mode 100644 index 0000000..13cfb62 --- /dev/null +++ b/doc/design.old/fancyhea.sty @@ -0,0 +1,129 @@ +% fancyheadings.sty version 1.7 +% Fancy headers and footers. +% Piet van Oostrum, Dept of Computer Science, University of Utrecht +% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands +% Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!sun4nl!ruuinf!piet) +% Sep 16, 1994 +% version 1.4: Correction for use with \reversemargin +% Sep 29, 1994: +% version 1.5: Added the \iftopfloat, \ifbotfloat and \iffloatpage commands +% Oct 4, 1994: +% version 1.6: Reset single spacing in headers/footers for use with +% setspace.sty or doublespace.sty +% Oct 4, 1994: +% version 1.7: changed \let\@mkboth\markboth to +% \def\@mkboth{\protect\markboth} to make it more robust + +\def\lhead{\@ifnextchar[{\@xlhead}{\@ylhead}} +\def\@xlhead[#1]#2{\gdef\@elhead{#1}\gdef\@olhead{#2}} +\def\@ylhead#1{\gdef\@elhead{#1}\gdef\@olhead{#1}} + +\def\chead{\@ifnextchar[{\@xchead}{\@ychead}} +\def\@xchead[#1]#2{\gdef\@echead{#1}\gdef\@ochead{#2}} +\def\@ychead#1{\gdef\@echead{#1}\gdef\@ochead{#1}} + +\def\rhead{\@ifnextchar[{\@xrhead}{\@yrhead}} +\def\@xrhead[#1]#2{\gdef\@erhead{#1}\gdef\@orhead{#2}} +\def\@yrhead#1{\gdef\@erhead{#1}\gdef\@orhead{#1}} + +\def\lfoot{\@ifnextchar[{\@xlfoot}{\@ylfoot}} +\def\@xlfoot[#1]#2{\gdef\@elfoot{#1}\gdef\@olfoot{#2}} +\def\@ylfoot#1{\gdef\@elfoot{#1}\gdef\@olfoot{#1}} + +\def\cfoot{\@ifnextchar[{\@xcfoot}{\@ycfoot}} +\def\@xcfoot[#1]#2{\gdef\@ecfoot{#1}\gdef\@ocfoot{#2}} +\def\@ycfoot#1{\gdef\@ecfoot{#1}\gdef\@ocfoot{#1}} + +\def\rfoot{\@ifnextchar[{\@xrfoot}{\@yrfoot}} +\def\@xrfoot[#1]#2{\gdef\@erfoot{#1}\gdef\@orfoot{#2}} +\def\@yrfoot#1{\gdef\@erfoot{#1}\gdef\@orfoot{#1}} + +\newdimen\headrulewidth +\newdimen\footrulewidth +\newdimen\plainheadrulewidth +\newdimen\plainfootrulewidth +\newdimen\headwidth +\newif\if@fancyplain \@fancyplainfalse +\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi} + +% Command to reset various things in the headers: +% a.o. single spacing (taken from setspace.sty) +% and the catcode of ^^M (so that epsf files in the header work if a +% verbatim crosses a page boundary) +\def\fancy@reset{\restorecr + \def\baselinestretch{1}% + \ifx\undefined\@newbaseline% NFSS not present; 2.09 or 2e + \ifx\@currsize\normalsize\@normalsize\else\@currsize\fi% + \else% NFSS (2.09) present + \@newbaseline% + \fi} + +% Initialization of the head and foot text. + +\headrulewidth 0.4pt +\footrulewidth\z@ +\plainheadrulewidth\z@ +\plainfootrulewidth\z@ + +\lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}} +% i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages +\chead{} +\rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}} +% i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages +\lfoot{} +\cfoot{\rm\thepage} % page number +\rfoot{} + +% Put together a header or footer given the left, center and +% right text, fillers at left and right and a rule. +% The \lap commands put the text into an hbox of zero size, +% so overlapping text does not generate an errormessage. + +\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\hbox +{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill +\parbox[b]{\headwidth}{\centering#3\strut}\hfill +\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5} + + +\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\footrule +\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill +\parbox[t]{\headwidth}{\centering#3\strut}\hfill +\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5} + +\def\headrule{{\if@fancyplain\headrulewidth\plainheadrulewidth\fi +\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}} + +\def\footrule{{\if@fancyplain\footrulewidth\plainfootrulewidth\fi +\vskip-0.3\normalbaselineskip\vskip-\footrulewidth +\hrule\@width\headwidth\@height\footrulewidth\vskip0.3\normalbaselineskip}} + +\def\ps@fancy{ +\def\@mkboth{\protect\markboth} +\@ifundefined{chapter}{\def\sectionmark##1{\markboth +{\uppercase{\ifnum \c@secnumdepth>\z@ + \thesection\hskip 1em\relax \fi ##1}}{}} +\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne + \thesubsection\hskip 1em\relax \fi ##1}}} +{\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth>\m@ne + \@chapapp\ \thechapter. \ \fi ##1}}{}} +\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@ + \thesection. \ \fi ##1}}}} +\ps@@fancy +\global\let\ps@fancy\ps@@fancy +\headwidth\textwidth} +\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy} +\def\ps@plain@fancy{\@fancyplaintrue\ps@@fancy} +\def\ps@@fancy{ +\def\@oddhead{\@fancyhead\@lodd\@olhead\@ochead\@orhead\@rodd} +\def\@oddfoot{\@fancyfoot\@lodd\@olfoot\@ocfoot\@orfoot\@rodd} +\def\@evenhead{\@fancyhead\@rodd\@elhead\@echead\@erhead\@lodd} +\def\@evenfoot{\@fancyfoot\@rodd\@elfoot\@ecfoot\@erfoot\@lodd} +} +\def\@lodd{\if@reversemargin\hss\else\relax\fi} +\def\@rodd{\if@reversemargin\relax\else\hss\fi} + +\let\latex@makecol\@makecol +\def\@makecol{\let\topfloat\@toplist\let\botfloat\@botlist\latex@makecol} +\def\iftopfloat#1#2{\ifx\topfloat\empty #2\else #1\fi} +\def\ifbotfloat#1#2{\ifx\botfloat\empty #2\else #1\fi} +\def\iffloatpage#1#2{\if@fcolmade #1\else #2\fi} diff --git a/doc/design.old/fig/esk.mp b/doc/design.old/fig/esk.mp new file mode 100644 index 0000000..7439556 --- /dev/null +++ b/doc/design.old/fig/esk.mp @@ -0,0 +1,497 @@ +%%% +%% +%% Alignment macros +%% +%%% + +%% +%% Align all boxes horizontally along their centers +%% +vardef halign@#(suffix first)(text tt) = + if str @# = "": + ypart(first.c- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.c) + else: + $.c) = ypart($.c- + fi + endfor + else: + ypart(first.@#- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.@#) + else: + $.@#) = ypart($.@#- + fi + endfor + fi + = 0; +enddef; + +%% +%% Align all boxes vertically along their centers +%% +vardef valign@#(suffix first)(text tt) = + if str @# = "": + xpart(first.c- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.c) + else: + $.c) = xpart($.c- + fi + endfor + else: + xpart(first.@#- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.@#) + else: + $.@#) = xpart($.@#- + fi + endfor + fi + = 0; +enddef; + + +%%% +%% +%% Sizing macros +%% +%%% + +%% +%% Set x-size of all boxes to be equal. May be used as lvalue. +%% +def eqxsize(suffix first)(text tt) = + xpart(first.e-first.w) + forsuffixes $=tt: = xpart($.e-$w) endfor +enddef; + +%% +%% Set y-size of all boxes to be equal. May be used as lvalue. +%% +def eqysize(suffix first)(text tt) = + ypart(first.n-first.s) + forsuffixes $=tt: = ypart($.n-$s) endfor +enddef; + +%% +%% Set x-size and y-size of all boxes equal. May be used as lvalue. +%% using a pair. +%% +def eqsize(suffix first)(text tt) = + (xpart(first.w-first.e), ypart(first.n-first.s)) + forsuffixes $=tt: = (xpart($.w-$e), ypart($.n-$s)) endfor +enddef; + + +%%% +%% +%% Suffix macros +%% +%%% + +%% +%% Return last suffix in list. +%% +vardef lastsuffix(text tt) = + save _i,_j; + _i := _j := 0; + forsuffixes $=tt: _i:=_i+1; endfor; + forsuffixes $=tt: + if incr _j = _i: $ fi + endfor +enddef; + +%% +%% Return true if suffix `ss' is the last suffix in `tt'. +%% +vardef islastsuffix(suffix ss)(text tt) = + save _st,_r; string _st; boolean _r; + _r := false; + forsuffixes $=tt: _st := str $; endfor; + if str ss = _st: _r := true; fi + _r +enddef; + + +%%% +%% +%% Spacing macros +%% +%%% + +%% +%% Set the x-spacing between all boxes to be equal. May be used as lvalue. +%% +def xspace(suffix first)(text tt) = + -xpart(first.e- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.w) + else: + $.w) = -xpart($.e- + fi + endfor +enddef; + +%% +%% Set the y-spacing between all boxes to be equal. May be used as lvalue. +%% +def yspace(suffix first)(text tt) = + -ypart(first.n- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.s) + else: + $.s) = -ypart($.n- + fi + endfor +enddef; + + +%%% +%% +%% Dropshadow +%% +%%% +pair shadowoff; +shadowoff = (2pt,-2pt); + +%input mpattern; +% +%beginpattern(shadow_pattern); +% u:=.3mm; +% fill unitsquare scaled u; +% fill unitsquare scaled u shifted (u,u); +% patternbbox(0,0,2u,2u); +%endpattern; + +%% +%% Dropshadow on a list of boxes +%% +vardef dropshadow(text t) = + fixsize(t); fixpos(t); + forsuffixes s=t: + drawshadow bpath.s; + endfor; + forsuffixes s=t: + unfill bpath.s; + endfor; +enddef; + +%% +%% Dropshadow on a single path +%% +vardef drawshadow expr p = + fill p shifted shadowoff withcolor .4white; +% fill p shifted shadowoff withpattern shadow_pattern; + unfill p; +enddef; + + +%%% +%% +%% Picture maker +%% +%%% +pair mkpicoff, mkpicoff.c; +pair mkpicoff.nw, mkpicoff.w, mkpicoff.sw, mkpicoff.s; +pair mkpicoff.se, mkpicoff.e, mkpicoff.ne, mkpicoff.n; +mkpicoff := (-.5,.5); mkpicoff.c := (-.5,.5); +mkpicoff.nw := (0,0); mkpicoff.w := (0,.5); +mkpicoff.sw := (0,1); mkpicoff.s := (.5,1); +mkpicoff.se := (1,1); mkpicoff.e := (1,.5); +mkpicoff.ne := (1,0); mkpicoff.n := (.5,0); + +%% +%% Make picture with a specified size. First argument (if present) +%% after picture will be the xsize (may be set to 0 to keep size). +%% Next argument (if present) will be ysize. An alignment position +%% may be given as suffix to the function (nw,w,sw,s,se,e,ne,n,c). If +%% no suffix is given, `c' will be assumed. If a pair is given as an +%% argument, it will be used as on offset of the picture within the +%% new picture (relative to the alignment). +%% +vardef mkpic@#(expr inarg)(text tt) = + save ll,lr,ul,ur,off, inpic; + save outpic, st, xsz, ysz, oxsz, oysz, ?; + pair ll,lr,ul,ur,off; + picture outpic, inpic; + string st; + numeric xsz, ysz, oxsz, oysz; + boolean ?; + + inpic := if picture inarg: inarg + elseif string inarg: inarg infont defaultfont scaled defaultscale + else: nullpicture + fi; + outpic := inpic; + + xsz := oxsz := xpart(lrcorner inpic - llcorner inpic); + ysz := oysz := ypart(ulcorner inpic - llcorner inpic); + ? := false; + off := (0,0); + + %% Parse arguments + for ss=tt: + if numeric ss: + if ss <> 0: + if not ?: xsz := ss else: ysz := ss fi; + fi; + ? := true; + elseif pair ss: + off := ss; + fi; + endfor; + + ul := ulcorner inpic; + st := str @#; + + %% Adjust for x-position + if (st = "") or (st = "n") or (st = "c") or (st = "s"): + ul := ul + (-.5xsz + .5oxsz, 0); + elseif (st = "ne") or (st = "e") or (st = "se"): + ul := ul + (-xsz + oxsz, 0); + fi; + + %% Adjust for y-position + if (st = "") or (st = "w") or (st = "c") or (st = "e"): + ul := ul + (0, .5ysz - .5oysz); + elseif (st = "sw") or (st = "s") or (st = "se"): + ul := ul + (0, ysz - oysz); + fi; + + ul := ul + off; + ll := ul + (0,-ysz); + lr := ul + (xsz,-ysz); + ur := ul + (xsz,0); + + setbounds outpic to ll--lr--ur--ul--cycle; + outpic +enddef; + + +%%% +%% +%% Bus boxes +%% +%%% +if unknown defaultdx: + input boxes; +fi + +newinternal default_busarrlen, default_busarrdir; +default_busarrlen := 3bp; +default_busarrdir := 45; + +vardef hbusit@#(text tt) = + beginbox_("hbuspath_","sizebus_",@#,tt); + generic_declare(pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w; + 0 = xpart (@#nw-@#sw) = ypart(@#se-@#sw); + 0 = xpart(@#ne-@#se) = ypart(@#ne-@#nw); + @#w = .5[@#nw,@#sw]; + @#s = .5[@#sw,@#se]; + @#e = .5[@#ne,@#se]; + @#n = .5[@#ne,@#nw]; + @#ne-@#c = @#c-@#sw = (@#dx,@#dy) + .5*(urcorner pic_@# - llcorner pic_@#); + endbox_(clearb_,@#); +enddef; + +def hbuspath_(suffix $) = + $.w -- + ($.nw+(($.nw-$w)+(0,$.arrlen)) rotated -$.arrdir) -- + (xpart(($.nw+(($.nw-$w)+(0,$.arrlen)) rotated -$.arrdir)),ypart($.nw)) -- + (xpart(($.ne+(($.ne-$e)+(0,$.arrlen)) rotated $.arrdir)),ypart($.ne)) -- + ($.ne+(($.ne-$e)+(0,$.arrlen)) rotated $.arrdir) -- + $.e -- + ($.se-(($e-$.se)+(0,$.arrlen)) rotated -$.arrdir) -- + (xpart(($.se-(($e-$.se)+(0,$.arrlen)) rotated -$.arrdir)),ypart($.se)) -- + (xpart(($.sw-(($w-$.sw)+(0,$.arrlen)) rotated $.arrdir)),ypart($.sw)) -- + ($.sw-(($w-$.sw)+(0,$.arrlen)) rotated $.arrdir) -- + cycle +enddef; + +vardef vbusit@#(text tt) = + beginbox_("vbuspath_","sizebus_",@#,tt); + generic_declare(pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w; + 0 = xpart (@#nw-@#sw) = ypart(@#se-@#sw); + 0 = xpart(@#ne-@#se) = ypart(@#ne-@#nw); + @#w = .5[@#nw,@#sw]; + @#s = .5[@#sw,@#se]; + @#e = .5[@#ne,@#se]; + @#n = .5[@#ne,@#nw]; + @#ne-@#c = @#c-@#sw = (@#dx,@#dy) + .5*(urcorner pic_@# - llcorner pic_@#); + endbox_(clearb_,@#); +enddef; + +def vbuspath_(suffix $) = + $.n -- + ($.ne+(($.ne-$n)+($.arrlen,0)) rotated -$.arrdir) -- + (xpart($.ne),ypart($.ne+(($.ne-$n)+($.arrlen,0)) rotated -$.arrdir))-- + (xpart($.se),ypart($.se+(($.se-$s)+($.arrlen,0)) rotated $.arrdir)) -- + ($.se+(($.se-$s)+($.arrlen,0)) rotated $.arrdir) -- + $.s -- + ($.sw-(($.s-$sw)+($.arrlen,0)) rotated -$.arrdir) -- + (xpart($.sw),ypart($.sw-(($.s-$sw)+($.arrlen,0)) rotated -$.arrdir)) -- + (xpart($.nw),ypart($.nw-(($.n-$nw)+($.arrlen,0)) rotated $.arrdir)) -- + ($.nw-(($.n-$nw)+($.arrlen,0)) rotated $.arrdir) -- + cycle +enddef; + +def sizebus_(suffix $) = + if unknown $.dx: $.dx=defaultdx; fi + if unknown $.dy: $.dy=defaultdy; fi + if unknown $.arrlen: $.arrlen=default_busarrlen; fi + if unknown $.arrdir: $.arrdir=default_busarrdir; fi +enddef; + + + +%%% +%% +%% Creating circles and boxes as pictures. +%% +%%% + +%% +%% Create circle containing the picture (and optionally filled) +%% +vardef circlepic(text tt) = + save inpic,outpic; picture inpic,outpic; + save bound; path bound; + save colp, argp; boolean colp, argp; + save fillcol; color fillcolor; + save xsz, ysz; + colp := argp := false; + + for ss=tt: + if not argp: + inpic := if picture ss: ss + elseif string ss: ss infont defaultfont scaled defaultscale + else: nullpicture + fi; + argp := true; + elseif color ss: + colp := true; + fillcolor := ss; + fi; + endfor; + + xsz := xpart(lrcorner inpic - llcorner inpic); + ysz := ypart(ulcorner inpic - llcorner inpic); + + bound := fullcircle + xscaled ((xsz++ysz)+defaultdx) yscaled ((xsz++ysz)+defaultdy) + shifted (.5(xsz,ysz) + llcorner inpic); + + outpic := nullpicture; + if colp: addto outpic contour bound withcolor fillcolor; fi; + addto outpic also inpic; + addto outpic doublepath bound; + outpic +enddef; + +%% +%% Create rectangle containing the picture (and optionally filled) +%% +vardef boxpic(text tt) = + save inpic,outpic; picture inpic,outpic; + save bound; path bound; + save colp, argp; boolean colp, argp; + save fillcol; color fillcolor; + colp := argp := false; + + for ss=tt: + if not argp: + inpic := if picture ss: ss + elseif string ss: ss infont defaultfont scaled defaultscale + else: nullpicture + fi; + argp := true; + elseif color ss: + colp := true; + fillcolor := ss; + fi; + endfor; + + bound := (lrcorner inpic + (defaultdx,-defaultdy)) -- + (llcorner inpic + (-defaultdx,-defaultdy)) -- + (ulcorner inpic + (-defaultdx,defaultdy)) -- + (urcorner inpic + (defaultdx,defaultdy)) -- cycle; + + outpic := nullpicture; + if colp: addto outpic contour bound withcolor fillcolor; fi; + addto outpic also inpic; + addto outpic doublepath bound; + outpic +enddef; + + + +%%% +%% +%% Misc macros. +%% +%%% + +%% +%% Fill all boxes using the given specification `w'. +%% +vardef fillall(text t)(text w) = + fixsize(t); fixpos(t); + forsuffixes s=t: + fill bpath.s w; + endfor; +enddef; + + +%% +%% Magnifying glass +%% +vardef magnify(expr magpos, magfact, magsize) = + save magpic; picture magpic; + magpic := currentpicture; + + clip magpic to fullcircle scaled magsize shifted magpos; + unfill fullcircle scaled (magsize*magfact) shifted magpos; + draw magpic shifted -magpos scaled magfact shifted magpos; + draw fullcircle scaled (magsize*magfact) shifted magpos; +enddef; + + +newinternal termlength; +termlength := 3; + +%% +%% Draw expression with a terminating end (i.e. ``----|'') +%% +def drawterm expr p = + draw (-(.5termlength,0)--(.5termlength,0)) + rotated (angle(direction infinity of p)+90) + shifted point infinity of p; + draw p; +enddef; + + +vardef midcutting(suffix ss) = + save ce, no, so, i, cw, ch, nc; + ce := .5xpart(ss.w+ss.e); + no := ypart(ss.n); so := ypart(ss.s); + cw := 5bp; ch := 5bp; + nc := 4; + + ss.nw--(ce-.5nc*cw-.25cw,no)-- + for i=-.5nc step 1 until .5nc-1: + (ce+cw*i,no+.5ch)--(ce+cw*i+.5cw,no-.5ch)-- + endfor + (ce+.5nc*cw-.25cw,no)--ss.ne--ss.se--(ce+.5nc*cw-.25cw,so)-- + for i=.5nc-.5 step -1 until -.5nc: + (ce+cw*i,so-.5ch)--(ce+cw*i-.5cw,so+.5ch)-- + endfor + (ce-.5nc*cw-.25cw,so)--ss.sw--cycle +enddef; diff --git a/doc/design.old/fig/figure.mp b/doc/design.old/fig/figure.mp new file mode 100644 index 0000000..b440c1a --- /dev/null +++ b/doc/design.old/fig/figure.mp @@ -0,0 +1,459 @@ +input rboxes; +input graph; +input esk; + +%prologues:=1; + +vardef dcuta(suffix a,b) expr p = + drawarrow p cutbefore bpath.a cutafter bpath.b; +enddef; + + +beginfig(1); + u := 3mm; + + circleit.f2(btex $f_5$ etex); + circleit.f3(btex $f_{17}$ etex); + circleit.f5(btex $f_2$ etex); + circleit.f8(btex $f_8$ etex); + circleit.f9(btex $f_9$ etex); + circleit.f10(btex $f_{10}$ etex); + circleit.f11(btex $f_{11}$ etex); + + eqsize(f2,f3,f4,f5,f8,f9,f10,f11); + halign(f2,f3,f5,f8,f9,f10,f11); + xspace(f2,f3,f5,f8,f9,f10,f11) = u; + + circleit.b1(btex etex); + xpart(f8.w-b1.w) = xpart(b1.e-f11.e) = .5u; + ypart(f8.s-b1.s) = ypart(b1.n-f8.n) = 2u; + + boxit.pfreelist(btex frame list pointer etex); + boxit.pcluster(btex cluster pointer etex); + boxit.descr(btex \vbox{\hbox{Cluster of four consecutive} + \hbox{aligned frames.}} etex); + + halign(pfreelist,pcluster); + xpart(f2.c-pfreelist.c) = xpart(f8.c-pcluster.c) = 2u; + yspace(f2,pfreelist) = 5u; + + descr.n = b1.s - (2u,3u); + + drawboxed(f11,f2,f3,f5,f8,f9,f10); + fixsize(b1); draw bpath.b1 dashed evenly; + drawunboxed(pfreelist,pcluster,descr); + + dcuta(f2,f3) f2.c{up}..{down}f3.c; + dcuta(f3,f5) f3.c{up}..{down}f5.c; + dcuta(f5,f8) f5.c{up}..{down}f8.c; + dcuta(f8,f9) f8.c{up}..{down}f9.c; + dcuta(f9,f10) f9.c{up}..{down}f10.c; + dcuta(f10,f11) f10.c{up}..{down}f11.c; + drawterm (f11.c{up}..f11.c+(3u,u)) cutbefore bpath.f11; + + dcuta(pfreelist,f2) pfreelist.c..{down}f2.c; + dcuta(pcluster,f8) pcluster.c..{down}f8.c; + + dcuta(descr,b1) descr.c..{up}b1.c; + +endfig; + + +beginfig(2); + u := 3mm; + + boxit.la(btex $A_{64k}$ etex); + boxit.lb(btex $B_{64k}$ etex); + boxit.lc(btex $C_{64k}$ etex); + boxit.ld(btex $D_{64k}$ etex); + ypart(la.n-la.s) = xpart(la.e-la.w); + + eqsize(la,lb,lc,ld); + + valign(la,lb); + halign(lc,ld); + xpart(.5[lc.c,ld.c]) = xpart(lb.c); + + yspace(lc,lb,la) = 3u; + xspace(lc,ld) = 1.5u; + + drawboxed(la,lb,lc,ld); + + drawarrow la.s--lb.n; + dcuta(lb,lc) lb.c--lc.c; + dcuta(lb,ld) lb.c--ld.c; +endfig; + +beginfig(3); + u := 3mm; + + boxit.sa1(btex $A_{4k}^1$ etex); + boxit.sa2(btex $A_{4k}^2$ etex); + boxit.sa3(btex $$ etex); + boxit.sa4(btex $A_{4k}^4$ etex); + boxit.sacut(); xpart(sacut.e-sacut.w) = 5u; + boxit.sa14(btex $A_{4k}^{14}$ etex); + boxit.sa15(btex $A_{4k}^{15}$ etex); + boxit.sa16(btex $A_{4k}^{16}$ etex); + + boxit.sb1(btex $B_{4k}^1$ etex); + boxit.sc1(btex $C_{4k}^1$ etex); + boxit.sd1(btex $D_{4k}^1$ etex); + boxit.desc(btex Same tree repeated 15 times etex); + + ypart(sa1.n-sa1.s) = xpart(sa1.e-sa1.w); + eqsize(sa1,sa2,sa3,sa4,sa14,sa15,sa16,sb1,sc1,sd1); + eqysize(sa1,sacut); + + halign(sa1,sa2,sa3,sa4,sacut,sa14,sa15,sa16); + xspace(sa1,sa2,sa3,sa4,sacut,sa14,sa15,sa16) = 0; + valign(sa1,sb1); + xpart(.5[sc1.c,sd1.c]) = xpart(sb1.c); + halign(sb1,desc); + halign(sc1,sd1); + xspace(sc1,sd1) = u; + xpart(.5[sa2.c,sa16.c]) = xpart(desc.c); + yspace(sd1,sb1,sa1) = 3u; + + + drawboxed(sa1,sa2,sa3,sa4,sa14,sa15,sa16); + fillall(sa3)(withcolor .8white); + drawboxed(sa3,sb1,sc1,sd1); + fixsize(sacut); draw bpath.sacut dashed evenly; + drawunboxed(desc); + + drawarrow sa1.s--sb1.n; + dcuta(sb1,sc1) sb1.c--sc1.c; + dcuta(sb1,sd1) sb1.c--sd1.c; + + drawarrow sa2.s--sa2.s-(0,ypart(sa1.s-sb1.n)); + drawarrow sa4.s--sa4.s-(0,ypart(sa1.s-sb1.n)); + drawarrow sa14.s--sa14.s-(0,ypart(sa1.s-sb1.n)); + drawarrow sa15.s--sa15.s-(0,ypart(sa1.s-sb1.n)); + drawarrow sa16.s--sa16.s-(0,ypart(sa1.s-sb1.n)); +endfig; + + +beginfig(4) + u := 3mm; + + boxit.r1(btex $R^1_{64k}$ etex); + boxit.r2(btex $R^2_{64k}$ etex); + eqxsize(r1,r2) = eqysize(r1,r2); + + boxit.a(btex $A$ etex); + boxit.b(btex $B$ etex); + boxit.c(btex $C$ etex); + eqxsize(a,b,c) = eqysize(a,b,c); + + halign(r1,r2); + xspace(r1,r2) = 0; + + halign(b,c); + xspace(b,c) = u; + valign(a,r2); + + yspace(b,a,r2) = 2u; + xpart(.5[b.c,c.c]) = xpart(a.c); + + drawboxed(r1,r2,a,b,c); + drawarrow r2.s -- a.n; + dcuta(a,b) a.c -- b.c; + dcuta(a,c) a.c -- c.c; + draw r1.nw -- r1.nw - (2u,0) dashed evenly; + draw r1.sw -- r1.sw - (3.5u,0) dashed evenly; + draw r2.ne -- r2.ne + (1.7u,0) dashed evenly; + draw r2.se -- r2.se + (2.7u,0) dashed evenly; +endfig; + + +beginfig(5) + u := 3mm; + + boxit.r1(btex $R^1_{64k}$ etex); + boxit.r2(btex $R^2_{64k}$ etex); + eqxsize(r1,r2) = eqysize(r1,r2); + + boxit.s0(btex $R^{2.0}_{4k}$ etex); + boxit.s1(btex $R^{2.1}_{4k}$ etex); + boxit.s2(btex $R^{2.2}_{4k}$ etex); + boxit.s14(btex $R^{2.14}_{4k}$ etex); + boxit.s15(btex $R^{2.15}_{4k}$ etex); + eqsize(s0,s1,s2,s14,s15); + ypart(s15.n-s15.s) = xpart(s15.e-s15.w); + + boxit.a(btex $A$ etex); + boxit.b(btex $B$ etex); + boxit.c(btex $C$ etex); + boxit.a2(btex $A$ etex); + eqxsize(a,b,c,a2) = eqysize(a,b,c,a2); + + halign(r1,r2); + xspace(r1,r2) = 0; + halign(s0,s1,s2,s14,s15); + xspace(s0,s1,s2) = xspace(s14,s15) = 0; + xspace(s2,s14) = 8u; + + halign(a,a2); + halign(b,c); + xspace(b,c) = u; + valign(a,s0,r2); + valign(a2,s15); + + yspace(b,a,s0,r2) = 2u; + xpart(.5[b.c,c.c]) = xpart(a.c); + + drawboxed(r1,r2,s0,s1,s2,s14,s15,a,b,c,a2); + + drawarrow r2.s -- s0.n; + drawarrow s0.s -- a.n; + dcuta(a,b) a.c -- b.c; + dcuta(a,c) a.c -- c.c; + drawarrow s15.s -- a2.n; + dcuta(s1,a) s1.c{down} .. a.c; + dcuta(s2,a) s2.c{down} .. {left}a.c; + dcuta(s14,a) s14.c{down} .. {dir150}a.c; + + draw r1.nw -- r1.nw - (2u,0) dashed evenly; + draw r1.sw -- r1.sw - (3.5u,0) dashed evenly; + draw r2.ne -- r2.ne + (1.7u,0) dashed evenly; + draw r2.se -- r2.se + (2.7u,0) dashed evenly; + draw s2.ne -- s14.nw dashed evenly; + draw s2.se -- s14.sw dashed evenly; +endfig; + + +beginfig(6); + u := 3mm; + + circleit.b1(btex $b$ etex); + circleit.b2(btex $b$ etex); + circleit.b3(btex $b$ etex); + circleit.b4(btex $b$ etex); + circleit.b5(btex $b$ etex); + circleit.b6(btex $b$ etex); + circleit.b7(btex $b$ etex); + boxit.pfl1(btex \vbox{\hbox{freelist ptr.} + \hbox{num free = 7}}etex); + boxit.fr1(btex etex); + + circleit.c1(btex $b$ etex); + circleit.c2(btex $b$ etex); + circleit.c3(btex $b$ etex); + boxit.pfl2(btex \vbox{\hbox{freelist ptr.} + \hbox{num free = 3}} etex); + boxit.fr2(btex etex); + eqsize(fr1,fr2); + + boxit.ptr(btex list-list pointer etex); + + eqsize(b1,b2,b3,b4,b5,b6,b7,c1,c2,c3); + halign(pfl1,b1,b2,b3,b4,b5,b6,b7); + halign(pfl2,c1,c2,c3); + xspace(pfl1,b1,b2,b3,b4,b5,b6,b7) = xspace(pfl2,c1,c2,c3) = u; + + xpart(pfl1.w-fr1.w) = ypart(fr1.n-pfl1.n) = ypart(pfl1.s-fr1.s) = + xpart(pfl2.w-fr2.w) = ypart(fr2.n-pfl2.n) = u; + xpart(fr1.e-b7.e) = 2u; + valign.e(fr1,fr2); + + yspace(fr2,fr1) = 2u; + ptr.c = pfl1.n + (-3u,5u); + + fixsize(pfl1,pfl2,ptr,b1,b2,b3,b4,b5,b6,b7,c1,c2,c3,fr1,fr2); + dropshadow(fr1,fr2); + drawunboxed(pfl1,pfl2,ptr); + drawboxed(b1,b2,b3,b4,b5,b6,b7,c1,c2,c3,fr1,fr2); + + dcuta(pfl1,b1) pfl1.c{dir80}..{dir300}b1.c; + dcuta(b1,b2) b1.c{up}..{down}b2.c; + dcuta(b2,b3) b2.c{up}..{down}b3.c; + dcuta(b3,b4) b3.c{up}..{down}b4.c; + dcuta(b4,b5) b4.c{up}..{down}b5.c; + dcuta(b5,b6) b5.c{up}..{down}b6.c; + dcuta(b6,b7) b6.c{up}..{down}b7.c; + drawterm (b7.c{up}..b7.c+(2u,.7u)) cutbefore bpath.b7; + + dcuta(pfl2,c1) pfl2.c{dir80}..{dir300}c1.c; + dcuta(c1,c2) c1.c{up}..{down}c2.c; + dcuta(c2,c3) c2.c{up}..{down}c3.c; + drawterm (c3.c{up}..c3.c+(2u,.7u)) cutbefore bpath.c3; + + dcuta(ptr,fr1) ptr.c{right}..{down}pfl1.c; + dcuta(fr1,fr2) pfl1.c..pfl2.c; + drawterm (pfl2.c{down}..{dir320}pfl2.c+(1.3u,ypart(fr2.n-pfl1.c))) + cutbefore bpath.fr2; + + numeric k; + k = xpart(.5[pfl1.e,b1.w]); + draw (k,ypart(fr1.n))--(k,ypart(fr1.s)) dashed evenly; + draw (k,ypart(fr2.n))--(k,ypart(fr2.s)) dashed evenly; + + label.ulft(btex \it 4KB frame etex scaled .6, fr1.se); + label.ulft(btex \it 4KB frame etex scaled .6, fr2.se); +endfig; + + +beginfig(7); + u := 3.2mm; + + boxit.addrA(); boxit.addrB(); boxit.addrC(); boxit.addrD(); + boxit.pA(btex $a_1$ etex); + boxit.pB(btex $b_1$ etex); + boxit.pC(btex $c_1$ etex); + boxit.pD1(btex $d_1$ etex); + boxit.pD2(btex $d_2$ etex); + + eqysize(addrA,addrB,addrC,addrD) = eqysize(pA,pB,pC,pD1,pD2); + eqxsize(pA,pB,pC,pD1,pD2); + eqxsize(addrA,addrB,addrC,addrD) = 8u; + + halign(addrA,pA); xpart(pA.w-addrA.w) = 2u; + halign(addrB,pB); xpart(pB.w-addrB.w) = 3.5u; + halign(addrC,pC); xpart(pC.w-addrC.w) = 1.2u; + halign(addrD,pD1,pD2); xpart(pD1.w-addrD.w) = .5u; + xpart(pD2.w-addrD.w) = 3.1u; + + yspace(addrD,addrB,addrA) = 3u; + halign(addrB,addrC); + xspace(addrB,addrC) = 2.7u; + xpart(.5[addrB.e,addrC.w]) - u = xpart(addrA.c); + xpart(addrD.c) = xpart(addrA.c) + 2u; + + fixsize(pA,pB,pC,pD1,pD2); + drawboxed(addrA,addrB,addrC,addrD); + fillall(pA,pB,pC,pD1,pD2)(withcolor .8white); + drawboxed(pA,pB,pC,pD1,pD2); + + label.lft(btex $A$: etex, addrA.w); + label.lft(btex $B$: etex, addrB.w); + label.lft(btex $C$: etex, addrC.w); + label.lft(btex $D$: etex, addrD.w); + + dcuta(pA,pB) pA.c{down}..pB.c{down}; + dcuta(pA,pC) pA.c{down}..pC.c{down}; + dcuta(pB,pD1) pB.c{down}..pD1.c{down}; + dcuta(pC,pD2) pC.c{down}..pD2.c{down}; +endfig; + +beginfig(8); + u := 3mm; + + boxit.pA(btex $a_1$ etex); + boxit.pB(btex $b_1$ etex); + boxit.pC(btex $c_1$ etex); + boxit.pD1(btex $d_1$ etex); + boxit.pD2(btex $d_2$ etex); + + eqsize(pA,pB,pC,pD1,pD2); + + valign(pD1,pB); valign(pD2,pC); + halign(pD1,pD2); + halign(pB,pC); + yspace(pD1,pB,pA) = 3u; + xspace(pB,pC) = 2u; + xpart(.5[pB.c,pC.c]) = xpart(pA.c); + + drawboxed(pA,pB,pC,pD1,pD2); + + dcuta(pA,pB) pA.c--pB.c; + dcuta(pA,pC) pA.c--pC.c; + dcuta(pB,pD1) pB.c--pD1.c; + dcuta(pC,pD2) pC.c--pD2.c; +endfig; + + +beginfig(9); + u := 3.2mm; + + boxit.addrA(); boxit.addrB(); boxit.addrC(); boxit.addrD(); + boxit.pA(btex $a_1$ etex); + boxit.pB(btex $b_1$ etex); + boxit.pC(btex $c_1$ etex); + boxit.pD1(btex $d_1$ etex); + boxit.pD2(btex $d_2$ etex scaled .7); + + eqysize(addrA,addrB,addrC,addrD) = eqysize(pA,pB,pC,pD1,pD2); + eqxsize(pA,pB,pC,pD1) = 3.5u; + xpart(pD2.e-pD2.w) = .8u; + eqxsize(addrA,addrB,addrC,addrD) = 8u; + + halign(addrA,pA); xpart(pA.w-addrA.w) = 2u; + halign(addrB,pB); xpart(pB.w-addrB.w) = 3.5u; + halign(addrC,pC); xpart(pC.w-addrC.w) = 1.2u; + halign(addrD,pD1,pD2); xpart(pD1.w-addrD.w) = .5u; + xpart(pD2.w-addrD.w) = 5.1u; + + yspace(addrD,addrB,addrA) = 3u; + halign(addrB,addrC); + xspace(addrB,addrC) = 2.7u; + xpart(.5[addrB.e,addrC.w]) - u = xpart(addrA.c); + xpart(addrD.c) = xpart(addrA.c) + 2u; + + fixsize(pA,pB,pC,pD1,pD2); + drawboxed(addrA,addrB,addrC,addrD); + fillall(pA,pB,pC,pD1,pD2)(withcolor .8white); + drawboxed(pA,pB,pC,pD1,pD2); + + label.lft(btex $A$: etex, addrA.w); + label.lft(btex $B$: etex, addrB.w); + label.lft(btex $C$: etex, addrC.w); + label.lft(btex $D$: etex, addrD.w); + + dcuta(pA,pB) pA.c{down}..pB.c{down}; + dcuta(pA,pC) pA.c{down}..pC.c{down}; + dcuta(pB,pD1) pB.c{down}..pD1.c{down}; + dcuta(pC,pD2) (pC.e-(.4u,0)){down}..pD2.c{down}; + draw (pC.se-(.8u,0))--(pC.ne-(.8u,0)) dashed evenly scaled .5; + + pair k; + k = (xpart(.5[addrB.w,addrC.e]),ypart(addrA.n)+u); + label.top(btex \vbox{ + \hbox{$a_1 = b_1 = c_1 = d_1 = 64~\rm KB$} + \hbox{$d_2 = 4~\rm KB$}} etex, k); +endfig; + + +beginfig(10); + u := 3mm; + + boxit.pA(btex $a^{64k}_1$ etex); + boxit.pB(btex $b^{64k}_1$ etex); + boxit.pD1(btex $d^{64k}_1$ etex); + boxit.pD2(btex $d^{4k}_2$ etex); + + boxit.s1(btex $c^{4k}_1$ etex); + boxit.s2(btex $c^{4k}_2$ etex); + boxit.s3(btex $c^{4k}_3$ etex); + boxit.s4(btex $c^{4k}_4$ etex); + boxit.scut(); xpart(scut.e-scut.w) = 5u; + boxit.s14(btex $c^{4k}_{14}$ etex); + boxit.s15(btex $c^{4k}_{15}$ etex); + boxit.s16(btex $c^{4k}_{16}$ etex); + + eqsize(s1,s2,s3,s4,s14,s15,s16,pD2); + eqysize(s1,scut); + halign(s1,s2,s3,s4,scut,s14,s15,s16); + xspace(s1,s2,s3,s4,scut,s14,s15,s16) = 0; + + eqsize(pA,pB,pD1); + + valign(pD1,pB); + halign(pD1,pD2); + halign(pB,s1); + yspace(pD1,pB,pA) = 3u; + xspace(pB,s1) = 2u; + xpart(.5[pB.c,s1.c]) = xpart(pA.c); + valign(pD2,s16); + + drawboxed(pA,pB,s1,s2,s3,s4,s14,s15,s16,pD1,pD2); + draw bpath.scut dashed evenly; + + dcuta(pA,pB) pA.c--pB.c; + dcuta(pA,s1) pA.c--s1.c; + dcuta(pB,pD1) pB.c--pD1.c; + dcuta(s16,pD2) s16.c--pD2.c; +endfig; + + +end; diff --git a/doc/design/Makefile b/doc/design/Makefile new file mode 100644 index 0000000..d1ad567 --- /dev/null +++ b/doc/design/Makefile @@ -0,0 +1,17 @@ + +.SUFFIXES: +.SUFFIXES: .tex .dvi .ps + +all: design.ps + +.tex.dvi: + latex $< + +.dvi.ps: + dvips $< -o + + +design.dvi: fig/figure.1 + +fig/figure.1: fig/figure.mp + (cd fig; mpost figure) diff --git a/doc/design/design.tex b/doc/design/design.tex new file mode 100644 index 0000000..cff0535 --- /dev/null +++ b/doc/design/design.tex @@ -0,0 +1,729 @@ +\documentclass[a4paper,twoside]{book} + +%\usepackage[draft]{graphicx} +\usepackage{graphicx} +\usepackage{subfigure} +\usepackage{hhline} + +\newcommand{\ukern}{$\mu$-kernel} +\newcommand{\lka}{\emph{L4Ka}} +\newcommand{\sigmaz}{\mbox{$\sigma_0$}} +\newcommand{\state}[1]{\texttt{#1}} + +\newcommand{\fdecl}[3]{\emph{#1} {\bf\emph{#2}} (\emph{#3})} +\newcommand{\true}{\emph{true}} +\newcommand{\false}{\emph{false}} +\newcommand{\Type}[1]{\emph{#1}} +\newcommand{\Func}[1]{\texttt{#1}()} +\newcommand{\Var}[1]{\texttt{#1}} + +\raggedbottom{} + +\title{\lka \\ Design Manual \vspace*{5mm}} + +\author{ + \hspace*{1mm} Uwe Dannowski \hspace*{1mm} \and + \hspace*{1mm} Espen Skoglund \hspace*{1mm} \and + \hspace*{1mm} Volkmar Uhlig \hspace*{1mm} \and + \\ + System Architecture Group \\ + University of Karlsruhe \\ + \texttt{\small \{dannowski,skoglund,uhlig\}@ira.uka.de} + \vspace*{10mm}} + +\date{\today \\ {\small (Under construction)}} + + +\begin{document} + +\maketitle{} + +\listoffigures{} + +\tableofcontents{} + + + +\chapter{Introduction} + +\section{Overview of L4} + +\section{Source Tree Layout} + +\section{Design Goals} + + + +\chapter{Design Overview} + +\section{Kernel Components} + +\section{Virtual Memory Layout} + + + +\chapter{Design Details} + +\section{Initialization} + +\section{General Exception and Interrupt Handling} + + +\section{IPC} + +\subsection{Thread States} + +During an ongoing IPC operation, a thread may at different stages be +blocked or otherwise descheduled. If the thread is blocked, it is +necessary for the thread being its IPC partner to identify why the +thread is blocked. Furthermore, if other threads in the system start +a new IPC operation with the thread, it is necessary them to recognize +that the thread is already involved in an IPC operation. Failing to +do so would cause the the ongoing IPC operation to fail in an +arbitrary manner, rendering the system in an undefined non-recoverable +state. In short, threads will at times need to know which state other +threads in the system currently holds. In the L4/KA kernel a thread +may at any time be in one of the following six states: + +\begin{description} +\item{\state{RUNNING}:} The most common thread state. All threads + which are not involved in an IPC operation, and all threads which + are in the initial or final phase of an IPC operation will be in + this state. + +\item{\state{POLLING}:} The thread is doing a send, but the receiver + is not ready to receive the message yet. + +\item{\state{WAITING}:} The thread is doing a receive, but the sender + is not ready to send the message yet. + +\item{\state{LOCKED\_RUNNING}:} The thread has started the actual + send/receive operation of the IPC, and is not currently blocked. + +\item{\state{LOCKED\_WAITING}:} The thread has started the actual + send/receive operation of the IPC, but is currently blocked. The + thread can be blocked because either (a) the sender is copying data + to it (the receiver), or (b) it (the sender) are doing an indirect + memory message transfer and the receiver has to resolve a page fault + in its address space. + +\item{\state{ABORTED}:} The thread is not runnable. That is, it could + be in the process of being created, but does not yet have all + required data structures (e.g., page tables) initialized. It could + also be that it is an event-driven kernel thread (e.g., the dynamic + kernel memory allocator, see Section~\ref{sec:Dynamic-kmem}) waiting + for an event to occur. +\end{description} + + +\begin{table}[htbp] + \begin{center} + \begin{tabular}{|l|c|c|c|c|} + \hhline{~----} + \multicolumn{1}{c|}{} & Locked & Send-wait & Recv-wait & Schedulable \\ + \hline + \state{RUNNING} & & & & yes \\ + \state{POLLING} & & yes & & \\ + \state{WAITING} & & & yes & \\ + \state{LOCKED\_RUNNING} & yes & & & yes \\ + \state{LOCKED\_WAITING} & yes & & & \\ + \state{ABORTED} & & & & \\ + \hline + \end{tabular} + \caption{Thread states and their respective thread state bits} + \label{tab:thread-states} + \end{center} +\end{table} + + +\begin{figure}[t] + \begin{center} + \includegraphics[scale=.8]{fig/figure.7} + \caption{Thread state transitions during an IPC operation} + \label{fig:thread-states} + \end{center} +\end{figure} + +\subsection{Page Fault Tunneling} + +\section{Kernel Memory Allocator} +\label{sec:Dynamic-kmem} + + +\section{Address Spaces} + +The kernel identifes address spaces by a field in each thread control +block pointing to an architecture specific class, \Type{space\_t}, +describing the address space. How this class is implemented is +architecture dependent, but it will typically be a structure +describing the topmost page table in the page table hierarchy. +Methods for retrieving the physical and virtual locations of this page +table are then used by, e.g., the architecture specific thread +switching code. The methods implemented in the \Type{space\_t} class +are never used by architecture independent code. + + +\section{Generic Page Table Access} + +The \ukern\ contains generic functions for mapping and unmapping page +frames from any multi-level page table. The kernel can be configured +to support an arbitrary number of page table levels with arbitrary +page sizes. + +The page tables in the kernel are tightly coupled with the mapping +database structures (see Section~\ref{sec:mapping-db}). Each page +table entry contains a link to its associated node, the mapping node, +in the mapping database. For page table layouts which are dictated by +hardware and does not allow for such a link to be stored directly in +the page table entry, a shadow page table scheme can be used. + +\begin{figure}[ht] + \begin{center} + \includegraphics[scale=.8]{fig/figure.8} + \caption[Shadow page tables]{Shadow page tables. The location of the + shadow page table entry ($v_s$) can be calculated from the + location of the real page table entry ($v_r$).} + \label{fig:shadow-pagetab} + \end{center} +\end{figure} + +Figure~\ref{fig:shadow-pagetab} illustrates how a shadow page table +can be implemented. The shadow page table is co-located with the real +page table so that the two occupies one contiguous chunk of memory. +If a page table is 4KByte in size, the location of a shadow page table +entry---the entry containing the mapping node pointer---can then be +calculated by adding 4KByte to the location of the real page table +entry. + + +\subsection{Specifying Hardware Page Sizes} + +An architecture defined constant, \Var{HW\_NUM\_PGSHIFTS}, defines the +number of page sizes the page tables support. This constant is +augmented with an array, \Var{hw\_pgshifts}, containing the ``shift +counts'' of all hardware page sizes (i.e., log$_2$ of the page sizes). +All the shift counts must be listed in ascending order and the array +must be terminated by the shift count for the complete virtual address +space. Also note that page tables logically containing page table +entries of a size which can not be mapped by the hardware must still +be included in the \Var{hw\_pgshifts} array. In order for software to +avoid mapping pages of such sizes an architecture dependent constant, +\Var{HW\_VALID\_PGSIZES}, should define a bit-mask specifying the page +sizes which are mapable by the hardware. If bit $n$ is set in the +constant it indicates that the hardware support mapping pages of size +$2^n$. Using this scheme, the specification for x86 page tables +(supporting 4KByte and 4MByte pages) would look as follows: + +{\small +\begin{verbatim} + #define HW_NUM_PGSHIFTS 2 + #define HW_VALID_PGSIZES ((1 << 22) + (1 << 12)) + + dword_t hw_pgshifts[HW_NUM_PGSHIFTS+1] = { + 12, // 4KB + 22, // 4MB + 32 // 4GB (whole address space) + }; +\end{verbatim} +} + +If the kernel was compiled for an older x86 architecture not +supporting 4MByte pages, \Var{HW\_VALID\_PGSIZES} would have to be set +to ``\texttt{(1~<<~12)}'' instead. + + +\subsection{Accessing Page Tables} + +The generic page table access functions must have some way of +accessing the architecture specific page tables. This is achieved by +defining an architecture specific class, \Type{pgent\_t}, which both +defines the layout of a single page table entry and how to access the +entry. + +The page table access functions will only access a page table through +a number of methods in the \Type{pgent\_t} class. The following list +describes which methods must be supported in order to use the generic +mapping and unmapping functionality of the kernel. Additional methods +may of course be specified, but will not be invoked by architecture +independent code. Each method takes at least two arguments, the +address space identifier and the hardware page size index as described +above. + +\begin{description} + +\item{\fdecl{int}{is\_valid}{space\_t * s, int pgsize}\\} Return \true\ + if page table entry is valid, \false\ otherwise. A page table entry + containing a pointer to a subtree is considered to be valid. + +\item{\fdecl{int}{is\_writable}{space\_t * s, int pgsize}\\} + Return \true\ if page table entry indicates a writable page frame, + \false\ otherwise. + +\item{\fdecl{int}{is\_subtree}{space\_t * s, int pgsize}\\} Return + \true\ if page table entry is a pointer to a subtree, \false\ + otherwise. + +\item{\fdecl{dword\_t}{address}{space\_t * s, int pgsize}\\} Return the + physical address of the page frame described by the page table + entry. It is assumed that the page table entry contains a valid + mapping. + +\item{\fdecl{pgent\_t *}{subtree}{space\_t * s, int pgsize}\\} Return + the location of the subtree described by the page table entry. It + is assumed that the page table entry describes a valid subtree. + +\item{\fdecl{mnode\_t *}{mapnode}{space\_t * s, int pgsize, dword\_t + vaddr}\\} Return the location of the mapping node associated + with the page table entry. It is assumed that the page table entry + contains a valid mapping. The virtual address which the page frame + maps to is supplied so that the implementation can choose to store + both the virtual address and the mapping node address in the same + location by storing the bitwise exlusive or of both values. + +\item{\fdecl{dword\_t}{vaddr}{space\_t * s, int pgsize, mnode\_t * + map}\\} Return the virtual address for which the page frame of + the page table entry maps to. It is assumed that the page table + entry contains a valid mapping. The mapping node address is + supplied so that both the virtual address and the mapping node + address can be store in the same location using the bitwise + exclusive or of both values. + +\item{\fdecl{void}{clear}{space\_t * s, int pgsize}\\} Invalidate the + page table entry. It is assumed that the page table entry does not + describe a subtree. + +\item{\fdecl{void}{make\_subtree}{space\_t * s, int pgsize}\\} Create + an empty subtree beneath the page table entry. It is assumed that + the page table entry is invalid. Any mappings in the page table + entry will not be invalidated and any existing subtrees will not be + deleted. + +\item{\fdecl{void}{remove\_subtree}{space\_t * s, int pgsize}\\} Remove + the subtree described by the page table entry. It is assumed that + the page table entry does indeed contain a subtree. Subtrees are + not deleted recursively. Any valid mappings or subtrees within the + subtree must be invalidated prior to invoking this function. + +\item{\fdecl{void}{set\_entry}{space\_t * s, dword\_t vaddr, int + writable, int pgsize}\\} Initialize the page table entry with + the indication virtual address. The \emph{writable} argument + indicates whether the page frame should be mapped writable or not. + It is assumed that the page table entry does not contain a subtree. + +\item{\fdecl{void}{set\_writable}{space\_t * s, int pgsize}\\} Sets the + page table entry read-write. + +\item{\fdecl{void}{set\_readonly}{space\_t * s, int pgsize}\\} Sets the + page table entry read-only. + +\item{\fdecl{void}{set\_mapnode}{space\_t * s, int pgsize, mnode\_t * + map, dword\_t vaddr}\\} Sets the mapping node and virtual + address associated with the page table entry. Any existing values + are unconditionally overwritten. + +\item{\fdecl{pgent\_t *}{next}{space\_t * s, int n, int pgsize}\\} + Return the \emph{n}th page table entry following the current one. + No checks are made to see whether the returned page table entry + resides within the page table or not. + +\end{description} + +\section{Mapping Database} +\label{sec:mapping-db} + +The mapping database is one of the single largest components of the +\ukern. This is not surprising. It needs to manipulate possibly very +complex data structures, and also needs to be flexible enough to +support widely different hardware architectures (page sizes). Of +course, making the database very flexible also makes it somewhat more +complex. We have, however, found that the added complexity of +supporting $n$ page sizes instead of only two (as is the case with +Intel x86) is neglectable. Furthermore, the generic database design +is of great help when adopting the \ukern\ to other hardware +architectures, and by having a common code base, possible bugs are +more easily detected and fixed. + + +\subsection{General Approach} + +The mapping database has to keep track of which address spaces each +physical page frame in the system is mapped into. It therefore maps +physical page frames to address spaces in much the same way that page +tables map virtual addresses to physical addresses. In addition, the +mapping database must also keep track of mappings between different +address spaces (i.e., recursive mappings). This is accomplished using +two different data nodes: root nodes and mapping nodes. + +\begin{description} +\item{\em Root nodes:} Root nodes are not associated with any specific + address space. Rather, they are organized in arrays, and the + physical address of the page frame in question is used for indexing + into one particular root node. A root node can point to a number of + mapping nodes, and/or it can point to an array of root nodes of + smaller page sizes. +\item{\em Mapping nodes:} A mapping node \emph{is} associated with a + specific address space. It identifies which address space the page + frame is mapped into, and the virtual address that the page is + mapped to. Mapping nodes can---as root nodes---point to a number + other mapping nodes, and/or it can point to an array of root nodes + of smaller page sizes. +\end{description} + +Using root nodes and mapping nodes, the mapping database is +constructed with a top-level mapping node (representing the kernel), +pointing to an array of root nodes spanning the whole address space. +The size of this array depends on the size of the largest page size +the hardware offers. For example, the Intel x86 has top-level root +nodes of 4~MB size, and the ARM has top-level root nodes of 1~MB size. + +\begin{figure}[t] + \begin{center} + \includegraphics{fig/figure.2} + \caption[Complex mapping tree]{Complex mapping tree consisting of + 64~KB nodes (A, C, D, and E), 4~KB nodes (B, F, and I), and 1~KB + nodes (G and H).} + \label{fig:complex-map} + \end{center} +\end{figure} + +Since the kernel mapping node is located in top of the mapping tree, +it indicates that the kernel ``owns'' the whole physical address +space, and may map any physical page frame to other address +spaces.\footnote{An optimization of this approach is to also put a + mapping node for \sigmaz\ above the top-level root nodes. This will + cause sigma$_0$ to own the whole physical address space, obviating + the need to put \sigmaz\ mapping nodes beneath almost all top-level + root nodes. Parts of the physical address space may still be + removed from \sigmaz\ using the invalidation scheme presented in + Section~\ref{sec:Flushing}.}\@ When the kernel maps physical page +frames to other address spaces, mapping nodes are created beneath the +respective root nodes. These mapping nodes may in turn map the page +frame to other address spaces, or they may choose to map only part of +the page frame (i.e., smaller page sizes). If they choose to map +smaller page sizes, a root node array is created below the mapping +node, and mapping nodes for the new mappings are inserted below the +respective root nodes. + +Figure~\ref{fig:complex-map} illustrates how a single 64~KB page frame +can be mapped to a number of address spaces. The mapping tree makes +use of both 64~KB, 4~KB, and 1~KB mappings (these are all valid page +sizes in the ARM architecture). Mapping nodes are indicated by +circles, and root nodes are indicated by arrays of rectangles. It +should be noted that it is perfectly legal for a node to create +mappings to any of its parents. The node, I, may for instance create +a mapping to the address space of A. Such an operation would simply +insert another mapping node below node I. + +As mentioned above, different hardware architectures implement +different page sizes. The kernel programmer must therefore specify +the number of page sizes, \texttt{NUM\_PAGESIZES}, that the hardware +implements, and also the size of the different pages. Page sizes are +specified by declaring an array, \texttt{mdb\_pgshifts}, containing +the ``shift-counts'' for the different pages (i.e., log$_2$ of the +page size). The declaration for the Intel x86 architecture would for +instance look like the following: + +{\small +\begin{verbatim} + #define NUM_PAGESIZES 2 + + dword_t mdb_pgshifts[NUM_PAGESIZES+1] = { + 12, // 4KB + 22, // 4MB + 32 // 4GB (whole address space) + }; +\end{verbatim} +} + +Note that the shift-counts must be listed in ascending order, and must +for reasons of implementation simplicity be terminated by the +shift-count for the whole address space. + + +\subsection{Data Structures} + +It should be clear by now that any node (both root and mapping) may +logically contain pointers to an arbitrary large number of mapping +nodes in addition to an array of root nodes. Some mechanism must +exist for implementing this. The solution is actually twofold: (1) +providing recursive mapping trees, and (2) providing pointers to both +a mapping node and a root node. + +\paragraph{Providing Recursive Mappings.} + +Root nodes and mapping nodes only contain a single pointer. However, +mapping nodes do also, in addition to the pointer, contain a depth +counter which indicates how far down in the mapping tree the mapping +node is located. Using this counter, a whole tree of mapping nodes +can be implemented as a singly linked list. + +\begin{figure}[tp] + \begin{center} + \subfigure[Logical interpretation of node pointers.]{% + \includegraphics{fig/figure.5}}% + \hspace{1cm}% + \subfigure[Actual interpretation of node pointers. Nodes are + linked in the same order as a depth-first traversal.]{% + \includegraphics{fig/figure.6}}% + \caption[Logical vs.\ actual interpretation of node + pointers]{Logical vs.\ actual interpretation of node pointers. + Each node is marked with the depth it has in the mapping tree.} + \label{fig:maptree-linking} + \end{center} +\end{figure} + +Figure~\ref{fig:maptree-linking} illustrates how the value of the +depth counter is used to help the singly linked list be interpreted as +a mapping tree. The list of nodes is ordered in the same way as one +would traverse the mapping tree in a depth-first manner. As such, the +order of the mapping nodes is well defined. Finding all sibling nodes +of a specific node can be accomplished by scanning the list rightwards +until one reaches a node which has a depth count value which is equal +or greater to the value in the starting node. For example, scanning +the nodes following node B would reveal that its sibling nodes are C +and D (E has a depth count which is equal to B). Removing a subtree +from the mapping tree thus becomes a simple matter of traversing the +list. Inserting a new node is accomplished by inserting it directly +following its parent node. + +\paragraph{Providing a Double Set of Pointers.} + +Keeping two pointers within each root node and mapping node is the +easiest way of solving the double pointer problem. This approach, +however, would in general cause all nodes to grow by four bytes +(assuming a 32-bit address space), which would have a drastic effect +on the memory usage of the mapping database. A better approach is to +associate a special node (\texttt{dualnode\_t}) with each root node +array. The dual-node contains a pointer to the actual root node +array, and also potentially a pointer to a mapping tree (i.e., to the +mapping node being the root of the mapping tree). Having a special +node associated with each root node array is very memory efficient +since each root node array typically consists of a large number of +root nodes. Moreover, the dual-node contains usage counters for the +root node array. These counters are necessary for cleaning up unused +root node arrays after a flush operation (see +Section~\ref{sec:Flushing}). + + +\subsection{Mapping} + +Inserting a new mapping is the simplest operation that can be +performed in the mapping database. In short, the operation can be +described in three steps: + +\begin{enumerate} +\item Find the correct mapping node (the mapper) by indexing into root + node arrays, and parsing mapping node trees. If no such mapping + node is found, cancel the map operation. +\item If the mapping node represents a larger page size than the size + of the page to be mapped, create sibling root node arrays below the + mapping node until a root node array representing the correct page + size has been created. +\item Insert the new mapping node (the mappee) directly below the + mapper (or directly below a root node in a root node array belonging + to the mapper). +\end{enumerate} + +Searching for the right mapping node in step 1, may, of course, +require a large number of mapping nodes and root nodes to be +traversed. It is still considered a conceptually simple operation +though. + + +\subsection{Flushing} +\label{sec:Flushing} + +The real design difficulty of the mapping database is related to the +operation of flushing pages. In its simplest (and most used) form, +the flush operation is not any harder than that of mapping pages. For +example, flushing node E in Figure~\ref{fig:complex-map} would only +require traversing the mapping tree until the mapping node was found, +delete the mapping node, and recursively deleting all of its sibling +nodes (node F, G, H, I, and the three root node arrays). + +The problem with flushing arises when flushing a page size smaller +than the page size represented by the current mapping node. Consider, +for example, the case when node A in Figure~\ref{fig:complex-map} +wishes to flush a single 4~KB page within its 64~KB page. It can not +simply remove its sibling nodes since this would cause the whole 64~KB +page to be flushed. Some other mechanism must therefore be invented. + +\begin{figure}[t] + \begin{center} + \includegraphics{fig/figure.3} + \caption[Complex mapping tree with a 4~KB page flushed]{Complex + mapping tree with the first 4~KB page of node A flushed. Light + gray nodes are partially invalid. Dark gray crossed root nodes + are completely invalid. Nodes B, F, G, and H are deleted.} + \label{fig:complex-map-4kb} + \end{center} +\end{figure} + +An obvious solution to the problem is to create a root node array +above node A, and populate its root nodes with basically the same +mapping tree as the one found below node A. Such an approach would, +however, require the mapping tree below node A (including some root +node arrays) to be duplicated a large number of times. Furthermore, +the code-complexity of the duplication algorithm would be quite high +since not all nodes below A could be duplicated as is. Node A and +node E should for instance not contain a sibling root node array, and +node B, F, G, H, and I should only be duplicated below some specific +root nodes. A better solution to the problem is presented in +Figure~\ref{fig:complex-map-4kb}. + +In Figure~\ref{fig:complex-map-4kb}, only the nodes which are fully +contained within the flushed page are deleted (node B, F, G, and H). +The nodes which are only partly affected by the flush operation (node +A, C, D, and E) are marked as \emph{partly invalid}. Other nodes are +not affected at all. Since mapping nodes in this scheme can be marked +as partly invalid, one must in some way be able to tell which parts of +the node that are invalid. This is achieved by marking the flushed +root nodes in the associated root node arrays as \emph{invalid}. If a +particular partly invalid mapping node does not have a sibling root +node array (i.e., node C and D), a root node array for this node have +to be created. + +\begin{figure}[t] + \begin{center} + \includegraphics{fig/figure.4} + \caption[Complex mapping tree with a 1~KB page flushed]{Complex + mapping tree with the first 1~KB page of node A flushed. Light + gray nodes are partially invalid. Dark gray crossed root nodes + are completely invalid. Node G is deleted. } + \label{fig:complex-map-1kb} + \end{center} +\end{figure} + +Figure~\ref{fig:complex-map-1kb} depicts another example of flushing a +small part of a larger page. In this example, a single 1~KB page is +flushed out of a 64~KB page. In general, the approach taken is the +same as for flushing 4~KB pages. The only difference is that fewer +nodes are actually deleted, and some more sibling root node arrays +need to be created. + +After a flush operation has been executed in the mapping database, it +is expected that all involved page tables are updated. As such, all +deletions or partly invalidations of nodes must be followed up by page +table modification in their associated tasks. An architecture +specific function, \texttt{pg\_flush()}, exists for this purpose. +When a node is deleted or marked invalid, the mapping database invokes +the function specifying the address space and the page frame affected. +It is up to the \texttt{pg\_flush()} function to ensure that the +appropriate page table entries are updated, and that any required TLB +flush operations are executed. + +When invalidating root nodes or deleting mapping trees beneath root +nodes, counters within the dual-node of the root node array are +updated. These counters are used for cleaning up data structures in +the mapping database. If all root nodes within a root node array are +found to be empty, the root node array will be deleted. If all root +nodes within a root node array are found to be invalid, the root node +array, the mapping node associated with the root node array, and the +whole subtree below the mapping node are deleted. + + +\subsection{Mapping Database Memory Management} + +The mapping database is itself responsible for allocating the fine +grained buffers used for the different mapping database structures. +The size of these fine grained buffers depends on the hardware +architecture used. In particular, they depend on the size of the root +node arrays used, and the size of the mapping node structures. The +ARM architecture will for instance need to support root node arrays +for 64~KB pages, 4~KB pages, and perhaps 1~KB pages. The x86 +architecture, on the other hand, will only need to support root node +arrays for 4~KB pages. + +\begin{figure}[tbp] + \begin{center} + \includegraphics{fig/figure.1} + \caption{Memory management in mapping database} + \label{fig:mdb-mem} + \end{center} +\end{figure} + +Each of the different buffer sizes have an associated list of page +frames (usually of 4~KB size) containing free buffers. The first few +bytes of each of these page frames are dedicated to management +structures. The rest of the frames contain the buffers proper (see +Figure~\ref{fig:mdb-mem}). The management structure is used to keep +track of free buffers in the frame. It contains: a pointer pointing +to a list of free buffers, a counter keeping track of the number of +free buffers, and a pointer to the next frame of free buffers. + +When a buffer is allocated from a frame, the buffer is removed from +the list of free buffers, and the counter for the number of free +buffers is decremented. If the counter reaches zero, the whole frame +is removed from the frame list. This avoids further accesses to the +frame when a new buffer is to be allocated. + +When a buffer is de-allocated, it is hooked into the buffer list of +the frame it belongs to, and the counter of free buffers is +incremented. If the new counter value equals to one, it indicates +that all the buffers in the frame was previously allocated. This in +turn implies that the page frame has been removed from the frame list. +As such, we will have to hook it into the frame list +again.\footnote{We may also choose to hook the frame into the frame + list when the counter reaches some higher value. This will prohibit + the next allocate buffer operation to empty the buffer list and + remove the frame from the frame list. Using such a scheme, there + will be less insertion/removal operations on the frame list.}\@ If +the new counter value reaches its maximum (determined by the buffer +size), it indicates that all the buffers in the frame have been freed. +The frame may then be handed back to the kernel memory allocator, or +it may be moved to the back of the frame list to make the frame less +likely to be allocated from in the future. This latter option is +useful if we want to free the frame at some later stage. + +A buffer list can only contain equally sized buffers. The kernel +programmer must therefore specify the valid buffer sizes for a given +architecture. This is achieved by declaring an architecture specific +array, \texttt{mdb\_buflists}, listing all valid buffer sizes. The +declaration for the x86 architecture would for instance look like the +following: + +{\small +\begin{verbatim} + mdb_buflist_t mdb_buflists[4] = { + { 12 }, // Mapping nodes, dualnode_t + { 4096 }, // 4KB root node arrays + { 0 } + }; +\end{verbatim} +} + +The \texttt{mdb\_buflist\_t} structure contains all valid pointers and +counters for manipulating frame lists. When declaring the structures, +however, only the first field of them (the size field) is set. The +rest of the fields are set during initialization. A zero size buffer +size is used as a termination criterion for the list. + +If the mapping database attempts to allocate a non-valid buffer size, +a kernel panic will be raised. Moreover, a buffer size which is +greater or equal to the frame size can not be structured as lists +within frames. Requests for such buffers are therefore simply +forwarded to the kernel memory allocator. They still need to be +declared in the \texttt{mdb\_buflists} array though. + + + +\section{Kernel Debugger} + + + + +\chapter{Architecture Specific Issues} + +\section{Intel x86} + +\section{ARM/StrongARM} + + + +\end{document} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/doc/design/fig/esk.mp b/doc/design/fig/esk.mp new file mode 100644 index 0000000..e100091 --- /dev/null +++ b/doc/design/fig/esk.mp @@ -0,0 +1,539 @@ +%%% +%% +%% Alignment macros +%% +%%% + +%% +%% Align all boxes horizontally along their centers +%% +vardef halign@#(suffix first)(text tt) = + if str @# = "": + ypart(first.c- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.c) + else: + $.c) = ypart($.c- + fi + endfor + else: + ypart(first.@#- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.@#) + else: + $.@#) = ypart($.@#- + fi + endfor + fi + = 0; +enddef; + +%% +%% Align all boxes vertically along their centers +%% +vardef valign@#(suffix first)(text tt) = + if str @# = "": + xpart(first.c- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.c) + else: + $.c) = xpart($.c- + fi + endfor + else: + xpart(first.@#- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.@#) + else: + $.@#) = xpart($.@#- + fi + endfor + fi + = 0; +enddef; + + +%%% +%% +%% Sizing macros +%% +%%% + +%% +%% Set x-size of all boxes to be equal. May be used as lvalue. +%% +def eqxsize(suffix first)(text tt) = + xpart(first.e-first.w) + forsuffixes $=tt: = xpart($.e-$w) endfor +enddef; + +%% +%% Set y-size of all boxes to be equal. May be used as lvalue. +%% +def eqysize(suffix first)(text tt) = + ypart(first.n-first.s) + forsuffixes $=tt: = ypart($.n-$s) endfor +enddef; + +%% +%% Set x-size and y-size of all boxes equal. May be used as lvalue. +%% using a pair. +%% +def eqsize(suffix first)(text tt) = + (xpart(first.w-first.e), ypart(first.n-first.s)) + forsuffixes $=tt: = (xpart($.w-$e), ypart($.n-$s)) endfor +enddef; + + +%%% +%% +%% Suffix macros +%% +%%% + +%% +%% Return last suffix in list. +%% +vardef lastsuffix(text tt) = + save _i,_j; + _i := _j := 0; + forsuffixes $=tt: _i:=_i+1; endfor; + forsuffixes $=tt: + if incr _j = _i: $ fi + endfor +enddef; + +%% +%% Return true if suffix `ss' is the last suffix in `tt'. +%% +vardef islastsuffix(suffix ss)(text tt) = + save _st,_r; string _st; boolean _r; + _r := false; + forsuffixes $=tt: _st := str $; endfor; + if str ss = _st: _r := true; fi + _r +enddef; + + +%%% +%% +%% Spacing macros +%% +%%% + +%% +%% Set the x-spacing between all boxes to be equal. May be used as lvalue. +%% +def xspace(suffix first)(text tt) = + -xpart(first.e- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.w) + else: + $.w) = -xpart($.e- + fi + endfor +enddef; + +%% +%% Set the y-spacing between all boxes to be equal. May be used as lvalue. +%% +def yspace(suffix first)(text tt) = + -ypart(first.n- + forsuffixes $=tt: + if islastsuffix($)(tt): + $.s) + else: + $.s) = -ypart($.n- + fi + endfor +enddef; + + +%%% +%% +%% Dropshadow +%% +%%% +pair shadowoff; +shadowoff = (2pt,-2pt); + +%input mpattern; +% +%beginpattern(shadow_pattern); +% u:=.3mm; +% fill unitsquare scaled u; +% fill unitsquare scaled u shifted (u,u); +% patternbbox(0,0,2u,2u); +%endpattern; + +%% +%% Dropshadow on a list of boxes +%% +vardef dropshadow(text t) = + fixsize(t); fixpos(t); + forsuffixes s=t: + drawshadow bpath.s; + endfor; + forsuffixes s=t: + unfill bpath.s; + endfor; +enddef; + +%% +%% Dropshadow on a single path +%% +vardef drawshadow expr p = + fill p shifted shadowoff withcolor .4white; +% fill p shifted shadowoff withpattern shadow_pattern; + unfill p; +enddef; + + +%%% +%% +%% Picture maker +%% +%%% +pair mkpicoff, mkpicoff.c; +pair mkpicoff.nw, mkpicoff.w, mkpicoff.sw, mkpicoff.s; +pair mkpicoff.se, mkpicoff.e, mkpicoff.ne, mkpicoff.n; +mkpicoff := (-.5,.5); mkpicoff.c := (-.5,.5); +mkpicoff.nw := (0,0); mkpicoff.w := (0,.5); +mkpicoff.sw := (0,1); mkpicoff.s := (.5,1); +mkpicoff.se := (1,1); mkpicoff.e := (1,.5); +mkpicoff.ne := (1,0); mkpicoff.n := (.5,0); + +%% +%% Make picture with a specified size. First argument (if present) +%% after picture will be the xsize (may be set to 0 to keep size). +%% Next argument (if present) will be ysize. An alignment position +%% may be given as suffix to the function (nw,w,sw,s,se,e,ne,n,c). If +%% no suffix is given, `c' will be assumed. If a pair is given as an +%% argument, it will be used as on offset of the picture within the +%% new picture (relative to the alignment). +%% +vardef mkpic@#(expr inarg)(text tt) = + save ll,lr,ul,ur,off, inpic; + save outpic, st, xsz, ysz, oxsz, oysz, ?; + pair ll,lr,ul,ur,off; + picture outpic, inpic; + string st; + numeric xsz, ysz, oxsz, oysz; + boolean ?; + + inpic := if picture inarg: inarg + elseif string inarg: inarg infont defaultfont scaled defaultscale + else: nullpicture + fi; + outpic := inpic; + + xsz := oxsz := xpart(lrcorner inpic - llcorner inpic); + ysz := oysz := ypart(ulcorner inpic - llcorner inpic); + ? := false; + off := (0,0); + + %% Parse arguments + for ss=tt: + if numeric ss: + if ss <> 0: + if not ?: xsz := ss else: ysz := ss fi; + fi; + ? := true; + elseif pair ss: + off := ss; + fi; + endfor; + + ul := ulcorner inpic; + st := str @#; + + %% Adjust for x-position + if (st = "") or (st = "n") or (st = "c") or (st = "s"): + ul := ul + (-.5xsz + .5oxsz, 0); + elseif (st = "ne") or (st = "e") or (st = "se"): + ul := ul + (-xsz + oxsz, 0); + fi; + + %% Adjust for y-position + if (st = "") or (st = "w") or (st = "c") or (st = "e"): + ul := ul + (0, .5ysz - .5oysz); + elseif (st = "sw") or (st = "s") or (st = "se"): + ul := ul + (0, ysz - oysz); + fi; + + ul := ul + off; + ll := ul + (0,-ysz); + lr := ul + (xsz,-ysz); + ur := ul + (xsz,0); + + setbounds outpic to ll--lr--ur--ul--cycle; + outpic +enddef; + + +%%% +%% +%% Bus boxes +%% +%%% +if unknown defaultdx: + input boxes; +fi + +newinternal default_busarrlen, default_busarrdir; +default_busarrlen := 3bp; +default_busarrdir := 45; + +vardef hbusit@#(text tt) = + beginbox_("hbuspath_","sizebus_",@#,tt); + generic_declare(pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w; + 0 = xpart (@#nw-@#sw) = ypart(@#se-@#sw); + 0 = xpart(@#ne-@#se) = ypart(@#ne-@#nw); + @#w = .5[@#nw,@#sw]; + @#s = .5[@#sw,@#se]; + @#e = .5[@#ne,@#se]; + @#n = .5[@#ne,@#nw]; + @#ne-@#c = @#c-@#sw = (@#dx,@#dy) + .5*(urcorner pic_@# - llcorner pic_@#); + endbox_(clearb_,@#); +enddef; + +def hbuspath_(suffix $) = + $.w -- + ($.nw+(($.nw-$w)+(0,$.arrlen)) rotated -$.arrdir) -- + (xpart(($.nw+(($.nw-$w)+(0,$.arrlen)) rotated -$.arrdir)),ypart($.nw)) -- + (xpart(($.ne+(($.ne-$e)+(0,$.arrlen)) rotated $.arrdir)),ypart($.ne)) -- + ($.ne+(($.ne-$e)+(0,$.arrlen)) rotated $.arrdir) -- + $.e -- + ($.se-(($e-$.se)+(0,$.arrlen)) rotated -$.arrdir) -- + (xpart(($.se-(($e-$.se)+(0,$.arrlen)) rotated -$.arrdir)),ypart($.se)) -- + (xpart(($.sw-(($w-$.sw)+(0,$.arrlen)) rotated $.arrdir)),ypart($.sw)) -- + ($.sw-(($w-$.sw)+(0,$.arrlen)) rotated $.arrdir) -- + cycle +enddef; + +vardef vbusit@#(text tt) = + beginbox_("vbuspath_","sizebus_",@#,tt); + generic_declare(pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w; + 0 = xpart (@#nw-@#sw) = ypart(@#se-@#sw); + 0 = xpart(@#ne-@#se) = ypart(@#ne-@#nw); + @#w = .5[@#nw,@#sw]; + @#s = .5[@#sw,@#se]; + @#e = .5[@#ne,@#se]; + @#n = .5[@#ne,@#nw]; + @#ne-@#c = @#c-@#sw = (@#dx,@#dy) + .5*(urcorner pic_@# - llcorner pic_@#); + endbox_(clearb_,@#); +enddef; + +def vbuspath_(suffix $) = + $.n -- + ($.ne+(($.ne-$n)+($.arrlen,0)) rotated -$.arrdir) -- + (xpart($.ne),ypart($.ne+(($.ne-$n)+($.arrlen,0)) rotated -$.arrdir))-- + (xpart($.se),ypart($.se+(($.se-$s)+($.arrlen,0)) rotated $.arrdir)) -- + ($.se+(($.se-$s)+($.arrlen,0)) rotated $.arrdir) -- + $.s -- + ($.sw-(($.s-$sw)+($.arrlen,0)) rotated -$.arrdir) -- + (xpart($.sw),ypart($.sw-(($.s-$sw)+($.arrlen,0)) rotated -$.arrdir)) -- + (xpart($.nw),ypart($.nw-(($.n-$nw)+($.arrlen,0)) rotated $.arrdir)) -- + ($.nw-(($.n-$nw)+($.arrlen,0)) rotated $.arrdir) -- + cycle +enddef; + +def sizebus_(suffix $) = + if unknown $.dx: $.dx=defaultdx; fi + if unknown $.dy: $.dy=defaultdy; fi + if unknown $.arrlen: $.arrlen=default_busarrlen; fi + if unknown $.arrdir: $.arrdir=default_busarrdir; fi +enddef; + + +%%% +%% +%% Dsik box +%% +%%% +if unknown defaultdx: + input boxes; +fi + +newinternal default_busarrlen, default_busarrdir; +default_diskarcdepth := 3bp; + + +vardef diskit@#(text tt) = + beginbox_("diskpath_","sizedisk_",@#,tt); + generic_declare(pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w; + 0 = xpart (@#nw-@#sw) = ypart(@#se-@#sw); + 0 = xpart(@#ne-@#se) = ypart(@#ne-@#nw); + @#w = .5[@#nw,@#sw]; + @#s = .5[@#sw,@#se]; + @#e = .5[@#ne,@#se]; + @#n = .5[@#ne,@#nw]; + @#ne-@#c = @#c-@#sw = (@#dx,@#dy) + .5*(urcorner pic_@# - llcorner pic_@#); + endbox_(clearb_,@#); +enddef; + +def diskpath_(suffix $) = + $.sw .. $.s-(0,$.ad) .. $.se -- + $.ne .. $.n+(0,$.ad) .. $.nw -- $.w -- + $.nw .. $.n-(0,$.ad) .. $.ne -- $.e -- + $.ne .. $.n+(0,$.ad) .. $.nw -- + cycle +enddef; + +def sizedisk_(suffix $) = + if unknown $.dx: $.dx=defaultdx; fi + if unknown $.dy: $.dy=defaultdy; fi + if unknown $.ad: $.ad=default_diskarcdepth; fi +enddef; + + + + +%%% +%% +%% Creating circles and boxes as pictures. +%% +%%% + +%% +%% Create circle containing the picture (and optionally filled) +%% +vardef circlepic(text tt) = + save inpic,outpic; picture inpic,outpic; + save bound; path bound; + save colp, argp; boolean colp, argp; + save fillcol; color fillcolor; + save xsz, ysz; + colp := argp := false; + + for ss=tt: + if not argp: + inpic := if picture ss: ss + elseif string ss: ss infont defaultfont scaled defaultscale + else: nullpicture + fi; + argp := true; + elseif color ss: + colp := true; + fillcolor := ss; + fi; + endfor; + + xsz := xpart(lrcorner inpic - llcorner inpic); + ysz := ypart(ulcorner inpic - llcorner inpic); + + bound := fullcircle + xscaled ((xsz++ysz)+defaultdx) yscaled ((xsz++ysz)+defaultdy) + shifted (.5(xsz,ysz) + llcorner inpic); + + outpic := nullpicture; + if colp: addto outpic contour bound withcolor fillcolor; fi; + addto outpic also inpic; + addto outpic doublepath bound; + outpic +enddef; + +%% +%% Create rectangle containing the picture (and optionally filled) +%% +vardef boxpic(text tt) = + save inpic,outpic; picture inpic,outpic; + save bound; path bound; + save colp, argp; boolean colp, argp; + save fillcol; color fillcolor; + colp := argp := false; + + for ss=tt: + if not argp: + inpic := if picture ss: ss + elseif string ss: ss infont defaultfont scaled defaultscale + else: nullpicture + fi; + argp := true; + elseif color ss: + colp := true; + fillcolor := ss; + fi; + endfor; + + bound := (lrcorner inpic + (defaultdx,-defaultdy)) -- + (llcorner inpic + (-defaultdx,-defaultdy)) -- + (ulcorner inpic + (-defaultdx,defaultdy)) -- + (urcorner inpic + (defaultdx,defaultdy)) -- cycle; + + outpic := nullpicture; + if colp: addto outpic contour bound withcolor fillcolor; fi; + addto outpic also inpic; + addto outpic doublepath bound; + outpic +enddef; + + + +%%% +%% +%% Misc macros. +%% +%%% + +%% +%% Fill all boxes using the given specification `w'. +%% +vardef fillall(text t)(text w) = + fixsize(t); fixpos(t); + forsuffixes s=t: + fill bpath.s w; + endfor; +enddef; + + +%% +%% Magnifying glass +%% +vardef magnify(expr magpos, magfact, magsize) = + save magpic; picture magpic; + magpic := currentpicture; + + clip magpic to fullcircle scaled magsize shifted magpos; + unfill fullcircle scaled (magsize*magfact) shifted magpos; + draw magpic shifted -magpos scaled magfact shifted magpos; + draw fullcircle scaled (magsize*magfact) shifted magpos; +enddef; + + +newinternal termlength; +termlength := 3; + +%% +%% Draw expression with a terminating end (i.e. ``----|'') +%% +def drawterm expr p = + draw (-(.5termlength,0)--(.5termlength,0)) + rotated (angle(direction infinity of p)+90) + shifted point infinity of p; + draw p; +enddef; + + +vardef midcutting(suffix ss) = + save ce, no, so, i, cw, ch, nc; + ce := .5xpart(ss.w+ss.e); + no := ypart(ss.n); so := ypart(ss.s); + cw := 5bp; ch := 5bp; + nc := 4; + + ss.nw--(ce-.5nc*cw-.25cw,no)-- + for i=-.5nc step 1 until .5nc-1: + (ce+cw*i,no+.5ch)--(ce+cw*i+.5cw,no-.5ch)-- + endfor + (ce+.5nc*cw-.25cw,no)--ss.ne--ss.se--(ce+.5nc*cw-.25cw,so)-- + for i=.5nc-.5 step -1 until -.5nc: + (ce+cw*i,so-.5ch)--(ce+cw*i-.5cw,so+.5ch)-- + endfor + (ce-.5nc*cw-.25cw,so)--ss.sw--cycle +enddef; diff --git a/doc/design/fig/figure.mp b/doc/design/fig/figure.mp new file mode 100644 index 0000000..46eb575 --- /dev/null +++ b/doc/design/fig/figure.mp @@ -0,0 +1,570 @@ +input rboxes; +input graph; +input esk; + +%prologues:=1; + +vardef dcuta(suffix a,b) expr p = + drawarrow p cutbefore bpath.a cutafter bpath.b; +enddef; + +vardef cuta(suffix a,b) expr p = + drawarrow p cutbefore bpath.a cutafter bpath.b; + point .5*length p of p +enddef; + + + +%% +%% Mapping DB memory allocator +%% +beginfig(1); + u := 3mm; + + circleit.b1(btex $b$ etex); + circleit.b2(btex $b$ etex); + circleit.b3(btex $b$ etex); + circleit.b4(btex $b$ etex); + circleit.b5(btex $b$ etex); + circleit.b6(btex $b$ etex); + circleit.b7(btex $b$ etex); + boxit.pfl1(btex \vbox{\hbox{freelist ptr.} + \hbox{num free = 7}}etex); + boxit.fr1(btex etex); + + circleit.c1(btex $b$ etex); + circleit.c2(btex $b$ etex); + circleit.c3(btex $b$ etex); + boxit.pfl2(btex \vbox{\hbox{freelist ptr.} + \hbox{num free = 3}} etex); + boxit.fr2(btex etex); + eqsize(fr1,fr2); + + boxit.ptr(btex list-list pointer etex); + + eqsize(b1,b2,b3,b4,b5,b6,b7,c1,c2,c3); + halign(pfl1,b1,b2,b3,b4,b5,b6,b7); + halign(pfl2,c1,c2,c3); + xspace(pfl1,b1,b2,b3,b4,b5,b6,b7) = xspace(pfl2,c1,c2,c3) = u; + + xpart(pfl1.w-fr1.w) = ypart(fr1.n-pfl1.n) = ypart(pfl1.s-fr1.s) = + xpart(pfl2.w-fr2.w) = ypart(fr2.n-pfl2.n) = u; + xpart(fr1.e-b7.e) = 2u; + valign.e(fr1,fr2); + + yspace(fr2,fr1) = 2u; + ptr.c = pfl1.n + (-3u,5u); + + fixsize(pfl1,pfl2,ptr,b1,b2,b3,b4,b5,b6,b7,c1,c2,c3,fr1,fr2); + dropshadow(fr1,fr2); + drawunboxed(pfl1,pfl2,ptr); + drawboxed(b1,b2,b3,b4,b5,b6,b7,c1,c2,c3,fr1,fr2); + + dcuta(pfl1,b1) pfl1.c{dir80}..{dir300}b1.c; + dcuta(b1,b2) b1.c{up}..{down}b2.c; + dcuta(b2,b3) b2.c{up}..{down}b3.c; + dcuta(b3,b4) b3.c{up}..{down}b4.c; + dcuta(b4,b5) b4.c{up}..{down}b5.c; + dcuta(b5,b6) b5.c{up}..{down}b6.c; + dcuta(b6,b7) b6.c{up}..{down}b7.c; + drawterm (b7.c{up}..b7.c+(2u,.7u)) cutbefore bpath.b7; + + dcuta(pfl2,c1) pfl2.c{dir80}..{dir300}c1.c; + dcuta(c1,c2) c1.c{up}..{down}c2.c; + dcuta(c2,c3) c2.c{up}..{down}c3.c; + drawterm (c3.c{up}..c3.c+(2u,.7u)) cutbefore bpath.c3; + + dcuta(ptr,fr1) ptr.c{right}..{down}pfl1.c; + dcuta(fr1,fr2) pfl1.c..pfl2.c; + drawterm (pfl2.c{down}..{dir320}pfl2.c+(1.3u,ypart(fr2.n-pfl1.c))) + cutbefore bpath.fr2; + + numeric k; + k = xpart(.5[pfl1.e,b1.w]); + draw (k,ypart(fr1.n))--(k,ypart(fr1.s)) dashed evenly; + draw (k,ypart(fr2.n))--(k,ypart(fr2.s)) dashed evenly; + + label.ulft(btex \it 4KB frame etex scaled .6, fr1.se); + label.ulft(btex \it 4KB frame etex scaled .6, fr2.se); +endfig; + + +vardef largeroots@# = + boxit.@#0(btex $R^{0}_{4k}$ etex scaled .8); + boxit.@#1(btex $R^{1}_{4k}$ etex scaled .8); + boxit.@#2(btex $R^{2}_{4k}$ etex scaled .8); + boxit.@#14(btex $R^{14}_{4k}$ etex scaled .8); + boxit.@#15(btex $R^{15}_{4k}$ etex scaled .8); + eqsize(@#0,@#1,@#2,@#14,@#15); + halign(@#0,@#1,@#2,@#14,@#15); + xspace(@#0,@#1,@#2) = xspace(@#14,@#15) = 0; xspace(@#2,@#14) = 4u; + ypart(@#15.n-@#15.s) = xpart(@#15.e-@#15.w); +enddef; + +vardef smallroots@# = + boxit.@#0(btex $R^{0}_{1k}$ etex scaled .8); + boxit.@#1(btex $R^{1}_{1k}$ etex scaled .8); + boxit.@#2(btex $R^{2}_{1k}$ etex scaled .8); + boxit.@#3(btex $R^{3}_{1k}$ etex scaled .8); + eqsize(@#0,@#1,@#2,@#3); + halign(@#0,@#1,@#2,@#3); + xspace(@#0,@#1,@#2,@#3) = 0; +enddef; + + +%% +%% Complex mapoping tree +%% +beginfig(2); + u := 3mm; + dl := 3u; + + circleit.nA(btex A etex); + circleit.nB(btex B etex); + circleit.nC(btex C etex); + circleit.nD(btex D etex); + circleit.nE(btex E etex); + circleit.nF(btex F etex); + circleit.nG(btex G etex); + circleit.nH(btex H etex); + circleit.nI(btex I etex); + eqsize(nA,nB,nC,nD,nE,nF,nG,nH,nI); + + %% Top array + boxit.r1(btex $R^1_{64k}$ etex); + boxit.r2(btex $R^2_{64k}$ etex); + eqxsize(r1,r2) = eqysize(r1,r2); + halign(r1,r2); + xspace(r1,r2) = 0; + + %% Root arrays + largeroots.ra; + largeroots.re; + smallroots.rf; + + % Locate A, C, D + valign(r2,nA,nC,nD); + yspace(nF,nD,nC,nA,r2) = dl; + + % Locate A's array, C, E + halign(ra0,nC,nE); + xspace(ra15,nC,nE) = 3u; + + % Locate B + valign(nB,ra0); + halign(nB,nD); + + % Locate E's array, nF, nI + valign(re0,nE,nF); + halign(nD,re0); + halign(nF,nI); + valign(nI,re15); + + % Locate F's array + valign(rf0,nF); + yspace(rf0,nF) = dl; + + % Locate G, H + halign(nG,nH); + valign(nG,rf0); valign(nH,rf1); + yspace(nG,rf0) = dl; + + fixsize(nA,r1,ra0); + drawboxed(r1,r2,ra0,ra1,ra2,ra14,ra15); + drawboxed(nA,nB,nC,nD,nE); + drawboxed(re0,re1,re2,re14,re15); + drawboxed(nF,nI,rf0,rf1,rf2,rf3,nG,nH); + + dcuta(r2,nA) r2.c -- nA.c; + dcuta(nA,ra15) nA.c{left} .. ra15.c; + dcuta(ra0,nB) ra0.c -- nB.c; + dcuta(nA,nC) nA.c -- nC.c; + dcuta(nC,nD) nC.c -- nD.c; + dcuta(nA,nE) nA.c{right} .. nE.c; + dcuta(nE,re0) nE.c -- re0.c; + dcuta(re0,nF) re0.c -- nF.c; + dcuta(re15,nI) re15.c -- nI.c; + dcuta(nF,rf0) nF.c -- rf0.c; + dcuta(rf0,nG) rf0.c -- nG.c; + dcuta(rf1,nH) rf1.c -- nH.c; + + draw r1.nw -- r1.nw - (2u,0) dashed evenly; + draw r1.sw -- r1.sw - (3.5u,0) dashed evenly; + draw r2.ne -- r2.ne + (1.7u,0) dashed evenly; + draw r2.se -- r2.se + (2.7u,0) dashed evenly; + draw ra2.ne -- ra14.nw dashed evenly; + draw ra2.se -- ra14.sw dashed evenly; + draw re2.ne -- re14.nw dashed evenly; + draw re2.se -- re14.sw dashed evenly; +endfig; + +color partlyInvalid; +color completelyInvalid; + +partlyInvalid = .85white; +completelyInvalid = .65white; + + +%% +%% Complex mapping tree, 4KB flushed +%% +beginfig(3); + u := 3mm; + dl := 3u; + + circleit.nA(btex A etex); + circleit.nC(btex C etex); + circleit.nD(btex D etex); + circleit.nE(btex E etex); + circleit.nI(btex I etex); + eqsize(nA,nC,nD,nE,nI); + + %% Top array + boxit.r1(btex $R^1_{64k}$ etex); + boxit.r2(btex $R^2_{64k}$ etex); + eqxsize(r1,r2) = eqysize(r1,r2); + halign(r1,r2); + xspace(r1,r2) = 0; + + %% Root arrays + largeroots.ra; + largeroots.rc; + largeroots.rd; + largeroots.re; + + % Locate A, C, D + valign(r2,nA,nC,nD); + yspace(nE,nA,r2) = dl; + halign(nC,re0); + yspace(nD,nC) = dl; + + % Locate A's array, C, E + halign(ra0,nE); + xspace(ra15,nC,nE) = 3u; + + % Locate C's array, D's array, E's array, nI + valign(re0,nE); + valign(nI,re15); + yspace(nI,re0,nE) = dl; + valign(rc0,ra0); + halign(nD,rc0); + yspace(rd0,nD) = dl; + valign(rd0,nD); + + fixsize(nA,r1,ra0,rc0,rd0,re0); + fillall(nA,nC,nD,nE)(withcolor partlyInvalid); + fillall(ra0,rc0,rd0,re0)(withcolor completelyInvalid); + drawboxed(r1,r2,ra0,ra1,ra2,ra14,ra15); + drawboxed(nA,nC,nD,nE); + drawboxed(re0,re1,re2,re14,re15,nI); + drawboxed(rc0,rc1,rc2,rc14,rc15); + drawboxed(rd0,rd1,rd2,rd14,rd15); + + dcuta(r2,nA) r2.c -- nA.c; + dcuta(nA,ra15) nA.c{left} .. ra15.c; + dcuta(nA,nC) nA.c -- nC.c; + dcuta(nC,rc15) nC.c{left} .. rc15.c; + dcuta(nC,nD) nC.c -- nD.c; + dcuta(nD,rd0) nD.c -- rd0.c; + dcuta(nA,nE) nA.c{right} .. nE.c; + dcuta(nE,re0) nE.c -- re0.c; + dcuta(re15,nI) re15.c -- nI.c; + + draw r1.nw -- r1.nw - (2u,0) dashed evenly; + draw r1.sw -- r1.sw - (3.5u,0) dashed evenly; + draw r2.ne -- r2.ne + (1.7u,0) dashed evenly; + draw r2.se -- r2.se + (2.7u,0) dashed evenly; + draw ra2.ne -- ra14.nw dashed evenly; draw ra2.se -- ra14.sw dashed evenly; + draw rc2.ne -- rc14.nw dashed evenly; draw rc2.se -- rc14.sw dashed evenly; + draw rd2.ne -- rd14.nw dashed evenly; draw rd2.se -- rd14.sw dashed evenly; + draw re2.ne -- re14.nw dashed evenly; draw re2.se -- re14.sw dashed evenly; + + draw ra0.nw--ra0.se; draw ra0.sw--ra0.ne; + draw rc0.nw--rc0.se; draw rc0.sw--rc0.ne; + draw rd0.nw--rd0.se; draw rd0.sw--rd0.ne; + draw re0.nw--re0.se; draw re0.sw--re0.ne; +endfig; + + + +%% +%% Complex mapping tree, 1KB flushed +%% +beginfig(4); + u := 3mm; + dl := 3u; + + circleit.nA(btex A etex); + circleit.nB(btex B etex); + circleit.nC(btex C etex); + circleit.nD(btex D etex); + circleit.nE(btex E etex); + circleit.nF(btex F etex); + circleit.nH(btex H etex); + circleit.nI(btex I etex); + eqsize(nA,nC,nD,nE,nI); + + %% Top array + boxit.r1(btex $R^1_{64k}$ etex); + boxit.r2(btex $R^2_{64k}$ etex); + eqxsize(r1,r2) = eqysize(r1,r2); + halign(r1,r2); + xspace(r1,r2) = 0; + + %% Root arrays + largeroots.ra; + smallroots.rrb; + largeroots.rc; + smallroots.rrc; + largeroots.rd; + smallroots.rrd; + largeroots.re; + smallroots.rrf; + + % Locate A, A's array, B, E + valign(r2,nA); + yspace(nB,nE,nA,r2) = dl; + xspace(ra15,nA,nE) = 3u; + valign(ra0,nB); + halign(ra0,nE); + + % Locate E's array, nF, nI + valign(re0,nE); + halign(re0,nB); + valign(nI,re15); valign(nF,re0); + yspace(nF,nB) = dl; halign(nF,nI); + + % Locate B's array, C + halign(rrb0,nF,nC); + valign(rrb0,nB); + valign(nC,nA); + + % Locate F's array, H + valign(rrf0,nF); + valign(rrf1,nH); + yspace(nH,rrf0,nF) = dl; + + % Locate C'a arrays + halign(rc0,rrf0); + halign(rrc0,nH); + valign(rrc0,rc0,rrb0); + + % Locate D, D's arrays + halign(nD,nH); + valign(rrd0,rd0,nD,nC); + yspace(rrd0,rd0,nD) = dl; + + + fixsize(nA,r1,ra0,rc0,rd0,re0); + fillall(nA,nB,nC,nE,nF,re0,ra0)(withcolor partlyInvalid); + drawboxed(r1,r2,ra0,ra1,ra2,ra14,ra15) + drawboxed(nA,nB,nC,nE,nF,nI); + drawboxed(re0,re1,re2,re14,re15); + fillall(rrb0,rrf0)(withcolor completelyInvalid); + drawboxed(rrb0,rrb1,rrb2,rrb3); + drawboxed(rrf0,rrf1,rrf2,rrf3,nH); + fillall(rrc0,rrd0)(withcolor completelyInvalid); + fillall(nD,rc0,rd0)(withcolor partlyInvalid); + drawboxed(rc0,rc1,rc2,rc14,rc15,rrc0,rrc1,rrc2,rrc3); + drawboxed(nD,rd0,rd1,rd2,rd14,rd15,rrd0,rrd1,rrd2,rrd3); + + dcuta(r2,nA) r2.c -- nA.c; + dcuta(nA,ra15) nA.c{left} .. ra15.c; + dcuta(ra0,nB) ra0.c -- nB.c; + dcuta(nB,rrb0) nB.c -- rrb0.c; + dcuta(nA,nC) nA.c -- nC.c; + dcuta(nC,rc15) nC.c{left} .. rc15.c; + dcuta(rc0,rrc0) rc0.c -- rrc0.c; + dcuta(nC,nD) nC.c -- nD.c; + dcuta(nD,rd0) nD.c -- rd0.c; + dcuta(rd0,rrd0) rd0.c -- rrd0.c; + dcuta(nA,nE) nA.c{right} .. nE.c; + dcuta(nE,re0) nE.c -- re0.c; + dcuta(re15,nI) re15.c -- nI.c; + dcuta(re0,nF) re0.c -- nF.c; + dcuta(nF,rrf0) nF.c -- rrf0.c; + dcuta(rrf1,nH) rrf1.c -- nH.c; + + draw r1.nw -- r1.nw - (2u,0) dashed evenly; + draw r1.sw -- r1.sw - (3.5u,0) dashed evenly; + draw r2.ne -- r2.ne + (1.7u,0) dashed evenly; + draw r2.se -- r2.se + (2.7u,0) dashed evenly; + draw ra2.ne -- ra14.nw dashed evenly; draw ra2.se -- ra14.sw dashed evenly; + draw rc2.ne -- rc14.nw dashed evenly; draw rc2.se -- rc14.sw dashed evenly; + draw rd2.ne -- rd14.nw dashed evenly; draw rd2.se -- rd14.sw dashed evenly; + draw re2.ne -- re14.nw dashed evenly; draw re2.se -- re14.sw dashed evenly; + + draw rrb0.nw--rrb0.se; draw rrb0.sw--rrb0.ne; + draw rrc0.nw--rrc0.se; draw rrc0.sw--rrc0.ne; + draw rrd0.nw--rrd0.se; draw rrd0.sw--rrd0.ne; + draw rrf0.nw--rrf0.se; draw rrf0.sw--rrf0.ne; +endfig; + + +%% +%% Maptree, logical +%% +beginfig(5) + u := 3mm; + + circleit.A(btex A etex); + circleit.B(btex B etex); + circleit.C(btex C etex); + circleit.D(btex D etex); + circleit.E(btex E etex); + eqsize(A,B,C,D,E); + + halign(B,E); + halign(C,D); + yspace(C,B,A) = 2.3u; + xspace(C,D) = xspace(B,E) = 2u; + xpart(.5[B.c,E.c]) = xpart(A.c); + xpart(.5[C.c,D.c]) = xpart(B.c); + + drawboxed(A,B,C,D,E); + undraw C.w-(u,0) -- C.w-(4u,0); % Extend picture leftwards + undraw E.e+(u,0) -- E.e+(4u,0); % Extend picture rightwards + + dcuta(A,B) A.c -- B.c; + dcuta(B,C) B.c -- C.c; + dcuta(B,D) B.c -- D.c; + dcuta(A,E) A.c -- E.c; + + label.lft(btex 0 etex scaled .7, A.w); + label.lft(btex 1 etex scaled .7, B.w); + label.lft(btex 2 etex scaled .7, C.w); + label.lft(btex 2 etex scaled .7, D.w); + label.lft(btex 1 etex scaled .7, E.w); +endfig; + + + +%% +%% Maptree, implementation +%% +beginfig(6) + u := 3mm; + + circleit.A(btex A etex); + circleit.B(btex B etex); + circleit.C(btex C etex); + circleit.D(btex D etex); + circleit.E(btex E etex); + eqsize(A,B,C,D,E); + + halign(A,B,C,D,E); + xspace(A,B,C,D,E) = 2u; + + drawboxed(A,B,C,D,E); + + dcuta(A,B) A.c{dir80} .. {dir280}B.c; + dcuta(B,C) B.c{dir80} .. {dir280}C.c; + dcuta(C,D) C.c{dir80} .. {dir280}D.c; + dcuta(D,E) D.c{dir80} .. {dir280}E.c; + drawterm (E.c{dir80} .. E.c+(3.2u,u)) cutbefore bpath.E; + + undraw C.s-(0,u) -- C.s-(0,3u); % Extend picture downwards + + label.bot(btex 0 etex scaled .7, A.s); + label.bot(btex 1 etex scaled .7, B.s); + label.bot(btex 2 etex scaled .7, C.s); + label.bot(btex 2 etex scaled .7, D.s); + label.bot(btex 1 etex scaled .7, E.s); +endfig; + + +%% +%% Thread states +%% +beginfig(7) + u := 5mm; + + circleit.run(btex \tt RUNNING etex); + circleit.poll(btex \tt POLLING etex); + circleit.wait(btex \tt WAITING etex); + circleit.lrun(btex \tt\vbox{\hbox{LOCKED-}\hbox{RUNNING}} etex); + circleit.lwait(btex \tt\vbox{\hbox{LOCKED-}\hbox{WAITING}} etex); + + eqsize(run,poll,wait,lrun,lwait); + lwait.dx = lwait.dy = u; + + halign(poll,wait); + halign(lrun,lwait); + + yspace(lwait,wait) = 5u; + yspace(wait,run) = 3u; + xspace(wait,poll) = 10u; + xspace(lwait,lrun) = 8u; + xpart(.5[wait.c,poll.c]) = xpart(.5[lwait.c,lrun.c]) = xpart(run.c); + + fixsize(lwait); + drawboxed(run,poll,wait,lrun,lwait); + + label.urt(btex send etex, + cuta(run,poll) run.c{dir10} .. {dir260}poll.c); + label.llft(btex timeout etex, + cuta(poll,run) poll.c{dir100} .. {dir170}run.c); + + label.ulft(btex recv etex, + cuta(run,wait) run.c{dir170} .. {dir280}wait.c); + label.lrt(btex timeout etex, + cuta(wait,run) wait.c{dir80} .. {dir10}run.c); + + label.urt(btex \vbox{\hbox{receiver}\hbox{ready}} etex, + cuta(poll,lrun) poll.c{dir290} .. {dir250}lrun.c); + label.urt(btex \vbox{\hbox{sender}\hbox{ready}} etex, + cuta(wait,lwait) wait.c{dir250} .. {dir290}lwait.c); + + label.top(btex pf resolved etex, + cuta(lrun,lwait) lrun.c{dir130} .. {dir230}lwait.c); + label.top(btex resolve pf etex, + cuta(lwait,lrun) lwait.c{dir25} .. {dir335}lrun.c); + + label.bot(btex resolve pf etex, + cuta(lrun,lwait) lrun.c{dir205} .. {dir155}lwait.c); + label.bot(btex pf resolved etex, + cuta(lwait,lrun) lwait.c{dir310} .. {dir50}lrun.c); + + label.urt(btex IPC done etex, + cuta(lrun,run) lrun.c{dir30} .. {dir220}run.c); + label.ulft(btex IPC done etex, + cuta(lwait,run) lwait.c{dir150} .. {dir320}run.c); + + label.urt(btex recv etex, + cuta(lrun,wait) lrun.c{up} .. {left}wait.c); +endfig; + + +%% +%% Shadow page table +%% +beginfig(8) + U := 3mm; + + boxit.x1(btex $v_r$ etex); x1.dx = .1u; x1.dy = .3u; + boxit.x2(btex $v_s$ etex); + boxit.p1(); + boxit.p2(); + + eqysize(x1,x2,p1,p2); + eqxsize(x1,x2); + eqxsize(p1,p2) = 13u; + xspace(p1,p2) = 0; + halign(x1,x2,p1,p2); + xpart(p1.c-x1.c) = xpart(p2.c-x2.c) = 3u; + + dropshadow(p1,p2); + fillall(x1,x2)(withcolor .85white); + drawboxed(p1,p2,x1,x2); + + label.bot(btex Page Table etex, p1.s - (0,.5u)); + label.bot(btex Shadow Page Table etex, p2.s - (0,.5u)); + label.bot(btex $x$ etex scaled .8, p1.sw - (0,.2u)); + label.bot(btex $x+4096$ etex scaled .8, p2.sw - (0,.2u)); + label.bot(btex $x+8192$ etex scaled .8, p2.se - (0,.2u)); + + label.top(btex $\overbrace{\hskip65mm}^{addr(v_s)=addr(v_r)+4096}$ etex, + .5[x1.n,x2.n]); +endfig; + +end; diff --git a/doc/design/migration.txt b/doc/design/migration.txt new file mode 100644 index 0000000..67f6988 --- /dev/null +++ b/doc/design/migration.txt @@ -0,0 +1,32 @@ +Thread migration in L4/KA SMP + +Statement: Migrating ourselvs is not allowed +Reasoning: Usually, the per-cpu scheduler migrates threads around, but never itself. + +Temp: Only running threads are migrated + + +Notation: X:y/z - Thread X, cpu=y, ctrl_cpu=z + X:Y->z - Thread X migrates Thread Y to CPU z + deq(X) - dequeue Thread X from READY and PRESENT queue + enq(X) - enqueue Thread X into READY and PRESENT queue + + +CPU 0 1 2 3 + +A:0/0 deq(B) +B:0/0 ----IPI(B,1)----> +A:B->1 poll(0) cont(0) + enq(B) + + +A:0/0 ----IPI(B,0)----> +B:1/1 poll(0) deq(B) +A:B->0 enq(B) cont(0) + + +#if (we allow A on x to migrate B from y to z where x != y != z != x, A != B) +A:0/0 +B:1/1 Orneeedadenkschheutnimmerdrübernach! +A:B->2 +#endif diff --git a/doc/kernel-memory-layout b/doc/kernel-memory-layout new file mode 100644 index 0000000..96d3db8 --- /dev/null +++ b/doc/kernel-memory-layout @@ -0,0 +1,7 @@ +0x0000.0000 exception vector page + + +0xE000.0000 TCB array +0xF000.0000 RAM - mapped as a contiguous area - XXX: is this ok? +0xF800.0000 page directory array +0xF900.0000 kernel code/data/misc diff --git a/doc/report.html b/doc/report.html new file mode 100644 index 0000000..6a538a0 --- /dev/null +++ b/doc/report.html @@ -0,0 +1,345 @@ + + + + + + + + L4/KA - A diary + + + +

+Pending problems

+ +

+on a write, ARM reports a read pagefault first if no mapping was present +(u)

+ +
I fear, we have to do this evil code analysis thing on a translation +abort to figure out whether it was a read or a write access. +
Write accesses on read-only mapped pages are fine - these cause a permission +abort.
+ +

+L4/Linux enter_kdebugs "non linux task" (u)

+ +
The linux kernel received an IPC with no error code, but the +sender's thread_id was not valid. +
Non-solution: Some exits in sys_ipc returning an error code didn't +keep the dest_id as specified. +

Note: Not seen anymore since 2000-04-10.

+ +

+ +
2000-01-18

+ +

+IPC via sysenter/sysexit works (u)

+ +
We use a modified version of Jochen's proposal for the int +0x30 replacement +
The kernel esp is restored from the tss.esp0 location directly after +entering the kernel. This saves the expensive (serializing) wrmsr to update +the MSR_0x175.
+ +

+ +
2000-01-17

+ +

+First steps towards the sysenter/sysexit IPC mechanism

+ +
sysenter: MSR_0x174 -> cs; MSR_0x174 + 8 -> ss; MSR_0x175 +-> esp; MSR_0x176 -> eip +
The esp register is overwritten on sysenter, no return information +is saved implicitly. +
sysexit: MSR_0x174 + 16 -> cs; MSR_0x174 + 16 + 8 -> ss; ecx +-> esp; edx -> eip +
The registers ecx and edx must contain esp and eip and thus are not +free for use. +

The kernel esp (MSR_0x175) must be updated on every thread switch. +
Jochen proposes to store the return address on the user's stack and +to keep the user's esp in ecx.

+ +

+ +
2000-01-16

+ +

+An IPC with timeout NEVER returns with error code 0x20 (timeout) (u)

+ +
Problem: This happened due to not dequeueing threads from the +wakeup queue. We relied on the scheduler to dequeue threads from the wakeup +queue. But this holds only, if the timeout becomes active. In case of an +IPC happening before the timeout expiry, the thread remained in the wakeup +queue. +
Scenario: L4/Linux' bottom half thread does IPCs with timeout and with +timeout NEVER. If an IPC with a timeout succeeded before the timeout became +active, the thread remained in the wakeup queue. Later on, when the thread +did an IPC with timeout NEVER, the scheduler found the thread in the wakeup +queue with an expired timeout and activated the thread. The thread then +concluded, that it woke up due to a timeout and returned with an error +code indicating a receive timeout (0x20). +
Solution: put calls to thread_dequeue_wakeup wherever they're required
+ +

+L4/Linux enter_kdebugs "wrong access" after some l4_thread_ex_regs from +the signal thread (u)

+ +
Scenario: The signal thread changes the thread's IP to an endless +loop in the emulib. Then it installes a faked exception 20 and kicks the +thread to the exception handler ... which then returns to the thread. +
Problem: Sometimes the worker thread is in a pagefault IPC. L4/KA does +an unwind_ipc by kicking the thread back to user land, but with trashed +registers, but the worker thread doesn't know that its registers were trashed. +
Solution: unwind_ipc must not unwind the IPC by placing the thread +in userland. It must abort only the IPC operation (i.e., return to the +place where do_pagefault_ipc was called), which means that we have to save +more state information. :-( +

Would it be enough to save the last_ipc_ksp to the TCB and restore that +on an aborted IPC (if it was valid)? +
Late night note: Yes it is. Currently, a return-to-able stack frame +is created in do_pagefault_ipc and its location is stored in the TCB (unwind_ipc_sp).

+ +

+ +
2000-04-12

+ +

+l4_thread_schedule doesn't work in RMGR

+ +
sbd. cut the RMGR local c-binding for l4_thread_schedule short +
Having more than one set of syscall bindings is not really healthy!!!
+ +

+ +
2000-04-11

+ +

+L4/Linux spuriously enter_kdebugs "bh error"

+ +
Still looking for the reason of wait(..., IPC_NEVER) returning +with timeout
+ +

+ +
2000-04-10

+ +

+L4/Linux sometimes enter_kdebugs "wrong stack" when processes are killed

+ +
Scenario: An L4/Linux task is hit by a signal -> its signal +thread receives a message from the L4/Linux kernel. Then it does an lthread_ex_regs +on its worker thread (which might be in a pagefault (effectively in an +IPC which has to be aborted)). +
In unwind_ipc we called thread_dequeue_send(tcb,tcb) with exchanged +arguments. This led to a kernel pagefault by dereferencing a NULL pointer +(Maybe, we should add a check for that?), which was turned into an IPC +to the corresponding pager -> the L4/Linux kernel. To the L4/Linux kernel +this IPC looked like a syscall, but the signal thread must not do Linux +syscalls. Finally, the thread_id of the signal thread didn't match the +thread_id of the worker thread (stored in L4/Linux' TSS structure) -> L4/Linux +complains about the signal thread using the wrong stack (although there +is not even a proper stack for that thread anyway :-)
+ +

+ +
2000-01-xx

+ +

+???

+ +
...
+ +

+ +
2000-01-18

+ +

+total silence after thread switch

+ +
switching from one thread to another can happen in two ways: +

- switch inside the same address space +
- switch to a different address space +

later is the more interesting and complicated case. +
Following situation: +

Thread A, address space 1 switches to Thread B, address space 2 +

assume that the tcb of thread A is not mapped in address space 2. Thus, +a +
switch to AS2 *BEFORE* the stack is switched to thread B will cause +a +
pagefault on the stack of thread A (since it is not mapped in AS 2). +But the +
pagefault handler usually operates on the stack. Therefore, the system +hangs +
in an infinite pagefault loop. +

Solution: +
To switch from one address space to another, stacks must be switched +BEFORE +
the address space is switched. If a pagefault is raised in the destination +
AS on the source tcb, we already have a valid stack and can handle +the +
fault. +
(v)

+ +

+crazy unpredictable behavior when changing small sections in the code (x86)

+ +
probably, GRUB used the memory where the x86-kernel was loaded +for its own purpose, after the image was loaded +
short term solution: relocate .init section +
long term solution: sign your code and check signature before execution
+ +

+ +
2000-01-17

+ +

+???

+ +
...
+ +

+ +
2000-01-14

+ +

+???

+ +
...
+ +

+ +
2000-01-13

+ +

+TCB layout (v)

+ +
Fixed stack size removed
+ +

+ +
2000-01-12

+ +

+IPC (v)

+ +

+Scheduler fixed (v)

+ +

+Flush TLB + Cache (u)

+ +

+ARM Mode switching, used wrong SP (u)

+ +

+Code moved to another section doesn't work any more, but did fine before

+ +
First, even symbols from section .kdebug were placed +in the .text section during the link process. +
When I create a separate .kdebug section directly behind the +.text +section, the virtual address of that section is end(.kdebug), +as expected. +
I forgot to set the load address of that section, thus is was loaded +somewhere but not even near the .text section. (u)
+ +
+

+2000-01-11

+ +

+???

+ +
...
+ +

+ +
2000-01-10

+ +

+Cannot raise any exception at all on ARM

+ +
To raise an exception the exception vector must be mapped in +the current pagetable. Otherwise, the machine simply locks up. (u)
+ +

+Unplausible values

+ +
When stealing code, always rererererecheck the semantics of +type names!!! +
word_t(source system) != word_t(dest system) +
(u)
+ +

+ +

+ +

+2000-01-09

+ +

+Make compatibility

+ +
It appears, that make 3.78.1 works better than 3.77... The +older version seemed unable to include the Makeconf file, probably caused +by a parsing error. Things broke when I started using $(error ... ), I +guess. (u)
+ +

+When cpp goes crazy

+ +
like +
#define blah(x) \ +
{ \ +
  foo; \ +
} \ +
being preprocessed as +
{ +
  foo; +
} +
you might suffer from DOSified files. Emacs not showing ^M +doesn't tell you anything. +
Using cvs under NT with a working directory on a samba share and the +repository accessed via rsh does unix2dos and dos2unix translations when +checking in/out. Files in working directory contain ^M. +(u)
+ +

+x86-Pagetables

+ +
usermode pagedir entries must have the usermode bit set. (v)
+ +

+VMWare - accessing nonexistent phys mem -> pgfault

+ +
VMWare does not cleanly emulate pagetable entries to non-existing +memory. Instead of delivering "undefined" data VMWare raises a pagefault. +(v)
+ +

+VMWare uses parts of the virtual mem

+ +
VMWare does not allow full usage of memory beyond 0xFFFF0000. +VMWare stops with errors like "muli not emulated". It seems that memory +used above that point cannot hold stuff like gdt and idt. (v)
+ +

+TODO

+ +
    +
  • +arch/config.h contains KERNEL_PHYS. This should go into the linker scripts. +(u)
  • + +
  • +keep in mind: Could we make use of architecturally private TCB members? +(u)
  • +
+ +
+
  + + diff --git a/doc/sigma0-new.txt b/doc/sigma0-new.txt new file mode 100644 index 0000000..2dda9a3 --- /dev/null +++ b/doc/sigma0-new.txt @@ -0,0 +1,148 @@ + PROPOSAL FOR NEW SIGMA0 VERSION X.0 RPC PROTOCOL + +The sigma0 RPC protocol that is defined in the L4/x86 reference manual +is not really suited for architectures other than x86. As such, one +will have to define new versions of the protocol for almost every new +architecture that L4 is built for. This proposal tries to solve the +problem by having a protocol which is generic enough to suit all +architectures while still being compatible to older versions of the +protocol. In addition, the protocol enable pagers to give back memory +to sigma0. + +As usual, the bits in the specification that are tildes (~) are +undefined/have no meaning. The protocol itself uses three words for +communication: w0, w1, and w2. If the third word equals zero and +first word does not equal 0xfffffffc, the request is treated as a +pagefault RPC and is translated into the appropriate sigma0 protocol +message. + +As with the previous sigma0 RPC protocol, a page (other than the +kernel info page) can not be mapped to two different address spaces. +Requests that can not be carried out should reply with a 0-word in w0 +to the caller + +All fpages mapped/granted to the caller are assured to span a +physically contigous memory region, even when the caller requests for +an fpage located at an arbitrary position. + + +KERNEL COMMUNICATION + + + w0 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~11 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ssss ss~~ + + Grant an fpage to the kernel. Size is specified in w2. The + fpage might be located on an arbitrary position. If request + can not be fulfilled, a 0-word should be replied. + + + w0 0000 0000 0000 0000 0000 0000 0000 0001 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + Reply (in w0) which amount of memory in bytes that is + recommended for use by the kernel. + + + For compatibility with older versions of the sigma0 RPC protocol + the following message is also supported. + + w0 1111 1111 1111 1111 1111 1111 1111 1100 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + Grant an arbitrary 4K page to the kernel. + + +NON-KERNEL COMMUNICATION + + + w0 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~11 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ssss ss01 + + Map an fpage located on an arbitrary position back to the + caller. The size part of the fpage in w2 indicates the size + of the wanted fpage. If request can not be fulfilled, a + 0-word should be replied. + + + w0 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~11 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 pppp pppp pppp pppp pppp ~~~~ ssss ss11 + + Map the indicated fpage to the caller. If request can not be + fulfilled, a 0-word should be replied. + + + w0 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~11 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 pppp pppp pppp pppp pppp ~~~~ ssss ss10 + + Unmap the specified fpage from the caller's address space. + Pages within the fpage that are not owned by the caller should + not be unmapped. No reply is sent to the caller. + + + w0 0000 0000 0000 0000 0000 0000 0000 0001 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + Map the kernel info page to the caller. + + + For compatibility with the pageault protocol and older versions of + sigma0 RPC, the following messages are also supported. + + w0 1111 1111 1111 1111 1111 1111 1111 1100 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + Map an arbirary 4K page to the caller's address space. + + + w0 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aa00 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + On x86: If "`a' <= 1G", map indicated physical 4K frame to + caller. If "1G < `a' <= 3G", map inidacted 4M frame plus 1G + to the caller. + + On other architectures: Map the indicated physical frame to + the caller (with the preferred page size of the architecture). + + + w0 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aa01 + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ 0101 10~~ + w2 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + + Only on x86: Map the indicated 4M physical frame to the caller. + + + w0 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aa~~ + w1 ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ ~~~~ + w2 0000 0000 0000 0000 0000 0000 0000 0000 + + Map the indicated physical frame to the caller (with the + preferred page size of the architecture). + + + +================================================================ +$Log: sigma0-new.txt,v $ +Revision 1.3 2001/04/25 15:03:21 skoglund +Sigma0 should map 4MB frame _plus_ 1G when receiving a pagefault above +1G. + +Revision 1.2 2001/04/20 20:37:59 skoglund +Updated description of the new version of sigma0 X.0 RPC protocol. The +new version is fully backwards compatible with the old sigma0 RPC, and +also supports pagefaults generated by an X.0 kernel (i.e., where third +word is zero). + +Revision 1.1 2000/09/29 11:10:35 skoglund +Proposal for new architecture independent sigma0 RPC protocol. + diff --git a/doc/status b/doc/status new file mode 100644 index 0000000..031dc04 --- /dev/null +++ b/doc/status @@ -0,0 +1,68 @@ +status (+ done, - todo, x toredo) + +* Initialization + + MMU + kernel PT + x memory allocator + - free operation + + sigma0 mappings + + sigma0 tcb + + kernel misc data / task table + + switch to sigma0 + - scheduler init + - interrupt init + - timer init + - mapping database init + +* lthread_ex_regs + + activation of 'dead' threads + x allocate tcb + + insert into present queue + + insert into ready queue + - adjust alive threads + x return results + +* id_nearest + + return of own id + - return of nearest chief + +* thread_switch + + thread context switch + - thread state check + - task switch + +- other syscalls + + +* data abort + x null tcb allocation + x new tcb allocation + - pager ipc + + + +next steps + +- basic same task short ipc + ; allows start of ipc path to be done + +-> simple non-preemptive same task thread switching and communication + +- task_new +- pager ipc +- fpages in ipc +- task switch + +-> non-preemptive thread switching (intra/inter task) & address space construction + +; allows development to be split: + 1. interrupts/timer + -> ipc timeouts + -> interrupt ipc + -> preemptive scheduling + 2. mapping db + -> task delete + -> unmap + 3. long ipc + + + diff --git a/doc/syscall_methods b/doc/syscall_methods new file mode 100644 index 0000000..717124c --- /dev/null +++ b/doc/syscall_methods @@ -0,0 +1,250 @@ +/******************************** +* Prefetch_Abort Syscall Method * +********************************/ + +/*************************************** +* Stack Frame * +**************************************** +* IAbort * Syscall * Other * +**************************************** +* SPSR * SPSR * ~ *<- Top TCB (start of kstack) +* a_lr -> pc * ~ * ~ * +* u_lr * u_lr -> pc * ~ * +* u_sp * u_sp * ~ *<- a_sp when in user mode +* r12 * #2 * o_lr -> pc * +* r11 * ~ * u-lr * +* ... * ... * u_sp * +* ... * ... * r12 * +* ... * ... * r11 * +* ... * ... * ... * +* ... * ... * r0 * +* r0 * ... * SPSR * +* #1 * ~ * #4 * +***************************************/ + +The immediate at the top of the stack specifies the stack layout. + +/* Reset Entry Point 0x0 +************************/ + nop @ Not relavent since mmu disabled + ... + +/* Undefined Entry Point 0x4 +****************************/ + b undefined_entry @ Jump to Undefined Instruction entry + ... + +// stack user state +undefined_entry: + ldr sp, #current_thread_sp @ load current threads stack + str lr, [sp, #-4]! @ Stack ud_lr + stmdb sp, {r0 - 14}^ @ Stack user registers + msr spsr, lr @ Move SPSR to un_lr + str lr, [sp, #60]! @ Stack User CPSR + mov lr, #(ABORT_MODE | IRQ_MASK) @ Load now CPSR value + mrs cpsr, lr @ Change to abort mode + + +// undefined_exit is an IPC exit since a exception IPC is generated or the +// thread is kill. + +/* SWI Entry Point at 0x8 +*************************/ + b swi_entry @ Jump to SWI entry + ... + +// swi_entry is same as undefined since its an undefined instruction expecption + +/* Prefetch Abort Entry Point 0xC +*********************************/ + b prefetch_abort_entry @ Jump to prefetch abort entry + ... + +// dispatch +prefetch_abort_entry: +#ifdef EXCEPTION_VECTOR_RELOCATED + mvn lr, lr @ Value is negative of syscall # +#endif + stmia sp, {sp, lr}^ @ Stack User sp, lr (pc after syscall) + cmp lr, #SYSCALL_LIMIT @ Range Check + addlt pc, pc, lr, lsl #3 @ Jump to relavent point +prefetch_abort: @ a_lr >= SYSCALL_LIMIT +#ifdef EXCEPTION_VECTOR_RELOCATED + mvn lr, lr @ Not a syscall so restore a_lr +#endif + sub lr, lr, #4 @ Ajust a_lr for return pc value + str lr, [sp, #8] @ Stack a_lr + msr spsr, lr @ move SPSR to a_lr + str lr, [sp, #12] @ Stack user CPSR + strdb sp!, {r0-r12} @ Stack rest of user registers + ... @ next 4/5 instructions of prefetch_abort + b prefetch_abort_rest +ipc_entry: @ a_lr = 0x4, ipc + @ next 6 instructions of ipc_entry + b ipc_rest + nop @ dummy + +// Syscall entry, ie ipc_entry + + msr spsr, lr @ move SPSR to a_lr + str lr, [sp, #12] @ Stack SPSR + + +// Syscall exit (sp points to kstack of whatever thread we are returnning to) +// Arguments already in relavent regs */ + + ldr lr, [sp, #12] @ Unstack User CPSR to a_lr + msc lr, spsr @ Move User CPSR to SPSR + ldmia sp, {sp, pc}^ @ Restore User CPSR/sp, pc + +// prefetch abort exit +prefetch_exit: + ldmia sp!, {r0-r12} @ Unstack rest registers + ldr lr, [sp, #12] @ Unstack User CPSR to a_lr + msc lr, spsr @ Move User CPSR to SPSR + ldmia sp, {sp, lr, pc}^ @ Restore User CPSR/sp/lr, pc + +/* Data Abort Entry Point at 0xC +********************************/ + b data_abort_entry @ Jump to data abort entry + ... + +data_abort_entry: + str lr, [sp, #-4]! @ Stack ud_lr + stmdb sp, {r0 - 14}^ @ Stack user registers + msr spsr, lr @ Move SPSR to un_lr + str lr, [sp, #60]! @ Stack User CPSR + + +// data_abort_exit is an IPC exit since a pager IPC is generated or the thread +// is kill. + +/* Unused Entry Point at 0x14 +*****************************/ + nop @ Not relevent (reserved) + ... + +/* IRQ Entry Point at 0x18 +**************************/ + b irq_entry @ Jump to IRQ entry + +// irq_entry same as undefined_entry since IRQ result in an IPC +// irq_exit is either IPC exit or a thread switch (possibly a debug int which +// is similar to a thread switch except the interrupted thread is restored + +/* FIQ Entry Point at 0x1C +**************************/ +fiq_entry: + +// FIXUP, need to decide weather we interrupted user or kernel. if user its +// the same as irq. If kernel we have to a little magic. + +// fiq_entry is the same as irq_entry but can start straight away without a +// branch + +// Note: where we can assign IRQ or FIQ to a interrupt source kernel timer and +// debugging interrupts are FIQ so they can interrupt at any time and it +// seperates the handlers. Otherwise they have a common code base. + +/******************************** +* SWI + Register Syscall Method * +********************************/ + +/**************************** +* Stack Frame * +***************************** +* Other * Syscall * +*****************************<- start of next TCB (start of kstack) +* p_lr -> pc * sv_lr -> pc * +* u_lr * u_lr * +* u_sp * u_sp * +* r12 * SPSR * +* r11 * ~ * +* ... * ~ * +* r0 * ... * +* SPSR * ~ * +****************************/ + +/* Reset Entry point 0x0 +************************/ + nop @ Not relavent since mmu disabled + ... + +/* Undefined Entry Point 0x4 +****************************/ + b undefined_entry @ Jump to Undefined Instruction entry + +undefined_entry: + ldr sp, #current_thread_sp @ Load ud_sp + str lr, [sp, #-4]! @ Stack ud_lr (pc after exception) + stmdb sp, {r0 - r14}^ @ Stack registers + msr spsr, lr @ Move SPSR to ud_lr + str lr, [sp, #-64]! @ Stack SPSR + + +// Undefined will exit in a ipc. So ipc_exit will be used + +/* SWI Entry point 0x8 +**********************/ + b swi_entry @ Jump to SWI entry + ... + +/* dispatch */ +swi_entry: + ldr sp, #current_thread_sp @ Load sv_sp + str lr, [sp, #-4]! @ Stack sv_lr (pc after syscall) + stmdb sp, {sp, lr}^ @ Stack u_sp, u_lr + msr spsr, lr @ Move SPSR to lr + str lr, [sp, #-12]! @ Stack SPSR + cmp r0, #SYSCALL_LIMIT @ Range Check + addlt pc, pc, r0, lsl #2 @ Jump to relavent Jump point + b invalid_swi @ Syscall # >= SYSCALL_LIMIT +ipc_entry: @ Syscall = 0, ipc + ... @ First 6 ipc intructions + b ipc_rest @ Branch to rest of ipc code + nop @ Dummy to avoid cache stall on SA's +id_nearest: @ Syscall = 1, id_nearest + ... @ ... + +/* Syscall exit (sp points to kstack of whatever thread we are returnning to) + * Arguments already in relavent regs */ +// If we switched threads + ldr lr, @ load sp of new thread + str lr, #current_thread_sp @ store in kernel data +// If same thread we start here + ldr lr, [sp], #4 @ Unstrack SPSR to sv_lr + msc lr, spsr @ load SPSR + ldmia sp, {sp, lr, pc}^ @ Restore CPSR, sp, lr, pc + +/* Prefetch Abort Entry point 0xC +*********************************/ + b prefetch_abort_entry + ... + +// Same as undefined + +/* Data Abort Entry Point at 0xC +********************************/ + b data_abort_entry @ Jump to data abort entry + ... + +// Same as undefined + +/* Unused Entry Point at 0x14 +*****************************/ + nop @ Not relevent (reserved) + ... + +/* IRQ Entry Point at 0x18 +**************************/ + b irq_entry @ Jump to IRQ entry + ... + +// Same as undefined + +/* FIQ Entry Point at 0x1C +**************************/ +fiq_entry: + +// Same as undefined with the constraint of the prefetch syscall method +// fiq entry point. diff --git a/kernel/.cvsignore b/kernel/.cvsignore new file mode 100644 index 0000000..1d14c64 --- /dev/null +++ b/kernel/.cvsignore @@ -0,0 +1,4 @@ +*-kernel +*-kernel.stripped +Makeconf.local +*.ii *.s diff --git a/kernel/Makeconf b/kernel/Makeconf new file mode 100644 index 0000000..57f94d3 --- /dev/null +++ b/kernel/Makeconf @@ -0,0 +1,221 @@ +# -*- mode: Makefile; -*- +###################################################################### +## +## Copyright (C) 1999-2002, Karlsruhe University +## +## File path: Makeconf +## Description: Central Makeconf gile +## +## @LICENSE@ +## +## $Id: Makeconf,v 1.50 2002/01/24 21:12:37 ud3 Exp $ +## +###################################################################### + +###################################################################### +# the root directory +# this rule calculates the kernel source directory by looking for +# the file Makeconf in the current and several parent directories + +TOPDIR = $(dir $(word 1,$(wildcard Makeconf $(addsuffix /Makeconf, .. ../.. ../../..)))) + +# this checks for the Makeconf.local +# we need it, so if it's not there, just rebuild it +ifneq ($(wildcard $(TOPDIR)Makeconf.local), ) + +###################################################################### +# this should be the very first rule + +_default: all + + +###################################################################### +# local Makeconf file + +-include $(TOPDIR)Makeconf.local + + +###################################################################### +# Platform specific parts + +ifeq ($(PLATFORM), dnard) +CPPFLAGS += -mcpu=strongarm110 +DEFINES += __CPU__=strongarm110 +ARCH = arm +else + +ifeq ($(PLATFORM), ep7211) +CPPFLAGS += -mcpu=arm7tdmi +DEFINES += __CPU__=arm720t EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), brutus) +CPPFLAGS += -mcpu=strongarm1100 +DEFINES += __CPU__=strongarm1100 EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), ipaq) +CPPFLAGS += -mcpu=strongarm1100 +DEFINES += __CPU__=strongarm1100 EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), pleb) +CPPFLAGS += -mcpu=strongarm1100 -save-temps -g +DEFINES += __CPU__=strongarm1100 EXCEPTION_VECTOR_RELOCATED +ARCH = arm +else + +ifeq ($(PLATFORM), i586) +ARCH = x86 +CFLAGS += -march=i586 +else + +ifeq ($(PLATFORM), i686) +ARCH = x86 +CFLAGS += -march=i686 +else + +ifeq ($(PLATFORM), p4) +ARCH = x86 +CFLAGS += -march=i686 +else + +ifeq ($(PLATFORM), r4000) +ARCH = mips +CFLAGS += -Wall -Wno-format -O9 -fomit-frame-pointer -mcpu=r4000 -G 0 -mno-abicalls -fno-pic -mips3 -mgp32 +#CFLAGS += -Wall -Wno-format -O9 -mcpu=r4000 -G 0 -mno-abicalls -fno-pic -mips3 -mgp32 +SFLAGS += -mips3 + +else +$(error fatal error: unknown platform "$(PLATFORM)". Change Makeconf.local) +endif +endif +endif +endif +endif +endif +endif +endif +endif + +else +PLATFORM=i686 # make make happy +_default: + $(MAKE) xconfig + $(MAKE) + @exit 0 +endif + +###################################################################### +# Architecture specific parts + +SHELL = bash +ifeq ($(ARCH), arm) + ifneq ($(shell type -p arm-unknown-linux-gcc),) +PREFIX = arm-unknown-linux-gnu- + else + ifneq ($(shell type -p arm-elf-gcc),) +PREFIX = arm-elf- + else +PREFIX = arm-linux- + endif + endif +CFLAGS += -Wall -Wno-format -O2 -fomit-frame-pointer +LDFLAGS += -Tlinker/$(PLATFORM).lds +endif + +ifeq ($(ARCH), mips) +PREFIX = mips- +endif + +ifeq ($(ARCH), x86) + ifneq ($(shell type -p i686-linux-gcc),) +PREFIX =i686-linux- + endif +CFLAGS += -Wall -Wno-format -O9 -fomit-frame-pointer -freg-struct-return +endif + +###################################################################### +# tools + +RM = rm +LN_S = ln -s +CC = $(PREFIX)gcc +#CC = ~/work/gcc/bin/gcc +DEPCC = gcc +LD = $(PREFIX)ld +OBJCOPY = $(PREFIX)objcopy +OBJDUMP = $(PREFIX)objdump +STRIP = $(PREFIX)strip +AR = $(PREFIX)ar +NM = $(PREFIX)nm + +LIBGCCINC = $(dir $(shell $(CC) --print-lib))include + +INCLUDES += $(TOPDIR)include $(LIBGCCINC) + +LIBGCC = $(dir $(shell $(CC) $(CFLAGS) --print-lib -)) + +SFLAGS += -DASSEMBLY +LDFLAGS += -N -Tlinker/$(ARCH).lds + +DEFINES += __ARCH__=$(ARCH)\ + __PLATFORM__=$(PLATFORM) + +CPPFLAGS += -nostdinc -U$(ARCH) -U$(PLATFORM) $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) + +CFLAGS += -x c++ -funsigned-char -funsigned-bitfields -fno-exceptions + +###################################################################### +# some evil magic + +ifeq ($(findstring -fomit-frame-pointer, $(CFLAGS)), -fomit-frame-pointer) +DEFINES += NO_FRAME_POINTER +endif + + + +###################################################################### +# compile rules + +%.o: %.S + $(CC) $(CPPFLAGS) $(SFLAGS) -o $@ -c $< + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< + + +###################################################################### +# library rules +LIB_OBJ = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(LIB_SRC))) + +$(LIB): $(LIB_OBJ) Makefile + $(AR) -rcs $(LIB) $(LIB_OBJ) + +OBJ = $(patsubst %.S, %.o, $(patsubst %.c, %.o, $(OBJ_SRC))) + +###################################################################### +# striptease + +%.stripped: % + @chmod a+r $^ + @chmod a-x $^ + @cp -fp $^ $@ + $(STRIP) $@ + +###################################################################### +# dependencies + +.depend: $(OBJ_SRC) $(LIB_SRC) Makefile + @echo Building dependencies in `pwd` + @$(DEPCC) $(CPPFLAGS) -o - -M $(OBJ_SRC) $(LIB_SRC) > $@ + + +###################################################################### +# cleanup + +celan clean:: + $(RM) -f *~ *.s *.o *.i *.ii *.s $(LIB) diff --git a/kernel/Makeconf.local b/kernel/Makeconf.local new file mode 100644 index 0000000..09998ff --- /dev/null +++ b/kernel/Makeconf.local @@ -0,0 +1 @@ +PLATFORM=i686 diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..8f145c7 --- /dev/null +++ b/kernel/Makefile @@ -0,0 +1,99 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.32 2001/12/07 19:04:23 skoglund Exp $ +## +###################################################################### + +# main rule +LIB= + +include Makeconf + +SUBDIRS = src src/$(ARCH) src/$(ARCH)/$(PLATFORM) kdb +LIBDIRS = -Lsrc -Lsrc/$(ARCH) -Lsrc/$(ARCH)/$(PLATFORM) -Lkdb \ + -L$(LIBGCC) + +LIBS = --start-group -lkernel -larch -lplatform -lkdb --end-group + + +KERNEL = $(ARCH)-kernel +OBJS = src/version.o + +SYMLINKS_ARCH = include +SYMLINKS_PLATFORM = include/arch + +all: $(KERNEL) + +$(KERNEL): include/config.h include/tcb_layout.h $(SUBDIRS) $(OBJS) + @echo "Linking kernel..." + $(LD) $(LDFLAGS) -o $@ $(LIBDIRS) src/$(ARCH)/$(PLATFORM)/startup.o $(OBJS) $(LIBS) + @$(STRIP) -N gcc2_compiled. $@ + cp $@ $@.stripped + $(STRIP) $@.stripped + @chmod a-x+r $@ $@.stripped + @echo Done. ; echo "" + +include/config.h: $(wildcard xconfig/*.in) + $(MAKE) -C xconfig + +.PHONY: src/version.o +src/version.o: + @touch src/version.c + @$(CC) $(CPPFLAGS) $(CFLAGS) '-D__USER__="$(USER)@'`hostname`'"' '-D__GCCVERSION__="$(shell $(CC) -v 2>&1 | tail -1)"' -o $@ -c src/version.c + +.PHONY: xconfig xconfig/ +xconfig xconfig/: + $(MAKE) -C xconfig + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ + +# include some ... ehmmm ... rules for +# - include/tcb_layout.h +include Makefile.voodoo + + +dep: include/tcb_layout.h + @for d in $(SUBDIRS); do \ + $(MAKE) -C $${d} .depend || exit 1; \ + done + +celan clean:: + @for d in $(SUBDIRS) xconfig; do \ + (cd $${d} && $(MAKE) clean) \ + done + find include -name *~ | xargs rm -f + @$(RM) -fv *-kernel{,.stripped,.lst,.map} + @[ `find . -name "*.[oa]" | wc -l` != 0 ] &&\ + (echo ; echo Did not delete the following files - review;\ + find . -name "*.[oa]"; echo) || true + @echo done. + +mrproper: clean + @echo Removing dependency files + @$(RM) -fv `find . -name .depend` + @echo Removing all object files and libraries "*.[oa]" + @$(RM) -fv `find . -name "*.[oa]"` + @echo Removing some machine-generated files + @$(RM) -fv include/tcb_layout.h + +lst $(KERNEL).lst: $(KERNEL) + @echo -n "Generating Listing $<.lst ... " + @chmod u+w -f $<.lst || true + @$(OBJDUMP).l4 -d $< > $<.lst || $(OBJDUMP) -d $< > $<.lst + @chmod a-w $<.lst + @echo done. + +map $(KERNEL).map: $(KERNEL) + @echo -n "Generating Map File $<.map ... " + @chmod u+w -f $<.map || true + @$(NM) -n $< > $<.map + @chmod a-w $<.map + @echo done. diff --git a/kernel/Makefile.voodoo b/kernel/Makefile.voodoo new file mode 100644 index 0000000..9f0fb77 --- /dev/null +++ b/kernel/Makefile.voodoo @@ -0,0 +1,78 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: Makefile.voodoo +## Description: Makefile to hide load of very ugly magic. +## +## @LICENSE@ +## +## $Id: Makefile.voodoo,v 1.10 2001/11/22 15:45:51 skoglund Exp $ +## +###################################################################### + +# create a random filename +TCBLAYOUTTMP:=./_$(shell date +%s)_123 + +# rebuild include/tcb_layout.h if needed +include/tcb_layout.h: include/tcb.h include/$(ARCH)/tcb.h Makefile.voodoo + @echo Generating $@ + @# + @# create dummy tcb_layout.h + @rm -f $@ + @touch $@ + @# + @# create offsets in C + @printf '\ +#include \n\ + \n\ +tcb_t tcb; \n\ + \n\ +#define O(x) (dword_t)((char*) &tcb.x - (char*)(&tcb)) \n\ + \n\ +dword_t offsets[] __attribute__ ((section(".offsets"))) = \n\ +{ \n' > $(TCBLAYOUTTMP).c + @( cat include/config.h; cat include/tcb.h | awk 'BEGIN{printme=0} /TCB_END_MARKER/ { printme = 0} { if (printme == 1 ) { print } } /TCB_START_MARKER/ {printme = 1 } ' ) | cpp $(CPPFLAGS) -P | tr '*[;' ' ' | sed -e 's/[ \t\\]*/ /' | awk -F' ' '{print $$2}' | grep -v '^$$' | awk '{ print " O("$$1")," } ' >> $(TCBLAYOUTTMP).c + @printf '\n};\n' >> $(TCBLAYOUTTMP).c + @# + @# build offsets with cross compiler + @$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(TCBLAYOUTTMP).o $(TCBLAYOUTTMP).c + @# extract offsets into bin + @$(OBJCOPY) -j .offsets -Obinary $(TCBLAYOUTTMP).o $(TCBLAYOUTTMP).bin + @# + @# + @# + @# create dumper + @printf '\ + \n\ +#include \n\ +#include \n\ +int offsets[] = { \n' > $(TCBLAYOUTTMP)-dump.c + @hexdump -v -e '"0x%x, "' $(TCBLAYOUTTMP).bin >> $(TCBLAYOUTTMP)-dump.c + @printf '}; \n\ + \n\ +char* ucase(char* s) \n\ +{ \n\ + for (char*t=s;*t;t++) \n\ + *t = toupper(*t); \n\ + return s; \n\ +} \n\ + \n\ +#define D(x) printf("#define OFS_TCB_%%-30s0x%%02x\t/* %%3d */\\n", ucase(#x), offsets[idx], offsets[idx]); idx++; \n\ + \n\ +int idx = 0; \n\ +int main(void) \n\ +{ \n' >> $(TCBLAYOUTTMP)-dump.c + @( cat include/config.h; cat include/tcb.h | awk 'BEGIN{printme=0} /TCB_END_MARKER/ { printme = 0} { if (printme == 1 ) { print } } /TCB_START_MARKER/ {printme = 1 } ' ) | cpp $(CPPFLAGS) -P | tr '*[;' ' ' | sed -e 's/[ \t\\]*/ /' | awk -F' ' '{print $$2}' | grep -v '^$$' | awk '{ print " D("$$1");" } ' >> $(TCBLAYOUTTMP)-dump.c + @printf '\n};\n' >> $(TCBLAYOUTTMP)-dump.c + @# + @# build dumper + @gcc -N -ggdb -x c++ -o $(TCBLAYOUTTMP)-dump $(TCBLAYOUTTMP)-dump.c + @# run dumper + @printf '/* machine-generated file - do NOT edit */\n' > $@ + @printf '#ifndef __TCB_LAYOUT__H__\n' >> $@ + @printf '#define __TCB_LAYOUT__H__\n\n' >> $@ + @$(TCBLAYOUTTMP)-dump >> $@ + @printf '\n#endif /* __TCB_LAYOUT__H__ */\n' >> $@ + @$(RM) $(TCBLAYOUTTMP)* + diff --git a/kernel/PERFORMANCE b/kernel/PERFORMANCE new file mode 100644 index 0000000..b1ef136 --- /dev/null +++ b/kernel/PERFORMANCE @@ -0,0 +1,42 @@ + Inter Inter Machine (CPU/MHz/L2) uid + Large Small Intra Xcpu Kernel date +-------+-------+-------+-------+--------+------------------------------+------ +int30 475 387 | 2x(PIII/450/512K) ud3 +syse* 347 181 | L4-Y 140700 +-------+-------+-------+-------+--------+------------------------------+------ +int30 490 319 | 2x(PIII/450/512K) ud3 +syse* 409 195 2380 | L4Ka 140700 +-------+-------+-------+-------+--------+------------------------------+------ +int30 494 327 | 1x(PIII/500/512K) espen +syse* 407 204 | L4Ka 140700 +-------+-------+-------+-------+--------+------------------------------+------ +int30 492 321 | 2x(PIII/500/512K) espen +syse* 415 204 | L4Ka Monolithic kernel 260900 +-------+-------+-------+-------+--------+------------------------------+------ +int30 611 466 3169 | 2x(PIII/500/512K) espen +syse* 513 338 3078 | L4Ka SMP kernel 260900 +-------+-------+-------+-------+--------+------------------------------+------ +int30 775 572 466 | 2x(PIII/500/512K) espen +syse* | L4Ka (not optimized) 081100 +-------+-------+-------+-------+--------+------------------------------+------ +int30 480 302 292 | 2x(PIII/500/512K) espen +syse* 352 197 183 | L4-Y 131100 +-------+-------+-------+-------+--------+------------------------------+------ +int30 523 488 336 | 2x(PIII/500/512K) espen +syse* | L4Ka (sys_ipc w/regargs) 211100 +-------+-------+-------+-------+--------+------------------------------+------ +int30 525 486 334 | 2x(PIII/500/512K) espen +syse* 427 410 256 | L4Ka 231100 +-------+-------+-------+-------+--------+------------------------------+------ +int30 468 342 337 | 2x(PIII/500/512K) espen +syse* 424 263 256 | L4Ka 011200 +-------+-------+-------+-------+--------+------------------------------+------ +int30 | 2x(PII/500/512K) espen +syse* 452 231 | L4Ka (largepath) 051201 +syse* 522 322 293 | L4Ka (smallpath) 051201 +syse* 288 106 | L4Ka (largepath, fastpath) 051201 +syse* 349 193 164 | L4Ka (smallpath, fastpath) 051201 +syse* 344 183 147 | L4Ka (smallpath, fastpath) 061201 +-------+-------+-------+-------+--------+------------------------------+------ +int30 | +syse* | diff --git a/kernel/README.html b/kernel/README.html new file mode 100644 index 0000000..d577962 --- /dev/null +++ b/kernel/README.html @@ -0,0 +1,31 @@ + + + + + + L4/KA README + + + +

+Recommended Build Environment

+ +
    +
  • +make 3.78.1
    +
    known to fail: 3.77
    +known to work: 3.79
  • + +
  • +binutils 2.9.5.0.22
    +
    known to work: 2.10.90 (i386-linux) using BFD version 2.10.0.9
  • + +
  • +gcc 2.95.2
  • + +
  • +wish (tcl/tk) 8.3
  • +
+ + + diff --git a/kernel/contrib/arm-opc.h b/kernel/contrib/arm-opc.h new file mode 100644 index 0000000..b013793 --- /dev/null +++ b/kernel/contrib/arm-opc.h @@ -0,0 +1,315 @@ +/* Opcode table for the ARM. + + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +/* + * - L4-ified by UD, Dec 2001 + */ + + +struct arm_opcode { + unsigned long value, mask; /* recognise instruction if (op&mask)==value */ + char *assembler; /* how to disassemble this instruction */ +}; + +/* format of the assembler string : + + %% % + %d print the bitfield in decimal + %x print the bitfield in hex + %X print the bitfield as 1 hex digit without leading "0x" + %r print as an ARM register + %f print a floating point constant if >7 else a + floating point register + %c print condition code (always bits 28-31) + %P print floating point precision in arithmetic insn + %Q print floating point precision in ldf/stf insn + %R print floating point rounding mode + %'c print specified char iff bit is one + %`c print specified char iff bit is zero + %?ab print a if bit is one else print b + %p print 'p' iff bits 12-15 are 15 + %t print 't' iff bit 21 set and bit 24 clear + %h print 'h' iff bit 5 set, else print 'b' + %o print operand2 (immediate or register + shift) + %a print address for ldr/str instruction + %s print address for ldr/str halfword/signextend instruction + %b print branch destination + %B print arm BLX(1) destination + %A print address for ldc/stc/ldf/stf instruction + %m print register mask for ldm/stm instruction + %C print the PSR sub type. + %F print the COUNT field of a LFM/SFM instruction. +Thumb specific format options: + %D print Thumb register (bits 0..2 as high number if bit 7 set) + %S print Thumb register (bits 3..5 as high number if bit 6 set) + %I print bitfield as a signed decimal + (top bit of range being the sign bit) + %M print Thumb register mask + %N print Thumb register mask (with LR) + %O print Thumb register mask (with PC) + %T print Thumb condition code (always bits 8-11) + %I print cirrus signed shift immediate: bits 0..3|4..6 + %B print Thumb branch destination (signed displacement) + %W print (bitfield * 4) as a decimal + %H print (bitfield * 2) as a decimal + %a print (bitfield * 4) as a pc-rel offset + decoded symbol +*/ + +/* Note: There is a partial ordering in this table - it must be searched from + the top to obtain a correct match. */ + +static struct arm_opcode arm_opcodes[] = +{ + /* ARM instructions. */ + {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, + {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, + {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"}, + {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"}, + {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, + + /* XScale instructions. */ + {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"}, + {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"}, + {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"}, + {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"}, + {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"}, + {0xf450f000, 0xfc70f000, "pld\t%a"}, + + /* V5 Instructions. */ + {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"}, + {0xfa000000, 0xfe000000, "blx\t%B"}, + {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"}, + {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"}, + {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"}, + {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"}, + {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + + /* V5E "El Segundo" Instructions. */ + {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"}, + {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"}, + {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + + {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, + + {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, + + {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"}, + {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"}, + + {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"}, + {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"}, + + {0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"}, + {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"}, + {0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"}, + {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"}, + + {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, + {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, + + /* ARM Instructions. */ + {0x00000090, 0x0e100090, "str%c%6's%h\t%12-15r, %s"}, + {0x00100090, 0x0e100090, "ldr%c%6's%h\t%12-15r, %s"}, + {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"}, + {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"}, + {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"}, + {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"}, + {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"}, + {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"}, + {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"}, + {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"}, + {0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"}, + {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"}, + {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"}, + {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"}, + {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"}, + {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"}, + {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"}, + {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"}, + {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"}, + {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"}, + {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"}, + {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"}, + {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"}, + {0x06000010, 0x0e000010, "undefined"}, + {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"}, + {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, + {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, + {0x0a000000, 0x0e000000, "b%24'l%c\t%b"}, + {0x0f000000, 0x0f000000, "swi%c\t%0-23x"}, + + /* Floating point coprocessor instructions */ + {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"}, + {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"}, + {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"}, + {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"}, + {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"}, + {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"}, + {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"}, + {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"}, + {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"}, + {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"}, + {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"}, + {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"}, + {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"}, + {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"}, + {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"}, + {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"}, + {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"}, + {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"}, + {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"}, + {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"}, + {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"}, + {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"}, + {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"}, + {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"}, + {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"}, + {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"}, + {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"}, + {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"}, + {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"}, + {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"}, + {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, + + /* Cirrus coprocessor instructions. */ + {0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, + {0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, + {0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, + {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, + {0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, + {0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, + {0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, + {0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, + {0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, + {0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, + {0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, + {0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, + {0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, + {0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, + {0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, + {0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, + {0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"}, + {0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"}, + {0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"}, + {0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"}, + {0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"}, + {0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"}, + {0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"}, + {0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"}, + {0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"}, + {0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"}, + {0x0e100610, 0x0ff0fff0, "cfmval32%c\tmvax%0-3d, mvfx%16-19d"}, + {0x0e000610, 0x0ff0fff0, "cfmv32al%c\tmvfx%0-3d, mvax%16-19d"}, + {0x0e100630, 0x0ff0fff0, "cfmvam32%c\tmvax%0-3d, mvfx%16-19d"}, + {0x0e000630, 0x0ff0fff0, "cfmv32am%c\tmvfx%0-3d, mvax%16-19d"}, + {0x0e100650, 0x0ff0fff0, "cfmvah32%c\tmvax%0-3d, mvfx%16-19d"}, + {0x0e000650, 0x0ff0fff0, "cfmv32ah%c\tmvfx%0-3d, mvax%16-19d"}, + {0x0e000670, 0x0ff0fff0, "cfmv32a%c\tmvfx%0-3d, mvax%16-19d"}, + {0x0e100670, 0x0ff0fff0, "cfmva32%c\tmvax%0-3d, mvfx%16-19d"}, + {0x0e000690, 0x0ff0fff0, "cfmv64a%c\tmvdx%0-3d, mvax%16-19d"}, + {0x0e100690, 0x0ff0fff0, "cfmva64%c\tmvax%0-3d, mvdx%16-19d"}, + {0x0e1006b0, 0x0ff0fff0, "cfmvsc32%c\tdspsc, mvfx%16-19d"}, + {0x0e0006b0, 0x0ff0fff0, "cfmv32sc%c\tmvfx%0-3d, dspsc"}, + {0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"}, + {0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"}, + {0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"}, + {0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"}, + {0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"}, + {0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"}, + {0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"}, + {0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"}, + {0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"}, + {0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"}, + {0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"}, + {0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"}, + {0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"}, + {0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"}, + {0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"}, + {0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"}, + {0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"}, + {0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"}, + {0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"}, + {0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"}, + {0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"}, + {0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"}, + {0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"}, + {0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"}, + {0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, + {0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, + {0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, + {0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, + {0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, + {0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, + {0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"}, + {0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"}, + {0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"}, + {0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"}, + {0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, + {0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, + {0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, + {0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, + {0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, + + /* Generic coprocessor instructions */ + {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, + {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"}, + {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"}, + + /* The rest. */ + {0x00000000, 0x00000000, "undefined instruction %0-31x"}, + {0x00000000, 0x00000000, 0} +}; + +#define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */ + diff --git a/kernel/contrib/arm_dis.c b/kernel/contrib/arm_dis.c new file mode 100644 index 0000000..bca2bd7 --- /dev/null +++ b/kernel/contrib/arm_dis.c @@ -0,0 +1,652 @@ +/* Instruction printing code for the ARM + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. + Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) + Modification by James G. Smith (jsmith@cygnus.co.uk) + +This file is part of libopcodes. + +This program 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 of the License, or (at your option) +any later version. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + + + +/* + * - L4-ified by UD, Dec 2001 + * - brute-force C++-ified by UD, Dec 2001 + */ + + +#include "arm-opc.h" + +#define _(x) x +#define VOLATILE __volatile__ +#define PTR char * +#define PARAMS(x) x +#define ATTRIBUTE_UNUSED +#define bfd_mach_i386_i386 0 +#define bfd_mach_i386_i8086 1 +#define bfd_mach_i386_i386_intel_syntax 2 +#define abort() return 4 +#define stderr NULL +#define boolean int +int fprintf(char* f, const char* format, ...) L4_SECT_KDEBUG; + +typedef struct { dword_t eip; dword_t esp; dword_t ebp; int val; } jmp_buf; + + +typedef dword_t bfd_vma; +typedef byte_t bfd_byte; + +typedef int (*fprintf_ftype) PARAMS((PTR, const char*, ...)); + +struct disassemble_info { + char* stream; + fprintf_ftype fprintf_func; + void (*print_address_func)(bfd_vma addr, struct disassemble_info *info); +}; + + + + +static char * arm_conditional[] = +{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", + "hi", "ls", "ge", "lt", "gt", "le", "", "nv"}; + +const char * arm_regnames[16] = +{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }; + +static char * arm_fp_const[] = +{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; + +static char * arm_shift[] = +{"lsl", "lsr", "asr", "ror"}; + + +static void +arm_decode_shift (long given, fprintf_ftype func, char * stream) +{ + func (stream, "%s", arm_regnames[given & 0xf]); + + if ((given & 0xff0) != 0) + { + if ((given & 0x10) == 0) + { + int amount = (given & 0xf80) >> 7; + int shift = (given & 0x60) >> 5; + + if (amount == 0) + { + if (shift == 3) + { + func (stream, ", rrx"); + return; + } + + amount = 32; + } + + func (stream, ", %s #%d", arm_shift[shift], amount); + } + else + func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5], + arm_regnames[(given & 0xf00) >> 8]); + } +} + +/* Print one instruction from PC on INFO->STREAM. + Return the size of the instruction (always 4 on ARM). */ +static int +print_insn_arm (bfd_vma pc, struct disassemble_info * info, long given) +{ + struct arm_opcode * insn; + char * stream = info->stream; + fprintf_ftype func = info->fprintf_func; + + for (insn = arm_opcodes; insn->assembler; insn++) + { + if ((given & insn->mask) == insn->value) + { + char * c; + + for (c = insn->assembler; *c; c++) + { + if (*c == '%') + { + switch (*++c) + { + case '%': + func (stream, "%%"); + break; + + case 'a': + if (((given & 0x000f0000) == 0x000f0000) + && ((given & 0x02000000) == 0)) + { + int offset = given & 0xfff; + + func (stream, "[pc"); + + if (given & 0x01000000) + { + if ((given & 0x00800000) == 0) + offset = - offset; + + /* pre-indexed */ + func (stream, ", #%d]", offset); + + offset += pc + 8; + + /* Cope with the possibility of write-back + being used. Probably a very dangerous thing + for the programmer to do, but who are we to + argue ? */ + if (given & 0x00200000) + func (stream, "!"); + } + else + { + /* Post indexed. */ + func (stream, "], #%d", offset); + + offset = pc + 8; /* ie ignore the offset. */ + } + + func (stream, "\t; "); + info->print_address_func (offset, info); + } + else + { + func (stream, "[%s", + arm_regnames[(given >> 16) & 0xf]); + if ((given & 0x01000000) != 0) + { + if ((given & 0x02000000) == 0) + { + int offset = given & 0xfff; + if (offset) + func (stream, ", %s#%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + } + else + { + func (stream, ", %s", + (((given & 0x00800000) == 0) + ? "-" : "")); + arm_decode_shift (given, func, stream); + } + + func (stream, "]%s", + ((given & 0x00200000) != 0) ? "!" : ""); + } + else + { + if ((given & 0x02000000) == 0) + { + int offset = given & 0xfff; + if (offset) + func (stream, "], %s#%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + else + func (stream, "]"); + } + else + { + func (stream, "], %s", + (((given & 0x00800000) == 0) + ? "-" : "")); + arm_decode_shift (given, func, stream); + } + } + } + break; + + case 's': + if ((given & 0x004f0000) == 0x004f0000) + { + /* PC relative with immediate offset. */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + + if ((given & 0x00800000) == 0) + offset = -offset; + + func (stream, "[pc, #%d]\t; ", offset); + + (*info->print_address_func) + (offset + pc + 8, info); + } + else + { + func (stream, "[%s", + arm_regnames[(given >> 16) & 0xf]); + if ((given & 0x01000000) != 0) + { + /* Pre-indexed. */ + if ((given & 0x00400000) == 0x00400000) + { + /* Immediate. */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + if (offset) + func (stream, ", %s#%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + } + else + { + /* Register. */ + func (stream, ", %s%s", + (((given & 0x00800000) == 0) + ? "-" : ""), + arm_regnames[given & 0xf]); + } + + func (stream, "]%s", + ((given & 0x00200000) != 0) ? "!" : ""); + } + else + { + /* Post-indexed. */ + if ((given & 0x00400000) == 0x00400000) + { + /* Immediate. */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + if (offset) + func (stream, "], %s#%d", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + else + func (stream, "]"); + } + else + { + /* Register. */ + func (stream, "], %s%s", + (((given & 0x00800000) == 0) + ? "-" : ""), + arm_regnames[given & 0xf]); + } + } + } + break; + + case 'b': + (*info->print_address_func) + (BDISP (given) * 4 + pc + 8, info); + break; + + case 'c': + func (stream, "%s", + arm_conditional [(given >> 28) & 0xf]); + break; + + case 'm': + { + int started = 0; + int reg; + + func (stream, "{"); + for (reg = 0; reg < 16; reg++) + if ((given & (1 << reg)) != 0) + { + if (started) + func (stream, ", "); + started = 1; + func (stream, "%s", arm_regnames[reg]); + } + func (stream, "}"); + } + break; + + case 'o': + if ((given & 0x02000000) != 0) + { + int rotate = (given & 0xf00) >> 7; + int immed = (given & 0xff); + immed = (((immed << (32 - rotate)) + | (immed >> rotate)) & 0xffffffff); + func (stream, "#%d\t; 0x%x", immed, immed); + } + else + arm_decode_shift (given, func, stream); + break; + + case 'p': + if ((given & 0x0000f000) == 0x0000f000) + func (stream, "p"); + break; + + case 't': + if ((given & 0x01200000) == 0x00200000) + func (stream, "t"); + break; + + case 'h': + if ((given & 0x00000020) == 0x00000020) + func (stream, "h"); + else + func (stream, "b"); + break; + + case 'A': + func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); + if ((given & 0x01000000) != 0) + { + int offset = given & 0xff; + if (offset) + func (stream, ", %s#%d]%s", + ((given & 0x00800000) == 0 ? "-" : ""), + offset * 4, + ((given & 0x00200000) != 0 ? "!" : "")); + else + func (stream, "]"); + } + else + { + int offset = given & 0xff; + if (offset) + func (stream, "], %s#%d", + ((given & 0x00800000) == 0 ? "-" : ""), + offset * 4); + else + func (stream, "]"); + } + break; + + case 'B': + /* Print ARM V5 BLX(1) address: pc+25 bits. */ + { + bfd_vma address; + bfd_vma offset = 0; + + if (given & 0x00800000) + /* Is signed, hi bits should be ones. */ + offset = (-1) ^ 0x00ffffff; + + /* Offset is (SignExtend(offset field)<<2). */ + offset += given & 0x00ffffff; + offset <<= 2; + address = offset + pc + 8; + + if (given & 0x01000000) + /* H bit allows addressing to 2-byte boundaries. */ + address += 2; + + info->print_address_func (address, info); + } + break; + + case 'I': + /* Print a Cirrus/DSP shift immediate. */ + /* Immediates are 7bit signed ints with bits 0..3 in + bits 0..3 of opcode and bits 4..6 in bits 5..7 + of opcode. */ + { + int imm; + + imm = (given & 0xf) | ((given & 0xe0) >> 1); + + /* Is ``imm'' a negative number? */ + if (imm & 0x40) + imm |= (-1 << 7); + + func (stream, "%d", imm); + } + + break; + + case 'C': + func (stream, "_"); + if (given & 0x80000) + func (stream, "f"); + if (given & 0x40000) + func (stream, "s"); + if (given & 0x20000) + func (stream, "x"); + if (given & 0x10000) + func (stream, "c"); + break; + + case 'F': + switch (given & 0x00408000) + { + case 0: + func (stream, "4"); + break; + case 0x8000: + func (stream, "1"); + break; + case 0x00400000: + func (stream, "2"); + break; + default: + func (stream, "3"); + } + break; + + case 'P': + switch (given & 0x00080080) + { + case 0: + func (stream, "s"); + break; + case 0x80: + func (stream, "d"); + break; + case 0x00080000: + func (stream, "e"); + break; + default: + func (stream, _("")); + break; + } + break; + case 'Q': + switch (given & 0x00408000) + { + case 0: + func (stream, "s"); + break; + case 0x8000: + func (stream, "d"); + break; + case 0x00400000: + func (stream, "e"); + break; + default: + func (stream, "p"); + break; + } + break; + case 'R': + switch (given & 0x60) + { + case 0: + break; + case 0x20: + func (stream, "p"); + break; + case 0x40: + func (stream, "m"); + break; + default: + func (stream, "z"); + break; + } + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + int bitstart = *c++ - '0'; + int bitend = 0; + while (*c >= '0' && *c <= '9') + bitstart = (bitstart * 10) + *c++ - '0'; + + switch (*c) + { + case '-': + c++; + + while (*c >= '0' && *c <= '9') + bitend = (bitend * 10) + *c++ - '0'; + + if (!bitend) + abort (); + + switch (*c) + { + case 'r': + { + long reg; + + reg = given >> bitstart; + reg &= (2 << (bitend - bitstart)) - 1; + + func (stream, "%s", arm_regnames[reg]); + } + break; + case 'd': + { + long reg; + + reg = given >> bitstart; + reg &= (2 << (bitend - bitstart)) - 1; + + func (stream, "%d", reg); + } + break; + case 'x': + { + long reg; + + reg = given >> bitstart; + reg &= (2 << (bitend - bitstart)) - 1; + + func (stream, "0x%08x", reg); + + /* Some SWI instructions have special + meanings. */ + if ((given & 0x0fffffff) == 0x0FF00000) + func (stream, "\t; IMB"); + else if ((given & 0x0fffffff) == 0x0FF00001) + func (stream, "\t; IMBRange"); + } + break; + case 'X': + { + long reg; + + reg = given >> bitstart; + reg &= (2 << (bitend - bitstart)) - 1; + + func (stream, "%01x", reg & 0xf); + } + break; + case 'f': + { + long reg; + + reg = given >> bitstart; + reg &= (2 << (bitend - bitstart)) - 1; + + if (reg > 7) + func (stream, "#%s", + arm_fp_const[reg & 7]); + else + func (stream, "f%d", reg); + } + break; + default: + abort (); + } + break; + + case '`': + c++; + if ((given & (1 << bitstart)) == 0) + func (stream, "%c", *c); + break; + case '\'': + c++; + if ((given & (1 << bitstart)) != 0) + func (stream, "%c", *c); + break; + case '?': + ++c; + if ((given & (1 << bitstart)) != 0) + func (stream, "%c", *c++); + else + func (stream, "%c", *++c); + break; + default: + abort (); + } + break; + + } + } + } + else + func (stream, "%c", *c); + } + return 4; + } + } + abort (); +} + + + + + + + + + + +void paf(bfd_vma addr, struct disassemble_info *info) L4_SECT_KDEBUG; +void paf(bfd_vma addr, struct disassemble_info *info) +{ + printf("%x", addr); +}; + + +int do_printf(const char** format_p); +int fprintf(char* f, const char* format, ...) +{ + return do_printf(&format); +}; + +int arm_disas(dword_t pc) L4_SECT_KDEBUG; +int arm_disas(dword_t pc) +{ + disassemble_info info = + { + NULL, + fprintf, + paf + }; + dword_t insn; + space_t *space = (space_t *) get_current_pgtable(); + if (!kdebug_get_mem(space, pc, &insn)) + { + printf("##"); + return 4; + } + return print_insn_arm(pc, &info, insn); +} + diff --git a/kernel/contrib/x86_dis.c b/kernel/contrib/x86_dis.c new file mode 100644 index 0000000..a044cf8 --- /dev/null +++ b/kernel/contrib/x86_dis.c @@ -0,0 +1,4181 @@ +/* Print i386 instructions for GDB, the GNU debugger. + Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999 + Free Software Foundation, Inc. + +This file is part of GDB. + +This program 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 of the License, or +(at your option) any later version. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* + * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) + * July 1988 + * modified by John Hassey (hassey@dg-rtp.dg.com) + */ + +/* + * The main tables describing the instructions is essentially a copy + * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 + * Programmers Manual. Usually, there is a capital letter, followed + * by a small letter. The capital letter tell the addressing mode, + * and the small letter tells about the operand size. Refer to + * the Intel manual for details. + */ + +/* + * - L4-ified by UD + * - brute-force C++-ified by UD + */ + + +#define _(x) x +#define VOLATILE __volatile__ +#define PTR char * +#define PARAMS(x) x +#define ATTRIBUTE_UNUSED +#define bfd_mach_i386_i386 0 +#define bfd_mach_i386_i8086 1 +#define bfd_mach_i386_i386_intel_syntax 2 +#define abort() do { } while (0) +int sprintf(char* s, const char* format, ...) L4_SECT_KDEBUG; +int fprintf(char* f, const char* format, ...) L4_SECT_KDEBUG; +static int do_sprintf(char** obuf, const char** format_p) L4_SECT_KDEBUG; +static const byte_t hexchars[] L4_SECT_KDEBUG = "0123456789abcdef"; +static inline int strlen(const char* p) { int i=0; while (*(p++)) i++; return i; }; + + +typedef struct { dword_t eip; dword_t esp; dword_t ebp; int val; } jmp_buf; + +static inline void longjmp(jmp_buf &env, int val) +{ +#if 0 + printf("%s(%x,%x) called from %x\n", __FUNCTION__, &env, val, + ({dword_t x;__asm__ __volatile__("call 0f;0:popl %0":"=r"(x));x;})); + printf("jumping to eip=%x esp=%x, ebp=%x\n", + env.eip, env.esp, env.ebp); +#endif + + env.val = val; + __asm__ __volatile__ ( + "jmp *(%%ebx) \n\t" + "orl %%esp,%%esp \n\t" + : + : "a" (&env.ebp), "c"(&env.esp), "b" (&env.eip) + : "edx", "esi", "edi", "memory"); + while(1); +}; +static inline int setjmp(jmp_buf &env) +{ +#if 0 + printf("%s(%x) called from %x\n", __FUNCTION__, &env, + ({dword_t x;__asm__ __volatile__("call 0f;0:popl %0":"=r"(x));x;})); +#endif + env.val = 0; + __asm__ __volatile__ ( + "movl %%ebp, (%0) \n\t" + "movl %%esp, (%1) \n\t" + "movl $0f, (%2) \n\t" + "0: \n\t" + "movl %%esp,%%esp \n\t" + "movl (%1),%%esp \n\t" + "movl (%0),%%ebp \n\t" + : + : "a" (&env.ebp), "c"(&env.esp), "b" (&env.eip) + : "edx", "esi", "edi", "memory"); +#if 0 + printf("prepared to return to eip=%x esp=%x, ebp=%x\n", + env.eip, env.esp, env.ebp); +#endif + return env.val; +}; + + + + +typedef dword_t bfd_vma; +typedef byte_t bfd_byte; + + + +#define MAXLEN 20 +struct dis_private +{ + /* Points to first byte not fetched. */ + bfd_byte *max_fetched; + bfd_byte the_buffer[MAXLEN]; + bfd_vma insn_start; + jmp_buf bailout; +}; + + + +typedef int (*fprintf_ftype) PARAMS((PTR, const char*, ...)); + +struct disassemble_info { + struct dis_private *private_data; + int (*read_memory_func)(bfd_vma memaddr, + bfd_byte *myaddr, unsigned int length, + struct disassemble_info *info); + void (*memory_error_func)(int status, + bfd_vma memaddr, + struct disassemble_info *info); + int mach; + int bytes_per_line; + char* stream; + fprintf_ftype fprintf_func; + void (*print_address_func)(bfd_vma addr, struct disassemble_info *info); +}; +char *strncpy(char *dest, const char *src, int n) L4_SECT_KDEBUG; +char *strcpy(char *dest, const char *src) L4_SECT_KDEBUG; +int sprintf(char *str, const char *format, ...) L4_SECT_KDEBUG; + + + + + +#ifndef UNIXWARE_COMPAT +/* Set non-zero for broken, compatible instructions. Set to zero for + non-broken opcodes. */ +#define UNIXWARE_COMPAT 1 +#endif + +static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *)) L4_SECT_KDEBUG; + + + +/* The opcode for the fwait instruction, which we treat as a prefix + when we can. */ +#define FWAIT_OPCODE (0x9b) + +/* Flags for the prefixes for the current instruction. See below. */ +static int prefixes; + +/* Flags for prefixes which we somehow handled when printing the + current instruction. */ +static int used_prefixes; + +/* Flags stored in PREFIXES. */ +#define PREFIX_REPZ 1 +#define PREFIX_REPNZ 2 +#define PREFIX_LOCK 4 +#define PREFIX_CS 8 +#define PREFIX_SS 0x10 +#define PREFIX_DS 0x20 +#define PREFIX_ES 0x40 +#define PREFIX_FS 0x80 +#define PREFIX_GS 0x100 +#define PREFIX_DATA 0x200 +#define PREFIX_ADDR 0x400 +#define PREFIX_FWAIT 0x800 + +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) + to ADDR (exclusive) are valid. Returns 1 for success, longjmps + on error. */ +#define FETCH_DATA(info, addr) \ + ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \ + ? 1 : fetch_data ((info), (addr))) + +static int +fetch_data (struct disassemble_info *info, bfd_byte *addr) +{ + int status; + struct dis_private *priv = (struct dis_private *)info->private_data; + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); + + status = (*info->read_memory_func) (start, + priv->max_fetched, + addr - priv->max_fetched, + info); + if (status != 0) + { + /* If we did manage to read at least one byte, then + print_insn_i386 will do something sensible. Otherwise, print + an error. We do that here because this is where we know + STATUS. */ + if (priv->max_fetched == priv->the_buffer) + (*info->memory_error_func) (status, start, info); + longjmp (priv->bailout, 1); + } + else + priv->max_fetched = addr; + return 1; +} + +#define XX NULL, 0 + +#define Eb OP_E, b_mode +#define indirEb OP_indirE, b_mode +#define Gb OP_G, b_mode +#define Ev OP_E, v_mode +#define Ed OP_E, d_mode +#define indirEv OP_indirE, v_mode +#define Ew OP_E, w_mode +#define Ma OP_E, v_mode +#define M OP_E, 0 /* lea */ +#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */ +#define Gv OP_G, v_mode +#define Gw OP_G, w_mode +#define Rd OP_Rd, d_mode +#define Ib OP_I, b_mode +#define sIb OP_sI, b_mode /* sign extened byte */ +#define Iv OP_I, v_mode +#define Iw OP_I, w_mode +#define Jb OP_J, b_mode +#define Jv OP_J, v_mode +#define Cd OP_C, d_mode +#define Dd OP_D, d_mode +#define Td OP_T, d_mode + +#define eAX OP_REG, eAX_reg +#define eBX OP_REG, eBX_reg +#define eCX OP_REG, eCX_reg +#define eDX OP_REG, eDX_reg +#define eSP OP_REG, eSP_reg +#define eBP OP_REG, eBP_reg +#define eSI OP_REG, eSI_reg +#define eDI OP_REG, eDI_reg +#define AL OP_REG, al_reg +#define CL OP_REG, cl_reg +#define DL OP_REG, dl_reg +#define BL OP_REG, bl_reg +#define AH OP_REG, ah_reg +#define CH OP_REG, ch_reg +#define DH OP_REG, dh_reg +#define BH OP_REG, bh_reg +#define AX OP_REG, ax_reg +#define DX OP_REG, dx_reg +#define indirDX OP_REG, indir_dx_reg + +#define Sw OP_SEG, w_mode +#define Ap OP_DIR, 0 +#define Ob OP_OFF, b_mode +#define Ov OP_OFF, v_mode +#define Xb OP_DSreg, eSI_reg +#define Xv OP_DSreg, eSI_reg +#define Yb OP_ESreg, eDI_reg +#define Yv OP_ESreg, eDI_reg +#define DSBX OP_DSreg, eBX_reg + +#define es OP_REG, es_reg +#define ss OP_REG, ss_reg +#define cs OP_REG, cs_reg +#define ds OP_REG, ds_reg +#define fs OP_REG, fs_reg +#define gs OP_REG, gs_reg + +#define MX OP_MMX, 0 +#define XM OP_XMM, 0 +#define EM OP_EM, v_mode +#define EX OP_EX, v_mode +#define MS OP_MS, v_mode +#define None OP_E, 0 +#define OPSUF OP_3DNowSuffix, 0 +#define OPSIMD OP_SIMD_Suffix, 0 + +/* bits in sizeflag */ +#if 0 /* leave undefined until someone adds the extra flag to objdump */ +#define SUFFIX_ALWAYS 4 +#endif +#define AFLAG 2 +#define DFLAG 1 + +typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag)); + +#undef PARAMS +#define PARAMS(x) x L4_SECT_KDEBUG + +static void OP_E PARAMS ((int, int)); +static void OP_G PARAMS ((int, int)); +static void OP_I PARAMS ((int, int)); +static void OP_indirE PARAMS ((int, int)); +static void OP_sI PARAMS ((int, int)); +static void OP_REG PARAMS ((int, int)); +static void OP_J PARAMS ((int, int)); +static void OP_DIR PARAMS ((int, int)); +static void OP_OFF PARAMS ((int, int)); +static void OP_ESreg PARAMS ((int, int)); +static void OP_DSreg PARAMS ((int, int)); +static void OP_SEG PARAMS ((int, int)); +static void OP_C PARAMS ((int, int)); +static void OP_D PARAMS ((int, int)); +static void OP_T PARAMS ((int, int)); +static void OP_Rd PARAMS ((int, int)); +static void OP_ST PARAMS ((int, int)); +static void OP_STi PARAMS ((int, int)); +static void OP_MMX PARAMS ((int, int)); +static void OP_XMM PARAMS ((int, int)); +static void OP_EM PARAMS ((int, int)); +static void OP_EX PARAMS ((int, int)); +static void OP_MS PARAMS ((int, int)); +static void OP_3DNowSuffix PARAMS ((int, int)); +static void OP_SIMD_Suffix PARAMS ((int, int)); +static void SIMD_Fixup PARAMS ((int, int)); + +static void append_seg PARAMS ((void)); +static void set_op PARAMS ((unsigned int op)); +static void putop PARAMS ((const char *templ, int sizeflag)); +static void dofloat PARAMS ((int sizeflag)); +static int get16 PARAMS ((void)); +static int get32 PARAMS ((void)); +static void ckprefix PARAMS ((void)); +static const char *prefix_name PARAMS ((int, int)); +static void ptr_reg PARAMS ((int, int)); +static void BadOp PARAMS ((void)); + +#define b_mode 1 +#define v_mode 2 +#define w_mode 3 +#define d_mode 4 +#define x_mode 5 + +#define es_reg 100 +#define cs_reg 101 +#define ss_reg 102 +#define ds_reg 103 +#define fs_reg 104 +#define gs_reg 105 + +#define eAX_reg 108 +#define eCX_reg 109 +#define eDX_reg 110 +#define eBX_reg 111 +#define eSP_reg 112 +#define eBP_reg 113 +#define eSI_reg 114 +#define eDI_reg 115 + +#define al_reg 116 +#define cl_reg 117 +#define dl_reg 118 +#define bl_reg 119 +#define ah_reg 120 +#define ch_reg 121 +#define dh_reg 122 +#define bh_reg 123 + +#define ax_reg 124 +#define cx_reg 125 +#define dx_reg 126 +#define bx_reg 127 +#define sp_reg 128 +#define bp_reg 129 +#define si_reg 130 +#define di_reg 131 + +#define indir_dx_reg 150 + +#define USE_GROUPS 1 +#define USE_PREFIX_USER_TABLE 2 + +#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS, NULL, 0 +#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS, NULL, 0 +#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS, NULL, 0 +#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS, NULL, 0 +#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS, NULL, 0 +#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS, NULL, 0 +#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS, NULL, 0 +#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS, NULL, 0 +#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS, NULL, 0 +#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS, NULL, 0 +#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS, NULL, 0 +#define GRP4 NULL, NULL, 11, NULL, USE_GROUPS, NULL, 0 +#define GRP5 NULL, NULL, 12, NULL, USE_GROUPS, NULL, 0 +#define GRP6 NULL, NULL, 13, NULL, USE_GROUPS, NULL, 0 +#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS, NULL, 0 +#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS, NULL, 0 +#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS, NULL, 0 +#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS, NULL, 0 +#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS, NULL, 0 +#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS, NULL, 0 +#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS, NULL, 0 +#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS, NULL, 0 +#define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS, NULL, 0 + +#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0 +#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0 + +#define FLOATCODE 50 +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 + +struct dis386 { + const char *name; + op_rtn op1; + int bytemode1; + op_rtn op2; + int bytemode2; + op_rtn op3; + int bytemode3; +}; + +/* Upper case letters in the instruction names here are macros. + 'A' => print 'b' if no register operands or suffix_always is true + 'B' => print 'b' if suffix_always is true + 'E' => print 'e' if 32-bit form of jcxz + 'L' => print 'l' if suffix_always is true + 'N' => print 'n' if instruction has no wait "prefix" + 'P' => print 'w' or 'l' if instruction has an operand size prefix, + or suffix_always is true + 'Q' => print 'w' or 'l' if no register operands or suffix_always is true + 'R' => print 'w' or 'l' ("wd" or "dq" in intel mode) + 'S' => print 'w' or 'l' if suffix_always is true + 'W' => print 'b' or 'w' ("w" or "de" in intel mode) +*/ + +static const struct dis386 dis386_att[] = { + /* 00 */ + { "addB", Eb, Gb, XX }, + { "addS", Ev, Gv, XX }, + { "addB", Gb, Eb, XX }, + { "addS", Gv, Ev, XX }, + { "addB", AL, Ib, XX }, + { "addS", eAX, Iv, XX }, + { "pushP", es, XX, XX }, + { "popP", es, XX, XX }, + /* 08 */ + { "orB", Eb, Gb, XX }, + { "orS", Ev, Gv, XX }, + { "orB", Gb, Eb, XX }, + { "orS", Gv, Ev, XX }, + { "orB", AL, Ib, XX }, + { "orS", eAX, Iv, XX }, + { "pushP", cs, XX, XX }, + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ + /* 10 */ + { "adcB", Eb, Gb, XX }, + { "adcS", Ev, Gv, XX }, + { "adcB", Gb, Eb, XX }, + { "adcS", Gv, Ev, XX }, + { "adcB", AL, Ib, XX }, + { "adcS", eAX, Iv, XX }, + { "pushP", ss, XX, XX }, + { "popP", ss, XX, XX }, + /* 18 */ + { "sbbB", Eb, Gb, XX }, + { "sbbS", Ev, Gv, XX }, + { "sbbB", Gb, Eb, XX }, + { "sbbS", Gv, Ev, XX }, + { "sbbB", AL, Ib, XX }, + { "sbbS", eAX, Iv, XX }, + { "pushP", ds, XX, XX }, + { "popP", ds, XX, XX }, + /* 20 */ + { "andB", Eb, Gb, XX }, + { "andS", Ev, Gv, XX }, + { "andB", Gb, Eb, XX }, + { "andS", Gv, Ev, XX }, + { "andB", AL, Ib, XX }, + { "andS", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG ES prefix */ + { "daa", XX, XX, XX }, + /* 28 */ + { "subB", Eb, Gb, XX }, + { "subS", Ev, Gv, XX }, + { "subB", Gb, Eb, XX }, + { "subS", Gv, Ev, XX }, + { "subB", AL, Ib, XX }, + { "subS", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG CS prefix */ + { "das", XX, XX, XX }, + /* 30 */ + { "xorB", Eb, Gb, XX }, + { "xorS", Ev, Gv, XX }, + { "xorB", Gb, Eb, XX }, + { "xorS", Gv, Ev, XX }, + { "xorB", AL, Ib, XX }, + { "xorS", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG SS prefix */ + { "aaa", XX, XX, XX }, + /* 38 */ + { "cmpB", Eb, Gb, XX }, + { "cmpS", Ev, Gv, XX }, + { "cmpB", Gb, Eb, XX }, + { "cmpS", Gv, Ev, XX }, + { "cmpB", AL, Ib, XX }, + { "cmpS", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG DS prefix */ + { "aas", XX, XX, XX }, + /* 40 */ + { "incS", eAX, XX, XX }, + { "incS", eCX, XX, XX }, + { "incS", eDX, XX, XX }, + { "incS", eBX, XX, XX }, + { "incS", eSP, XX, XX }, + { "incS", eBP, XX, XX }, + { "incS", eSI, XX, XX }, + { "incS", eDI, XX, XX }, + /* 48 */ + { "decS", eAX, XX, XX }, + { "decS", eCX, XX, XX }, + { "decS", eDX, XX, XX }, + { "decS", eBX, XX, XX }, + { "decS", eSP, XX, XX }, + { "decS", eBP, XX, XX }, + { "decS", eSI, XX, XX }, + { "decS", eDI, XX, XX }, + /* 50 */ + { "pushS", eAX, XX, XX }, + { "pushS", eCX, XX, XX }, + { "pushS", eDX, XX, XX }, + { "pushS", eBX, XX, XX }, + { "pushS", eSP, XX, XX }, + { "pushS", eBP, XX, XX }, + { "pushS", eSI, XX, XX }, + { "pushS", eDI, XX, XX }, + /* 58 */ + { "popS", eAX, XX, XX }, + { "popS", eCX, XX, XX }, + { "popS", eDX, XX, XX }, + { "popS", eBX, XX, XX }, + { "popS", eSP, XX, XX }, + { "popS", eBP, XX, XX }, + { "popS", eSI, XX, XX }, + { "popS", eDI, XX, XX }, + /* 60 */ + { "pushaP", XX, XX, XX }, + { "popaP", XX, XX, XX }, + { "boundS", Gv, Ma, XX }, + { "arpl", Ew, Gw, XX }, + { "(bad)", XX, XX, XX }, /* seg fs */ + { "(bad)", XX, XX, XX }, /* seg gs */ + { "(bad)", XX, XX, XX }, /* op size prefix */ + { "(bad)", XX, XX, XX }, /* adr size prefix */ + /* 68 */ + { "pushP", Iv, XX, XX }, /* 386 book wrong */ + { "imulS", Gv, Ev, Iv }, + { "pushP", sIb, XX, XX }, /* push of byte really pushes 2 or 4 bytes */ + { "imulS", Gv, Ev, sIb }, + { "insb", Yb, indirDX, XX }, + { "insR", Yv, indirDX, XX }, + { "outsb", indirDX, Xb, XX }, + { "outsR", indirDX, Xv, XX }, + /* 70 */ + { "jo", Jb, XX, XX }, + { "jno", Jb, XX, XX }, + { "jb", Jb, XX, XX }, + { "jae", Jb, XX, XX }, + { "je", Jb, XX, XX }, + { "jne", Jb, XX, XX }, + { "jbe", Jb, XX, XX }, + { "ja", Jb, XX, XX }, + /* 78 */ + { "js", Jb, XX, XX }, + { "jns", Jb, XX, XX }, + { "jp", Jb, XX, XX }, + { "jnp", Jb, XX, XX }, + { "jl", Jb, XX, XX }, + { "jge", Jb, XX, XX }, + { "jle", Jb, XX, XX }, + { "jg", Jb, XX, XX }, + /* 80 */ + { GRP1b }, + { GRP1S }, + { "(bad)", XX, XX, XX }, + { GRP1Ss }, + { "testB", Eb, Gb, XX }, + { "testS", Ev, Gv, XX }, + { "xchgB", Eb, Gb, XX }, + { "xchgS", Ev, Gv, XX }, + /* 88 */ + { "movB", Eb, Gb, XX }, + { "movS", Ev, Gv, XX }, + { "movB", Gb, Eb, XX }, + { "movS", Gv, Ev, XX }, + { "movQ", Ev, Sw, XX }, + { "leaS", Gv, M, XX }, + { "movQ", Sw, Ev, XX }, + { "popQ", Ev, XX, XX }, + /* 90 */ + { "nop", XX, XX, XX }, + { "xchgS", eCX, eAX, XX }, + { "xchgS", eDX, eAX, XX }, + { "xchgS", eBX, eAX, XX }, + { "xchgS", eSP, eAX, XX }, + { "xchgS", eBP, eAX, XX }, + { "xchgS", eSI, eAX, XX }, + { "xchgS", eDI, eAX, XX }, + /* 98 */ + { "cWtR", XX, XX, XX }, + { "cRtd", XX, XX, XX }, + { "lcallP", Ap, XX, XX }, + { "(bad)", XX, XX, XX }, /* fwait */ + { "pushfP", XX, XX, XX }, + { "popfP", XX, XX, XX }, + { "sahf", XX, XX, XX }, + { "lahf", XX, XX, XX }, + /* a0 */ + { "movB", AL, Ob, XX }, + { "movS", eAX, Ov, XX }, + { "movB", Ob, AL, XX }, + { "movS", Ov, eAX, XX }, + { "movsb", Yb, Xb, XX }, + { "movsR", Yv, Xv, XX }, + { "cmpsb", Xb, Yb, XX }, + { "cmpsR", Xv, Yv, XX }, + /* a8 */ + { "testB", AL, Ib, XX }, + { "testS", eAX, Iv, XX }, + { "stosB", Yb, AL, XX }, + { "stosS", Yv, eAX, XX }, + { "lodsB", AL, Xb, XX }, + { "lodsS", eAX, Xv, XX }, + { "scasB", AL, Yb, XX }, + { "scasS", eAX, Yv, XX }, + /* b0 */ + { "movB", AL, Ib, XX }, + { "movB", CL, Ib, XX }, + { "movB", DL, Ib, XX }, + { "movB", BL, Ib, XX }, + { "movB", AH, Ib, XX }, + { "movB", CH, Ib, XX }, + { "movB", DH, Ib, XX }, + { "movB", BH, Ib, XX }, + /* b8 */ + { "movS", eAX, Iv, XX }, + { "movS", eCX, Iv, XX }, + { "movS", eDX, Iv, XX }, + { "movS", eBX, Iv, XX }, + { "movS", eSP, Iv, XX }, + { "movS", eBP, Iv, XX }, + { "movS", eSI, Iv, XX }, + { "movS", eDI, Iv, XX }, + /* c0 */ + { GRP2b }, + { GRP2S }, + { "retP", Iw, XX, XX }, + { "retP", XX, XX, XX }, + { "lesS", Gv, Mp, XX }, + { "ldsS", Gv, Mp, XX }, + { "movA", Eb, Ib, XX }, + { "movQ", Ev, Iv, XX }, + /* c8 */ + { "enterP", Iw, Ib, XX }, + { "leaveP", XX, XX, XX }, + { "lretP", Iw, XX, XX }, + { "lretP", XX, XX, XX }, + { "int3", XX, XX, XX }, + { "int", Ib, XX, XX }, + { "into", XX, XX, XX}, + { "iretP", XX, XX, XX }, + /* d0 */ + { GRP2b_one }, + { GRP2S_one }, + { GRP2b_cl }, + { GRP2S_cl }, + { "aam", sIb, XX, XX }, + { "aad", sIb, XX, XX }, + { "(bad)", XX, XX, XX }, + { "xlat", DSBX, XX, XX }, + /* d8 */ + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + /* e0 */ + { "loopne", Jb, XX, XX }, + { "loope", Jb, XX, XX }, + { "loop", Jb, XX, XX }, + { "jEcxz", Jb, XX, XX }, + { "inB", AL, Ib, XX }, + { "inS", eAX, Ib, XX }, + { "outB", Ib, AL, XX }, + { "outS", Ib, eAX, XX }, + /* e8 */ + { "callP", Jv, XX, XX }, + { "jmpP", Jv, XX, XX }, + { "ljmpP", Ap, XX, XX }, + { "jmp", Jb, XX, XX }, + { "inB", AL, indirDX, XX }, + { "inS", eAX, indirDX, XX }, + { "outB", indirDX, AL, XX }, + { "outS", indirDX, eAX, XX }, + /* f0 */ + { "(bad)", XX, XX, XX }, /* lock prefix */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, /* repne */ + { "(bad)", XX, XX, XX }, /* repz */ + { "hlt", XX, XX, XX }, + { "cmc", XX, XX, XX }, + { GRP3b }, + { GRP3S }, + /* f8 */ + { "clc", XX, XX, XX }, + { "stc", XX, XX, XX }, + { "cli", XX, XX, XX }, + { "sti", XX, XX, XX }, + { "cld", XX, XX, XX }, + { "std", XX, XX, XX }, + { GRP4 }, + { GRP5 }, +}; + +static const struct dis386 dis386_intel[] = { + /* 00 */ + { "add", Eb, Gb, XX }, + { "add", Ev, Gv, XX }, + { "add", Gb, Eb, XX }, + { "add", Gv, Ev, XX }, + { "add", AL, Ib, XX }, + { "add", eAX, Iv, XX }, + { "push", es, XX, XX }, + { "pop", es, XX, XX }, + /* 08 */ + { "or", Eb, Gb, XX }, + { "or", Ev, Gv, XX }, + { "or", Gb, Eb, XX }, + { "or", Gv, Ev, XX }, + { "or", AL, Ib, XX }, + { "or", eAX, Iv, XX }, + { "push", cs, XX, XX }, + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ + /* 10 */ + { "adc", Eb, Gb, XX }, + { "adc", Ev, Gv, XX }, + { "adc", Gb, Eb, XX }, + { "adc", Gv, Ev, XX }, + { "adc", AL, Ib, XX }, + { "adc", eAX, Iv, XX }, + { "push", ss, XX, XX }, + { "pop", ss, XX, XX }, + /* 18 */ + { "sbb", Eb, Gb, XX }, + { "sbb", Ev, Gv, XX }, + { "sbb", Gb, Eb, XX }, + { "sbb", Gv, Ev, XX }, + { "sbb", AL, Ib, XX }, + { "sbb", eAX, Iv, XX }, + { "push", ds, XX, XX }, + { "pop", ds, XX, XX }, + /* 20 */ + { "and", Eb, Gb, XX }, + { "and", Ev, Gv, XX }, + { "and", Gb, Eb, XX }, + { "and", Gv, Ev, XX }, + { "and", AL, Ib, XX }, + { "and", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG ES prefix */ + { "daa", XX, XX, XX }, + /* 28 */ + { "sub", Eb, Gb, XX }, + { "sub", Ev, Gv, XX }, + { "sub", Gb, Eb, XX }, + { "sub", Gv, Ev, XX }, + { "sub", AL, Ib, XX }, + { "sub", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG CS prefix */ + { "das", XX, XX, XX }, + /* 30 */ + { "xor", Eb, Gb, XX }, + { "xor", Ev, Gv, XX }, + { "xor", Gb, Eb, XX }, + { "xor", Gv, Ev, XX }, + { "xor", AL, Ib, XX }, + { "xor", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG SS prefix */ + { "aaa", XX, XX, XX }, + /* 38 */ + { "cmp", Eb, Gb, XX }, + { "cmp", Ev, Gv, XX }, + { "cmp", Gb, Eb, XX }, + { "cmp", Gv, Ev, XX }, + { "cmp", AL, Ib, XX }, + { "cmp", eAX, Iv, XX }, + { "(bad)", XX, XX, XX }, /* SEG DS prefix */ + { "aas", XX, XX, XX }, + /* 40 */ + { "inc", eAX, XX, XX }, + { "inc", eCX, XX, XX }, + { "inc", eDX, XX, XX }, + { "inc", eBX, XX, XX }, + { "inc", eSP, XX, XX }, + { "inc", eBP, XX, XX }, + { "inc", eSI, XX, XX }, + { "inc", eDI, XX, XX }, + /* 48 */ + { "dec", eAX, XX, XX }, + { "dec", eCX, XX, XX }, + { "dec", eDX, XX, XX }, + { "dec", eBX, XX, XX }, + { "dec", eSP, XX, XX }, + { "dec", eBP, XX, XX }, + { "dec", eSI, XX, XX }, + { "dec", eDI, XX, XX }, + /* 50 */ + { "push", eAX, XX, XX }, + { "push", eCX, XX, XX }, + { "push", eDX, XX, XX }, + { "push", eBX, XX, XX }, + { "push", eSP, XX, XX }, + { "push", eBP, XX, XX }, + { "push", eSI, XX, XX }, + { "push", eDI, XX, XX }, + /* 58 */ + { "pop", eAX, XX, XX }, + { "pop", eCX, XX, XX }, + { "pop", eDX, XX, XX }, + { "pop", eBX, XX, XX }, + { "pop", eSP, XX, XX }, + { "pop", eBP, XX, XX }, + { "pop", eSI, XX, XX }, + { "pop", eDI, XX, XX }, + /* 60 */ + { "pusha", XX, XX, XX }, + { "popa", XX, XX, XX }, + { "bound", Gv, Ma, XX }, + { "arpl", Ew, Gw, XX }, + { "(bad)", XX, XX, XX }, /* seg fs */ + { "(bad)", XX, XX, XX }, /* seg gs */ + { "(bad)", XX, XX, XX }, /* op size prefix */ + { "(bad)", XX, XX, XX }, /* adr size prefix */ + /* 68 */ + { "push", Iv, XX, XX }, /* 386 book wrong */ + { "imul", Gv, Ev, Iv }, + { "push", sIb, XX, XX }, /* push of byte really pushes 2 or 4 bytes */ + { "imul", Gv, Ev, sIb }, + { "ins", Yb, indirDX, XX }, + { "ins", Yv, indirDX, XX }, + { "outs", indirDX, Xb, XX }, + { "outs", indirDX, Xv, XX }, + /* 70 */ + { "jo", Jb, XX, XX }, + { "jno", Jb, XX, XX }, + { "jb", Jb, XX, XX }, + { "jae", Jb, XX, XX }, + { "je", Jb, XX, XX }, + { "jne", Jb, XX, XX }, + { "jbe", Jb, XX, XX }, + { "ja", Jb, XX, XX }, + /* 78 */ + { "js", Jb, XX, XX }, + { "jns", Jb, XX, XX }, + { "jp", Jb, XX, XX }, + { "jnp", Jb, XX, XX }, + { "jl", Jb, XX, XX }, + { "jge", Jb, XX, XX }, + { "jle", Jb, XX, XX }, + { "jg", Jb, XX, XX }, + /* 80 */ + { GRP1b }, + { GRP1S }, + { "(bad)", XX, XX, XX }, + { GRP1Ss }, + { "test", Eb, Gb, XX }, + { "test", Ev, Gv, XX }, + { "xchg", Eb, Gb, XX }, + { "xchg", Ev, Gv, XX }, + /* 88 */ + { "mov", Eb, Gb, XX }, + { "mov", Ev, Gv, XX }, + { "mov", Gb, Eb, XX }, + { "mov", Gv, Ev, XX }, + { "mov", Ev, Sw, XX }, + { "lea", Gv, M, XX }, + { "mov", Sw, Ev, XX }, + { "pop", Ev, XX, XX }, + /* 90 */ + { "nop", XX, XX, XX }, + { "xchg", eCX, eAX, XX }, + { "xchg", eDX, eAX, XX }, + { "xchg", eBX, eAX, XX }, + { "xchg", eSP, eAX, XX }, + { "xchg", eBP, eAX, XX }, + { "xchg", eSI, eAX, XX }, + { "xchg", eDI, eAX, XX }, + /* 98 */ + { "cW", XX, XX, XX }, /* cwde and cbw */ + { "cR", XX, XX, XX }, /* cdq and cwd */ + { "lcall", Ap, XX, XX }, + { "(bad)", XX, XX, XX }, /* fwait */ + { "pushf", XX, XX, XX }, + { "popf", XX, XX, XX }, + { "sahf", XX, XX, XX }, + { "lahf", XX, XX, XX }, + /* a0 */ + { "mov", AL, Ob, XX }, + { "mov", eAX, Ov, XX }, + { "mov", Ob, AL, XX }, + { "mov", Ov, eAX, XX }, + { "movs", Yb, Xb, XX }, + { "movs", Yv, Xv, XX }, + { "cmps", Xb, Yb, XX }, + { "cmps", Xv, Yv, XX }, + /* a8 */ + { "test", AL, Ib, XX }, + { "test", eAX, Iv, XX }, + { "stos", Yb, AL, XX }, + { "stos", Yv, eAX, XX }, + { "lods", AL, Xb, XX }, + { "lods", eAX, Xv, XX }, + { "scas", AL, Yb, XX }, + { "scas", eAX, Yv, XX }, + /* b0 */ + { "mov", AL, Ib, XX }, + { "mov", CL, Ib, XX }, + { "mov", DL, Ib, XX }, + { "mov", BL, Ib, XX }, + { "mov", AH, Ib, XX }, + { "mov", CH, Ib, XX }, + { "mov", DH, Ib, XX }, + { "mov", BH, Ib, XX }, + /* b8 */ + { "mov", eAX, Iv, XX }, + { "mov", eCX, Iv, XX }, + { "mov", eDX, Iv, XX }, + { "mov", eBX, Iv, XX }, + { "mov", eSP, Iv, XX }, + { "mov", eBP, Iv, XX }, + { "mov", eSI, Iv, XX }, + { "mov", eDI, Iv, XX }, + /* c0 */ + { GRP2b }, + { GRP2S }, + { "ret", Iw, XX, XX }, + { "ret", XX, XX, XX }, + { "les", Gv, Mp, XX }, + { "lds", Gv, Mp, XX }, + { "mov", Eb, Ib, XX }, + { "mov", Ev, Iv, XX }, + /* c8 */ + { "enter", Iw, Ib, XX }, + { "leave", XX, XX, XX }, + { "lret", Iw, XX, XX }, + { "lret", XX, XX, XX }, + { "int3", XX, XX, XX }, + { "int", Ib, XX, XX }, + { "into", XX, XX, XX }, + { "iret", XX, XX, XX }, + /* d0 */ + { GRP2b_one }, + { GRP2S_one }, + { GRP2b_cl }, + { GRP2S_cl }, + { "aam", sIb, XX, XX }, + { "aad", sIb, XX, XX }, + { "(bad)", XX, XX, XX }, + { "xlat", DSBX, XX, XX }, + /* d8 */ + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + { FLOAT }, + /* e0 */ + { "loopne", Jb, XX, XX }, + { "loope", Jb, XX, XX }, + { "loop", Jb, XX, XX }, + { "jEcxz", Jb, XX, XX }, + { "in", AL, Ib, XX }, + { "in", eAX, Ib, XX }, + { "out", Ib, AL, XX }, + { "out", Ib, eAX, XX }, + /* e8 */ + { "call", Jv, XX, XX }, + { "jmp", Jv, XX, XX }, + { "ljmp", Ap, XX, XX }, + { "jmp", Jb, XX, XX }, + { "in", AL, indirDX, XX }, + { "in", eAX, indirDX, XX }, + { "out", indirDX, AL, XX }, + { "out", indirDX, eAX, XX }, + /* f0 */ + { "(bad)", XX, XX, XX }, /* lock prefix */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, /* repne */ + { "(bad)", XX, XX, XX }, /* repz */ + { "hlt", XX, XX, XX }, + { "cmc", XX, XX, XX }, + { GRP3b }, + { GRP3S }, + /* f8 */ + { "clc", XX, XX, XX }, + { "stc", XX, XX, XX }, + { "cli", XX, XX, XX }, + { "sti", XX, XX, XX }, + { "cld", XX, XX, XX }, + { "std", XX, XX, XX }, + { GRP4 }, + { GRP5 }, +}; + +static const struct dis386 dis386_twobyte_att[] = { + /* 00 */ + { GRP6 }, + { GRP7 }, + { "larS", Gv, Ew, XX }, + { "lslS", Gv, Ew, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "clts", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 08 */ + { "invd", XX, XX, XX }, + { "wbinvd", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "ud2a", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { GRPAMD }, + { "femms", XX, XX, XX }, + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */ + /* 10 */ + { PREGRP8 }, + { PREGRP9 }, + { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlps", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklps", XM, EX, XX }, + { "unpckhps", XM, EX, XX }, + { "movhps", XM, EX, SIMD_Fixup, 'l' }, + { "movhps", EX, XM, SIMD_Fixup, 'l' }, + /* 18 */ + { GRP14 }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 20 */ + /* these are all backward in appendix A of the intel book */ + { "movL", Rd, Cd, XX }, + { "movL", Rd, Dd, XX }, + { "movL", Cd, Rd, XX }, + { "movL", Dd, Rd, XX }, + { "movL", Rd, Td, XX }, + { "(bad)", XX, XX, XX }, + { "movL", Td, Rd, XX }, + { "(bad)", XX, XX, XX }, + /* 28 */ + { "movaps", XM, EX, XX }, + { "movaps", EX, XM, XX }, + { PREGRP2 }, + { "movntps", Ev, XM, XX }, + { PREGRP4 }, + { PREGRP3 }, + { "ucomiss", XM, EX, XX }, + { "comiss", XM, EX, XX }, + /* 30 */ + { "wrmsr", XX, XX, XX }, + { "rdtsc", XX, XX, XX }, + { "rdmsr", XX, XX, XX }, + { "rdpmc", XX, XX, XX }, + { "sysenter", XX, XX, XX }, + { "sysexit", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 38 */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 40 */ + { "cmovo", Gv, Ev, XX }, + { "cmovno", Gv, Ev, XX }, + { "cmovb", Gv, Ev, XX }, + { "cmovae", Gv, Ev, XX }, + { "cmove", Gv, Ev, XX }, + { "cmovne", Gv, Ev, XX }, + { "cmovbe", Gv, Ev, XX }, + { "cmova", Gv, Ev, XX }, + /* 48 */ + { "cmovs", Gv, Ev, XX }, + { "cmovns", Gv, Ev, XX }, + { "cmovp", Gv, Ev, XX }, + { "cmovnp", Gv, Ev, XX }, + { "cmovl", Gv, Ev, XX }, + { "cmovge", Gv, Ev, XX }, + { "cmovle", Gv, Ev, XX }, + { "cmovg", Gv, Ev, XX }, + /* 50 */ + { "movmskps", Gv, EX, XX }, + { PREGRP13 }, + { PREGRP12 }, + { PREGRP11 }, + { "andps", XM, EX, XX }, + { "andnps", XM, EX, XX }, + { "orps", XM, EX, XX }, + { "xorps", XM, EX, XX }, + /* 58 */ + { PREGRP0 }, + { PREGRP10 }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { PREGRP14 }, + { PREGRP7 }, + { PREGRP5 }, + { PREGRP6 }, + /* 60 */ + { "punpcklbw", MX, EM, XX }, + { "punpcklwd", MX, EM, XX }, + { "punpckldq", MX, EM, XX }, + { "packsswb", MX, EM, XX }, + { "pcmpgtb", MX, EM, XX }, + { "pcmpgtw", MX, EM, XX }, + { "pcmpgtd", MX, EM, XX }, + { "packuswb", MX, EM, XX }, + /* 68 */ + { "punpckhbw", MX, EM, XX }, + { "punpckhwd", MX, EM, XX }, + { "punpckhdq", MX, EM, XX }, + { "packssdw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "movd", MX, Ed, XX }, + { "movq", MX, EM, XX }, + /* 70 */ + { "pshufw", MX, EM, Ib }, + { GRP10 }, + { GRP11 }, + { GRP12 }, + { "pcmpeqb", MX, EM, XX }, + { "pcmpeqw", MX, EM, XX }, + { "pcmpeqd", MX, EM, XX }, + { "emms", XX, XX, XX }, + /* 78 */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "movd", Ed, MX, XX }, + { "movq", EM, MX, XX }, + /* 80 */ + { "jo", Jv, XX, XX }, + { "jno", Jv, XX, XX }, + { "jb", Jv, XX, XX }, + { "jae", Jv, XX, XX }, + { "je", Jv, XX, XX }, + { "jne", Jv, XX, XX }, + { "jbe", Jv, XX, XX }, + { "ja", Jv, XX, XX }, + /* 88 */ + { "js", Jv, XX, XX }, + { "jns", Jv, XX, XX }, + { "jp", Jv, XX, XX }, + { "jnp", Jv, XX, XX }, + { "jl", Jv, XX, XX }, + { "jge", Jv, XX, XX }, + { "jle", Jv, XX, XX }, + { "jg", Jv, XX, XX }, + /* 90 */ + { "seto", Eb, XX, XX }, + { "setno", Eb, XX, XX }, + { "setb", Eb, XX, XX }, + { "setae", Eb, XX, XX }, + { "sete", Eb, XX, XX }, + { "setne", Eb, XX, XX }, + { "setbe", Eb, XX, XX }, + { "seta", Eb, XX, XX }, + /* 98 */ + { "sets", Eb, XX, XX }, + { "setns", Eb, XX, XX }, + { "setp", Eb, XX, XX }, + { "setnp", Eb, XX, XX }, + { "setl", Eb, XX, XX }, + { "setge", Eb, XX, XX }, + { "setle", Eb, XX, XX }, + { "setg", Eb, XX, XX }, + /* a0 */ + { "pushP", fs, XX, XX }, + { "popP", fs, XX, XX }, + { "cpuid", XX, XX, XX }, + { "btS", Ev, Gv, XX }, + { "shldS", Ev, Gv, Ib }, + { "shldS", Ev, Gv, CL }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* a8 */ + { "pushP", gs, XX, XX }, + { "popP", gs, XX, XX }, + { "rsm", XX, XX, XX }, + { "btsS", Ev, Gv, XX }, + { "shrdS", Ev, Gv, Ib }, + { "shrdS", Ev, Gv, CL }, + { GRP13 }, + { "imulS", Gv, Ev, XX }, + /* b0 */ + { "cmpxchgB", Eb, Gb, XX }, + { "cmpxchgS", Ev, Gv, XX }, + { "lssS", Gv, Mp, XX }, + { "btrS", Ev, Gv, XX }, + { "lfsS", Gv, Mp, XX }, + { "lgsS", Gv, Mp, XX }, + { "movzbR", Gv, Eb, XX }, + { "movzwR", Gv, Ew, XX }, /* yes, there really is movzww ! */ + /* b8 */ + { "(bad)", XX, XX, XX }, + { "ud2b", XX, XX, XX }, + { GRP8 }, + { "btcS", Ev, Gv, XX }, + { "bsfS", Gv, Ev, XX }, + { "bsrS", Gv, Ev, XX }, + { "movsbR", Gv, Eb, XX }, + { "movswR", Gv, Ew, XX }, /* yes, there really is movsww ! */ + /* c0 */ + { "xaddB", Eb, Gb, XX }, + { "xaddS", Ev, Gv, XX }, + { PREGRP1 }, + { "(bad)", XX, XX, XX }, + { "pinsrw", MX, Ev, Ib }, + { "pextrw", Ev, MX, Ib }, + { "shufps", XM, EX, Ib }, + { GRP9 }, + /* c8 */ + { "bswap", eAX, XX, XX }, /* bswap doesn't support 16 bit regs */ + { "bswap", eCX, XX, XX }, + { "bswap", eDX, XX, XX }, + { "bswap", eBX, XX, XX }, + { "bswap", eSP, XX, XX }, + { "bswap", eBP, XX, XX }, + { "bswap", eSI, XX, XX }, + { "bswap", eDI, XX, XX }, + /* d0 */ + { "(bad)", XX, XX, XX }, + { "psrlw", MX, EM, XX }, + { "psrld", MX, EM, XX }, + { "psrlq", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmullw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmovmskb", Ev, MX, XX }, + /* d8 */ + { "psubusb", MX, EM, XX }, + { "psubusw", MX, EM, XX }, + { "pminub", MX, EM, XX }, + { "pand", MX, EM, XX }, + { "paddusb", MX, EM, XX }, + { "paddusw", MX, EM, XX }, + { "pmaxub", MX, EM, XX }, + { "pandn", MX, EM, XX }, + /* e0 */ + { "pavgb", MX, EM, XX }, + { "psraw", MX, EM, XX }, + { "psrad", MX, EM, XX }, + { "pavgw", MX, EM, XX }, + { "pmulhuw", MX, EM, XX }, + { "pmulhw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "movntq", Ev, MX, XX }, + /* e8 */ + { "psubsb", MX, EM, XX }, + { "psubsw", MX, EM, XX }, + { "pminsw", MX, EM, XX }, + { "por", MX, EM, XX }, + { "paddsb", MX, EM, XX }, + { "paddsw", MX, EM, XX }, + { "pmaxsw", MX, EM, XX }, + { "pxor", MX, EM, XX }, + /* f0 */ + { "(bad)", XX, XX, XX }, + { "psllw", MX, EM, XX }, + { "pslld", MX, EM, XX }, + { "psllq", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmaddwd", MX, EM, XX }, + { "psadbw", MX, EM, XX }, + { "maskmovq", MX, EM, XX }, + /* f8 */ + { "psubb", MX, EM, XX }, + { "psubw", MX, EM, XX }, + { "psubd", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "paddb", MX, EM, XX }, + { "paddw", MX, EM, XX }, + { "paddd", MX, EM, XX }, + { "(bad)", XX, XX, XX } +}; + +static const struct dis386 dis386_twobyte_intel[] = { + /* 00 */ + { GRP6 }, + { GRP7 }, + { "lar", Gv, Ew, XX }, + { "lsl", Gv, Ew, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "clts", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 08 */ + { "invd", XX, XX, XX }, + { "wbinvd", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "ud2a", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { GRPAMD }, + { "femms" , XX, XX, XX}, + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */ + /* 10 */ + { PREGRP8 }, + { PREGRP9 }, + { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ + { "movlps", EX, XM, SIMD_Fixup, 'h' }, + { "unpcklps", XM, EX, XX }, + { "unpckhps", XM, EX, XX }, + { "movhps", XM, EX, SIMD_Fixup, 'l' }, + { "movhps", EX, XM, SIMD_Fixup, 'l' }, + /* 18 */ + { GRP14 }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 20 */ + /* these are all backward in appendix A of the intel book */ + { "mov", Rd, Cd, XX }, + { "mov", Rd, Dd, XX }, + { "mov", Cd, Rd, XX }, + { "mov", Dd, Rd, XX }, + { "mov", Rd, Td, XX }, + { "(bad)", XX, XX, XX }, + { "mov", Td, Rd, XX }, + { "(bad)", XX, XX, XX }, + /* 28 */ + { "movaps", XM, EX, XX }, + { "movaps", EX, XM, XX }, + { PREGRP2 }, + { "movntps", Ev, XM, XX }, + { PREGRP4 }, + { PREGRP3 }, + { "ucomiss", XM, EX, XX }, + { "comiss", XM, EX, XX }, + /* 30 */ + { "wrmsr", XX, XX, XX }, + { "rdtsc", XX, XX, XX }, + { "rdmsr", XX, XX, XX }, + { "rdpmc", XX, XX, XX }, + { "sysenter", XX, XX, XX }, + { "sysexit", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 38 */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* 40 */ + { "cmovo", Gv, Ev, XX }, + { "cmovno", Gv, Ev, XX }, + { "cmovb", Gv, Ev, XX }, + { "cmovae", Gv, Ev, XX }, + { "cmove", Gv, Ev, XX }, + { "cmovne", Gv, Ev, XX }, + { "cmovbe", Gv, Ev, XX }, + { "cmova", Gv, Ev, XX }, + /* 48 */ + { "cmovs", Gv, Ev, XX }, + { "cmovns", Gv, Ev, XX }, + { "cmovp", Gv, Ev, XX }, + { "cmovnp", Gv, Ev, XX }, + { "cmovl", Gv, Ev, XX }, + { "cmovge", Gv, Ev, XX }, + { "cmovle", Gv, Ev, XX }, + { "cmovg", Gv, Ev, XX }, + /* 50 */ + { "movmskps", Gv, EX, XX }, + { PREGRP13 }, + { PREGRP12 }, + { PREGRP11 }, + { "andps", XM, EX, XX }, + { "andnps", XM, EX, XX }, + { "orps", XM, EX, XX }, + { "xorps", XM, EX, XX }, + /* 58 */ + { PREGRP0 }, + { PREGRP10 }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { PREGRP14 }, + { PREGRP7 }, + { PREGRP5 }, + { PREGRP6 }, + /* 60 */ + { "punpcklbw", MX, EM, XX }, + { "punpcklwd", MX, EM, XX }, + { "punpckldq", MX, EM, XX }, + { "packsswb", MX, EM, XX }, + { "pcmpgtb", MX, EM, XX }, + { "pcmpgtw", MX, EM, XX }, + { "pcmpgtd", MX, EM, XX }, + { "packuswb", MX, EM, XX }, + /* 68 */ + { "punpckhbw", MX, EM, XX }, + { "punpckhwd", MX, EM, XX }, + { "punpckhdq", MX, EM, XX }, + { "packssdw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "movd", MX, Ed, XX }, + { "movq", MX, EM, XX }, + /* 70 */ + { "pshufw", MX, EM, Ib }, + { GRP10 }, + { GRP11 }, + { GRP12 }, + { "pcmpeqb", MX, EM, XX }, + { "pcmpeqw", MX, EM, XX }, + { "pcmpeqd", MX, EM, XX }, + { "emms", XX, XX, XX }, + /* 78 */ + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "movd", Ed, MX, XX }, + { "movq", EM, MX, XX }, + /* 80 */ + { "jo", Jv, XX, XX }, + { "jno", Jv, XX, XX }, + { "jb", Jv, XX, XX }, + { "jae", Jv, XX, XX }, + { "je", Jv, XX, XX }, + { "jne", Jv, XX, XX }, + { "jbe", Jv, XX, XX }, + { "ja", Jv, XX, XX }, + /* 88 */ + { "js", Jv, XX, XX }, + { "jns", Jv, XX, XX }, + { "jp", Jv, XX, XX }, + { "jnp", Jv, XX, XX }, + { "jl", Jv, XX, XX }, + { "jge", Jv, XX, XX }, + { "jle", Jv, XX, XX }, + { "jg", Jv, XX, XX }, + /* 90 */ + { "seto", Eb, XX, XX }, + { "setno", Eb, XX, XX }, + { "setb", Eb, XX, XX }, + { "setae", Eb, XX, XX }, + { "sete", Eb, XX, XX }, + { "setne", Eb, XX, XX }, + { "setbe", Eb, XX, XX }, + { "seta", Eb, XX, XX }, + /* 98 */ + { "sets", Eb, XX, XX }, + { "setns", Eb, XX, XX }, + { "setp", Eb, XX, XX }, + { "setnp", Eb, XX, XX }, + { "setl", Eb, XX, XX }, + { "setge", Eb, XX, XX }, + { "setle", Eb, XX, XX }, + { "setg", Eb, XX, XX }, + /* a0 */ + { "push", fs, XX, XX }, + { "pop", fs, XX, XX }, + { "cpuid", XX, XX, XX }, + { "bt", Ev, Gv, XX }, + { "shld", Ev, Gv, Ib }, + { "shld", Ev, Gv, CL }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + /* a8 */ + { "push", gs, XX, XX }, + { "pop", gs, XX, XX }, + { "rsm" , XX, XX, XX}, + { "bts", Ev, Gv, XX }, + { "shrd", Ev, Gv, Ib }, + { "shrd", Ev, Gv, CL }, + { GRP13 }, + { "imul", Gv, Ev, XX }, + /* b0 */ + { "cmpxchg", Eb, Gb, XX }, + { "cmpxchg", Ev, Gv, XX }, + { "lss", Gv, Mp, XX }, + { "btr", Ev, Gv, XX }, + { "lfs", Gv, Mp, XX }, + { "lgs", Gv, Mp, XX }, + { "movzx", Gv, Eb, XX }, + { "movzx", Gv, Ew, XX }, + /* b8 */ + { "(bad)", XX, XX, XX }, + { "ud2b", XX, XX, XX }, + { GRP8 }, + { "btc", Ev, Gv, XX }, + { "bsf", Gv, Ev, XX }, + { "bsr", Gv, Ev, XX }, + { "movsx", Gv, Eb, XX }, + { "movsx", Gv, Ew, XX }, + /* c0 */ + { "xadd", Eb, Gb, XX }, + { "xadd", Ev, Gv, XX }, + { PREGRP1 }, + { "(bad)", XX, XX, XX }, + { "pinsrw", MX, Ev, Ib }, + { "pextrw", Ev, MX, Ib }, + { "shufps", XM, EX, Ib }, + { GRP9 }, + /* c8 */ + { "bswap", eAX, XX, XX }, /* bswap doesn't support 16 bit regs */ + { "bswap", eCX, XX, XX }, + { "bswap", eDX, XX, XX }, + { "bswap", eBX, XX, XX }, + { "bswap", eSP, XX, XX }, + { "bswap", eBP, XX, XX }, + { "bswap", eSI, XX, XX }, + { "bswap", eDI, XX, XX }, + /* d0 */ + { "(bad)", XX, XX, XX }, + { "psrlw", MX, EM, XX }, + { "psrld", MX, EM, XX }, + { "psrlq", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmullw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmovmskb", Ev, MX, XX }, + /* d8 */ + { "psubusb", MX, EM, XX }, + { "psubusw", MX, EM, XX }, + { "pminub", MX, EM, XX }, + { "pand", MX, EM, XX }, + { "paddusb", MX, EM, XX }, + { "paddusw", MX, EM, XX }, + { "pmaxub", MX, EM, XX }, + { "pandn", MX, EM, XX }, + /* e0 */ + { "pavgb", MX, EM, XX }, + { "psraw", MX, EM, XX }, + { "psrad", MX, EM, XX }, + { "pavgw", MX, EM, XX }, + { "pmulhuw", MX, EM, XX }, + { "pmulhw", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "movntq", Ev, MX, XX }, + /* e8 */ + { "psubsb", MX, EM, XX }, + { "psubsw", MX, EM, XX }, + { "pminsw", MX, EM, XX }, + { "por", MX, EM, XX }, + { "paddsb", MX, EM, XX }, + { "paddsw", MX, EM, XX }, + { "pmaxsw", MX, EM, XX }, + { "pxor", MX, EM, XX }, + /* f0 */ + { "(bad)", XX, XX, XX }, + { "psllw", MX, EM, XX }, + { "pslld", MX, EM, XX }, + { "psllq", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "pmaddwd", MX, EM, XX }, + { "psadbw", MX, EM, XX }, + { "maskmovq", MX, EM, XX }, + /* f8 */ + { "psubb", MX, EM, XX }, + { "psubw", MX, EM, XX }, + { "psubd", MX, EM, XX }, + { "(bad)", XX, XX, XX }, + { "paddb", MX, EM, XX }, + { "paddw", MX, EM, XX }, + { "paddd", MX, EM, XX }, + { "(bad)", XX, XX, XX } +}; + +static const struct dis386 dis386_l4[] = { + /* 00 */ + { "", XX, XX, XX }, + { "int3", XX, XX, XX } +}; + +static const unsigned char onebyte_has_modrm[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +}; + +static const unsigned char twobyte_has_modrm[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ + /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */ + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ + /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */ + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */ + /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */ + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ + /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ + /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ + /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */ + /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */ + /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +}; + +static const unsigned char twobyte_uses_f3_prefix[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ + /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */ + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ + /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */ + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */ + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */ + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ + /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */ + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */ + /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +}; + +static char obuf[300]; +static char *obufp; +static char scratchbuf[300]; +static unsigned char *start_codep; +static unsigned char *insn_codep; +static unsigned char *codep; +static disassemble_info *the_info; +static int mod; +static int rm; +static int reg; +static void oappend PARAMS ((const char *s)); + +static const char *names32[]={ + "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi", +}; +static const char *names16[] = { + "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di", +}; +static const char *names8[] = { + "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh", +}; +static const char *names_seg[] = { + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", +}; +static const char *index16[] = { + "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx" +}; + +static const struct dis386 grps[][8] = { + /* GRP1b */ + { + { "addA", Eb, Ib, XX }, + { "orA", Eb, Ib, XX }, + { "adcA", Eb, Ib, XX }, + { "sbbA", Eb, Ib, XX }, + { "andA", Eb, Ib, XX }, + { "subA", Eb, Ib, XX }, + { "xorA", Eb, Ib, XX }, + { "cmpA", Eb, Ib, XX } + }, + /* GRP1S */ + { + { "addQ", Ev, Iv, XX }, + { "orQ", Ev, Iv, XX }, + { "adcQ", Ev, Iv, XX }, + { "sbbQ", Ev, Iv, XX }, + { "andQ", Ev, Iv, XX }, + { "subQ", Ev, Iv, XX }, + { "xorQ", Ev, Iv, XX }, + { "cmpQ", Ev, Iv, XX } + }, + /* GRP1Ss */ + { + { "addQ", Ev, sIb, XX }, + { "orQ", Ev, sIb, XX }, + { "adcQ", Ev, sIb, XX }, + { "sbbQ", Ev, sIb, XX }, + { "andQ", Ev, sIb, XX }, + { "subQ", Ev, sIb, XX }, + { "xorQ", Ev, sIb, XX }, + { "cmpQ", Ev, sIb, XX } + }, + /* GRP2b */ + { + { "rolA", Eb, Ib, XX }, + { "rorA", Eb, Ib, XX }, + { "rclA", Eb, Ib, XX }, + { "rcrA", Eb, Ib, XX }, + { "shlA", Eb, Ib, XX }, + { "shrA", Eb, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "sarA", Eb, Ib, XX }, + }, + /* GRP2S */ + { + { "rolQ", Ev, Ib, XX }, + { "rorQ", Ev, Ib, XX }, + { "rclQ", Ev, Ib, XX }, + { "rcrQ", Ev, Ib, XX }, + { "shlQ", Ev, Ib, XX }, + { "shrQ", Ev, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "sarQ", Ev, Ib, XX }, + }, + /* GRP2b_one */ + { + { "rolA", Eb, XX, XX }, + { "rorA", Eb, XX, XX }, + { "rclA", Eb, XX, XX }, + { "rcrA", Eb, XX, XX }, + { "shlA", Eb, XX, XX }, + { "shrA", Eb, XX, XX }, + { "(bad)", XX, XX, XX }, + { "sarA", Eb, XX, XX }, + }, + /* GRP2S_one */ + { + { "rolQ", Ev, XX, XX }, + { "rorQ", Ev, XX, XX }, + { "rclQ", Ev, XX, XX }, + { "rcrQ", Ev, XX, XX }, + { "shlQ", Ev, XX, XX }, + { "shrQ", Ev, XX, XX }, + { "(bad)", XX, XX, XX}, + { "sarQ", Ev, XX, XX }, + }, + /* GRP2b_cl */ + { + { "rolA", Eb, CL, XX }, + { "rorA", Eb, CL, XX }, + { "rclA", Eb, CL, XX }, + { "rcrA", Eb, CL, XX }, + { "shlA", Eb, CL, XX }, + { "shrA", Eb, CL, XX }, + { "(bad)", XX, XX, XX }, + { "sarA", Eb, CL, XX }, + }, + /* GRP2S_cl */ + { + { "rolQ", Ev, CL, XX }, + { "rorQ", Ev, CL, XX }, + { "rclQ", Ev, CL, XX }, + { "rcrQ", Ev, CL, XX }, + { "shlQ", Ev, CL, XX }, + { "shrQ", Ev, CL, XX }, + { "(bad)", XX, XX, XX }, + { "sarQ", Ev, CL, XX } + }, + /* GRP3b */ + { + { "testA", Eb, Ib, XX }, + { "(bad)", Eb, XX, XX }, + { "notA", Eb, XX, XX }, + { "negA", Eb, XX, XX }, + { "mulB", AL, Eb, XX }, + { "imulB", AL, Eb, XX }, + { "divB", AL, Eb, XX }, + { "idivB", AL, Eb, XX } + }, + /* GRP3S */ + { + { "testQ", Ev, Iv, XX }, + { "(bad)", XX, XX, XX }, + { "notQ", Ev, XX, XX }, + { "negQ", Ev, XX, XX }, + { "mulS", eAX, Ev, XX }, + { "imulS", eAX, Ev, XX }, + { "divS", eAX, Ev, XX }, + { "idivS", eAX, Ev, XX }, + }, + /* GRP4 */ + { + { "incA", Eb, XX, XX }, + { "decA", Eb, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP5 */ + { + { "incQ", Ev, XX, XX }, + { "decQ", Ev, XX, XX }, + { "callP", indirEv, XX, XX }, + { "lcallP", indirEv, XX, XX }, + { "jmpP", indirEv, XX, XX }, + { "ljmpP", indirEv, XX, XX }, + { "pushQ", Ev, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP6 */ + { + { "sldt", Ew, XX, XX }, + { "str", Ew, XX, XX }, + { "lldt", Ew, XX, XX }, + { "ltr", Ew, XX, XX }, + { "verr", Ew, XX, XX }, + { "verw", Ew, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX } + }, + /* GRP7 */ + { + { "sgdt", Ew, XX, XX }, + { "sidt", Ew, XX, XX }, + { "lgdt", Ew, XX, XX }, + { "lidt", Ew, XX, XX }, + { "smsw", Ew, XX, XX }, + { "(bad)", XX, XX, XX }, + { "lmsw", Ew, XX, XX }, + { "invlpg", Ew, XX, XX }, + }, + /* GRP8 */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "btQ", Ev, Ib, XX }, + { "btsQ", Ev, Ib, XX }, + { "btrQ", Ev, Ib, XX }, + { "btcQ", Ev, Ib, XX }, + }, + /* GRP9 */ + { + { "(bad)", XX, XX, XX }, + { "cmpxchg8b", Ev, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP10 */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "psrlw", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "psraw", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "psllw", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP11 */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "psrld", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "psrad", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "pslld", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP12 */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "psrlq", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "psllq", MS, Ib, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRP13 */ + { + { "fxsave", Ev, XX, XX }, + { "fxrstor", Ev, XX, XX }, + { "ldmxcsr", Ev, XX, XX }, + { "stmxcsr", Ev, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "sfence", None, XX, XX }, + }, + /* GRP14 */ + { + { "prefetchnta", Ev, XX, XX }, + { "prefetcht0", Ev, XX, XX }, + { "prefetcht1", Ev, XX, XX }, + { "prefetcht2", Ev, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* GRPAMD */ + { + { "prefetch", Eb, XX, XX }, + { "prefetchw", Eb, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + } + +}; + +static const struct dis386 prefix_user_table[][2] = { + /* PREGRP0 */ + { + { "addps", XM, EX, XX }, + { "addss", XM, EX, XX }, + }, + /* PREGRP1 */ + { + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */ + { "", XM, EX, OPSIMD }, + }, + /* PREGRP2 */ + { + { "cvtpi2ps", XM, EM, XX }, + { "cvtsi2ss", XM, Ev, XX }, + }, + /* PREGRP3 */ + { + { "cvtps2pi", MX, EX, XX }, + { "cvtss2si", Gv, EX, XX }, + }, + /* PREGRP4 */ + { + { "cvttps2pi", MX, EX, XX }, + { "cvttss2si", Gv, EX, XX }, + }, + /* PREGRP5 */ + { + { "divps", XM, EX, XX }, + { "divss", XM, EX, XX }, + }, + /* PREGRP6 */ + { + { "maxps", XM, EX, XX }, + { "maxss", XM, EX, XX }, + }, + /* PREGRP7 */ + { + { "minps", XM, EX, XX }, + { "minss", XM, EX, XX }, + }, + /* PREGRP8 */ + { + { "movups", XM, EX, XX }, + { "movss", XM, EX, XX }, + }, + /* PREGRP9 */ + { + { "movups", EX, XM, XX }, + { "movss", EX, XM, XX }, + }, + /* PREGRP10 */ + { + { "mulps", XM, EX, XX }, + { "mulss", XM, EX, XX }, + }, + /* PREGRP11 */ + { + { "rcpps", XM, EX, XX }, + { "rcpss", XM, EX, XX }, + }, + /* PREGRP12 */ + { + { "rsqrtps", XM, EX, XX }, + { "rsqrtss", XM, EX, XX }, + }, + /* PREGRP13 */ + { + { "sqrtps", XM, EX, XX }, + { "sqrtss", XM, EX, XX }, + }, + /* PREGRP14 */ + { + { "subps", XM, EX, XX }, + { "subss", XM, EX, XX }, + } +}; + +#define INTERNAL_DISASSEMBLER_ERROR _("") + +static void +ckprefix () +{ + prefixes = 0; + used_prefixes = 0; + while (1) + { + FETCH_DATA (the_info, codep + 1); + switch (*codep) + { + case 0xf3: + prefixes |= PREFIX_REPZ; + break; + case 0xf2: + prefixes |= PREFIX_REPNZ; + break; + case 0xf0: + prefixes |= PREFIX_LOCK; + break; + case 0x2e: + prefixes |= PREFIX_CS; + break; + case 0x36: + prefixes |= PREFIX_SS; + break; + case 0x3e: + prefixes |= PREFIX_DS; + break; + case 0x26: + prefixes |= PREFIX_ES; + break; + case 0x64: + prefixes |= PREFIX_FS; + break; + case 0x65: + prefixes |= PREFIX_GS; + break; + case 0x66: + prefixes |= PREFIX_DATA; + break; + case 0x67: + prefixes |= PREFIX_ADDR; + break; + case FWAIT_OPCODE: + /* fwait is really an instruction. If there are prefixes + before the fwait, they belong to the fwait, *not* to the + following instruction. */ + if (prefixes) + { + prefixes |= PREFIX_FWAIT; + codep++; + return; + } + prefixes = PREFIX_FWAIT; + break; + default: + return; + } + codep++; + } +} + +/* Return the name of the prefix byte PREF, or NULL if PREF is not a + prefix byte. */ + +static const char * +prefix_name (int pref, int sizeflag) +{ + switch (pref) + { + case 0xf3: + return "repz"; + case 0xf2: + return "repnz"; + case 0xf0: + return "lock"; + case 0x2e: + return "cs"; + case 0x36: + return "ss"; + case 0x3e: + return "ds"; + case 0x26: + return "es"; + case 0x64: + return "fs"; + case 0x65: + return "gs"; + case 0x66: + return (sizeflag & DFLAG) ? "data16" : "data32"; + case 0x67: + return (sizeflag & AFLAG) ? "addr16" : "addr32"; + case FWAIT_OPCODE: + return "fwait"; + default: + return NULL; + } +} + +static char op1out[100], op2out[100], op3out[100]; +static int op_ad, op_index[3]; +static unsigned int op_address[3]; +static unsigned int start_pc; + + +/* + * On the 386's of 1988, the maximum length of an instruction is 15 bytes. + * (see topic "Redundant prefixes" in the "Differences from 8086" + * section of the "Virtual 8086 Mode" chapter.) + * 'pc' should be the address of this instruction, it will + * be used to print the target address if this is a relative jump or call + * The function returns the length of this instruction in bytes. + */ + +static int print_insn_i386 + PARAMS ((bfd_vma pc, disassemble_info *info)); + +#if 0 +static char intel_syntax; +#else +#define intel_syntax 0 +#endif +static char open_char; +static char close_char; +static char separator_char; +static char scale_char; + +int print_insn_i386_att PARAMS((bfd_vma pc, disassemble_info *info)); +int +print_insn_i386_att (bfd_vma pc, disassemble_info *info) +{ +// intel_syntax = 0; + open_char = '('; + close_char = ')'; + separator_char = ','; + scale_char = ','; + + return print_insn_i386 (pc, info); +} + +static int +print_insn_i386 (bfd_vma pc, disassemble_info *info) +{ + const struct dis386 *dp; + int i; + int two_source_ops; + char *first, *second, *third; + int needcomma; + unsigned char need_modrm; + unsigned char uses_f3_prefix; + VOLATILE int sizeflag; + VOLATILE int orig_sizeflag; + + struct dis_private priv; + bfd_byte *inbuf = priv.the_buffer; + + if (info->mach == bfd_mach_i386_i386 + || info->mach == bfd_mach_i386_i386_intel_syntax) + sizeflag = AFLAG|DFLAG; + else if (info->mach == bfd_mach_i386_i8086) + sizeflag = 0; + else + abort (); + orig_sizeflag = sizeflag; + + /* The output looks better if we put 7 bytes on a line, since that + puts most long word instructions on a single line. */ + info->bytes_per_line = 7; + + info->private_data = (dis_private *) &priv; + priv.max_fetched = priv.the_buffer; + priv.insn_start = pc; + + obuf[0] = 0; + op1out[0] = 0; + op2out[0] = 0; + op3out[0] = 0; + + op_index[0] = op_index[1] = op_index[2] = -1; + + the_info = info; + start_pc = pc; + start_codep = inbuf; + codep = inbuf; + + if (setjmp (priv.bailout) != 0) + { + const char *name; + + /* Getting here means we tried for data but didn't get it. That + means we have an incomplete instruction of some sort. Just + print the first byte as a prefix or a .byte pseudo-op. */ + if (codep > inbuf) + { + name = prefix_name (inbuf[0], orig_sizeflag); + if (name != NULL) + (*info->fprintf_func) (info->stream, "%s", name); + else + { + /* Just print the first byte as a .byte instruction. */ + (*info->fprintf_func) (info->stream, ".byte 0x%x", + (unsigned int) inbuf[0]); + } + + return 1; + } + + return 1; + } + + ckprefix (); + + insn_codep = codep; + + FETCH_DATA (info, codep + 1); + two_source_ops = (*codep == 0x62) || (*codep == 0xc8); + + obufp = obuf; + + if ((prefixes & PREFIX_FWAIT) + && ((*codep < 0xd8) || (*codep > 0xdf))) + { + const char *name; + + /* fwait not followed by floating point instruction. Print the + first prefix, which is probably fwait itself. */ + name = prefix_name (inbuf[0], orig_sizeflag); + if (name == NULL) + name = INTERNAL_DISASSEMBLER_ERROR; + (*info->fprintf_func) (info->stream, "%s", name); + return 1; + } + + if (*codep == 0x0f) + { + FETCH_DATA (info, codep + 2); + if (intel_syntax) + dp = &dis386_twobyte_intel[*++codep]; + else + dp = &dis386_twobyte_att[*++codep]; + need_modrm = twobyte_has_modrm[*codep]; + uses_f3_prefix = twobyte_uses_f3_prefix[*codep]; + } + else + if (*codep == 0xcc) + { + /* L4KD's hacks */ + FETCH_DATA (info, codep + 3); /* get two more bytes */ + need_modrm = 0; + uses_f3_prefix = 0; + + dp = &dis386_l4[0]; + switch (*++codep) + { + case 0x3c: + switch(*++codep) + { + case 0: oappend ("l4kd outchar(%al)"); break; + case 1: oappend ("l4kd outstring(%eax)"); break; + case 2: oappend ("l4kd outcstring(%eax)"); break; + case 3: oappend ("l4kd clear_page"); break; + case 4: oappend ("l4kd cursor"); break; + case 5: oappend ("l4kd outhex32(%eax)"); break; + case 6: oappend ("l4kd outhex20(%eax)"); break; + case 7: oappend ("l4kd outhex16(%eax)"); break; + case 8: oappend ("l4kd outhex12(%eax)"); break; + case 9: oappend ("l4kd outhex8(%eax)"); break; + case 10: oappend ("l4kd outhex4(%eax)"); break; + case 11: oappend ("l4kd outdec(%eax)"); break; + case 12: oappend ("l4kd incharety"); break; + case 13: oappend ("l4kd inchar"); break; + case 14: oappend ("l4kd inhex32"); break; + case 15: oappend ("l4kd inhex16"); break; + case 16: oappend ("l4kd inhex8"); break; + case 17: oappend ("l4kd inhext"); break; + case ' ' ... 0x7f: + { + char msg[2] = {*codep,0}; + oappend ("l4kd ko('"); oappend (msg); oappend ("')"); + }; break; + default: + oappend ("l4kd ???"); break; + }; + break; + + case 0x90: + { + int len; + + if (*++codep == 0xeb) + { + oappend ("l4kd kd_display(\""); + + FETCH_DATA (info, codep + 2); + len = *++codep; + + FETCH_DATA (info, codep + len + 1); + { + char msg[len + 1]; + strncpy(msg, (char*) codep + 1, len); + msg[len] = 0; + oappend (msg); + codep += len; + }; + oappend ("\")"); + } + else + { + codep -= 2; + dp = &dis386_l4[1]; + }; + + }; break; + case 0xeb: + { + int len; + oappend ("l4kd enter_kdebug(\""); + + FETCH_DATA (info, codep + 2); + len = *++codep; + + FETCH_DATA (info, codep + len + 1); + { + char msg[len + 1]; + strncpy(msg, (char*) codep + 1, len); + msg[len] = 0; + oappend (msg); + codep += len; + }; + oappend ("\")"); + }; break; + default: + codep--; + dp = &dis386_l4[1]; + break; + } + } + else + { + if (intel_syntax) + dp = &dis386_intel[*codep]; + else + dp = &dis386_att[*codep]; + need_modrm = onebyte_has_modrm[*codep]; + uses_f3_prefix = 0; + } + codep++; + + if (!uses_f3_prefix && (prefixes & PREFIX_REPZ)) + { + oappend ("repz "); + used_prefixes |= PREFIX_REPZ; + } + if (prefixes & PREFIX_REPNZ) + { + oappend ("repnz "); + used_prefixes |= PREFIX_REPNZ; + } + if (prefixes & PREFIX_LOCK) + { + oappend ("lock "); + used_prefixes |= PREFIX_LOCK; + } + + if (prefixes & PREFIX_DATA) + sizeflag ^= DFLAG; + + if (prefixes & PREFIX_ADDR) + { + sizeflag ^= AFLAG; + if (sizeflag & AFLAG) + oappend ("addr32 "); + else + oappend ("addr16 "); + used_prefixes |= PREFIX_ADDR; + } + + if (need_modrm) + { + FETCH_DATA (info, codep + 1); + mod = (*codep >> 6) & 3; + reg = (*codep >> 3) & 7; + rm = *codep & 7; + } + + if (dp->name == NULL && dp->bytemode1 == FLOATCODE) + { + dofloat (sizeflag); + } + else + { + if (dp->name == NULL) + { + switch(dp->bytemode2) + { + case USE_GROUPS: + dp = &grps[dp->bytemode1][reg]; + break; + case USE_PREFIX_USER_TABLE: + dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0]; + used_prefixes |= (prefixes & PREFIX_REPZ); + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } + } + + putop (dp->name, sizeflag); + + obufp = op1out; + op_ad = 2; + if (dp->op1) + (*dp->op1)(dp->bytemode1, sizeflag); + + obufp = op2out; + op_ad = 1; + if (dp->op2) + (*dp->op2)(dp->bytemode2, sizeflag); + + obufp = op3out; + op_ad = 0; + if (dp->op3) + (*dp->op3)(dp->bytemode3, sizeflag); + } + + /* See if any prefixes were not used. If so, print the first one + separately. If we don't do this, we'll wind up printing an + instruction stream which does not precisely correspond to the + bytes we are disassembling. */ + if ((prefixes & ~used_prefixes) != 0) + { + const char *name; + + name = prefix_name (inbuf[0], orig_sizeflag); + if (name == NULL) + name = INTERNAL_DISASSEMBLER_ERROR; + (*info->fprintf_func) (info->stream, "%s", name); + return 1; + } + + obufp = obuf + strlen (obuf); + for (i = strlen (obuf); i < 6; i++) + oappend (" "); + oappend (" "); + (*info->fprintf_func) (info->stream, "%s", obuf); + + /* The enter and bound instructions are printed with operands in the same + order as the intel book; everything else is printed in reverse order. */ + if (intel_syntax || two_source_ops) + { + first = op1out; + second = op2out; + third = op3out; + op_ad = op_index[0]; + op_index[0] = op_index[2]; + op_index[2] = op_ad; + } + else + { + first = op3out; + second = op2out; + third = op1out; + } + needcomma = 0; + if (*first) + { + if (op_index[0] != -1) + (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); + else + (*info->fprintf_func) (info->stream, "%s", first); + needcomma = 1; + } + if (*second) + { + if (needcomma) + (*info->fprintf_func) (info->stream, ","); + if (op_index[1] != -1) + (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); + else + (*info->fprintf_func) (info->stream, "%s", second); + needcomma = 1; + } + if (*third) + { + if (needcomma) + (*info->fprintf_func) (info->stream, ","); + if (op_index[2] != -1) + (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); + else + (*info->fprintf_func) (info->stream, "%s", third); + } + return codep - inbuf; +} + +static const char *float_mem_att[] = { + /* d8 */ + "fadds", + "fmuls", + "fcoms", + "fcomps", + "fsubs", + "fsubrs", + "fdivs", + "fdivrs", + /* d9 */ + "flds", + "(bad)", + "fsts", + "fstps", + "fldenv", + "fldcw", + "fNstenv", + "fNstcw", + /* da */ + "fiaddl", + "fimull", + "ficoml", + "ficompl", + "fisubl", + "fisubrl", + "fidivl", + "fidivrl", + /* db */ + "fildl", + "(bad)", + "fistl", + "fistpl", + "(bad)", + "fldt", + "(bad)", + "fstpt", + /* dc */ + "faddl", + "fmull", + "fcoml", + "fcompl", + "fsubl", + "fsubrl", + "fdivl", + "fdivrl", + /* dd */ + "fldl", + "(bad)", + "fstl", + "fstpl", + "frstor", + "(bad)", + "fNsave", + "fNstsw", + /* de */ + "fiadd", + "fimul", + "ficom", + "ficomp", + "fisub", + "fisubr", + "fidiv", + "fidivr", + /* df */ + "fild", + "(bad)", + "fist", + "fistp", + "fbld", + "fildll", + "fbstp", + "fistpll", +}; + +static const char *float_mem_intel[] = { + /* d8 */ + "fadd", + "fmul", + "fcom", + "fcomp", + "fsub", + "fsubr", + "fdiv", + "fdivr", + /* d9 */ + "fld", + "(bad)", + "fst", + "fstp", + "fldenv", + "fldcw", + "fNstenv", + "fNstcw", + /* da */ + "fiadd", + "fimul", + "ficom", + "ficomp", + "fisub", + "fisubr", + "fidiv", + "fidivr", + /* db */ + "fild", + "(bad)", + "fist", + "fistp", + "(bad)", + "fld", + "(bad)", + "fstp", + /* dc */ + "fadd", + "fmul", + "fcom", + "fcomp", + "fsub", + "fsubr", + "fdiv", + "fdivr", + /* dd */ + "fld", + "(bad)", + "fst", + "fstp", + "frstor", + "(bad)", + "fNsave", + "fNstsw", + /* de */ + "fiadd", + "fimul", + "ficom", + "ficomp", + "fisub", + "fisubr", + "fidiv", + "fidivr", + /* df */ + "fild", + "(bad)", + "fist", + "fistp", + "fbld", + "fild", + "fbstp", + "fistpll", +}; + +#define ST OP_ST, 0 +#define STi OP_STi, 0 + +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0 +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0 +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0 +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0 +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0 +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0 +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0 +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0 +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0 + +static const struct dis386 float_reg[][8] = { + /* d8 */ + { + { "fadd", ST, STi, XX }, + { "fmul", ST, STi, XX }, + { "fcom", STi, XX, XX }, + { "fcomp", STi, XX, XX }, + { "fsub", ST, STi, XX }, + { "fsubr", ST, STi, XX }, + { "fdiv", ST, STi, XX }, + { "fdivr", ST, STi, XX }, + }, + /* d9 */ + { + { "fld", STi, XX, XX }, + { "fxch", STi, XX, XX }, + { FGRPd9_2 }, + { "(bad)", XX, XX, XX }, + { FGRPd9_4 }, + { FGRPd9_5 }, + { FGRPd9_6 }, + { FGRPd9_7 }, + }, + /* da */ + { + { "fcmovb", ST, STi, XX }, + { "fcmove", ST, STi, XX }, + { "fcmovbe",ST, STi, XX }, + { "fcmovu", ST, STi, XX }, + { "(bad)", XX, XX, XX }, + { FGRPda_5 }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* db */ + { + { "fcmovnb",ST, STi, XX }, + { "fcmovne",ST, STi, XX }, + { "fcmovnbe",ST, STi, XX }, + { "fcmovnu",ST, STi, XX }, + { FGRPdb_4 }, + { "fucomi", ST, STi, XX }, + { "fcomi", ST, STi, XX }, + { "(bad)", XX, XX, XX }, + }, + /* dc */ + { + { "fadd", STi, ST, XX }, + { "fmul", STi, ST, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, +#if UNIXWARE_COMPAT + { "fsub", STi, ST, XX }, + { "fsubr", STi, ST, XX }, + { "fdiv", STi, ST, XX }, + { "fdivr", STi, ST, XX }, +#else + { "fsubr", STi, ST, XX }, + { "fsub", STi, ST, XX }, + { "fdivr", STi, ST, XX }, + { "fdiv", STi, ST, XX }, +#endif + }, + /* dd */ + { + { "ffree", STi, XX, XX }, + { "(bad)", XX, XX, XX }, + { "fst", STi, XX, XX }, + { "fstp", STi, XX, XX }, + { "fucom", STi, XX, XX }, + { "fucomp", STi, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + }, + /* de */ + { + { "faddp", STi, ST, XX }, + { "fmulp", STi, ST, XX }, + { "(bad)", XX, XX, XX }, + { FGRPde_3 }, +#if UNIXWARE_COMPAT + { "fsubp", STi, ST, XX }, + { "fsubrp", STi, ST, XX }, + { "fdivp", STi, ST, XX }, + { "fdivrp", STi, ST, XX }, +#else + { "fsubrp", STi, ST, XX }, + { "fsubp", STi, ST, XX }, + { "fdivrp", STi, ST, XX }, + { "fdivp", STi, ST, XX }, +#endif + }, + /* df */ + { + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { "(bad)", XX, XX, XX }, + { FGRPdf_4 }, + { "fucomip",ST, STi, XX }, + { "fcomip", ST, STi, XX }, + { "(bad)", XX, XX, XX }, + }, +}; + + +static char *fgrps[][8] = { + /* d9_2 0 */ + { + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* d9_4 1 */ + { + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", + }, + + /* d9_5 2 */ + { + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", + }, + + /* d9_6 3 */ + { + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", + }, + + /* d9_7 4 */ + { + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", + }, + + /* da_5 5 */ + { + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* db_4 6 */ + { + "feni(287 only)","fdisi(287 only)","fNclex","fNinit", + "fNsetpm(287 only)","(bad)","(bad)","(bad)", + }, + + /* de_3 7 */ + { + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, + + /* df_4 8 */ + { + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", + }, +}; + +static void +dofloat (int sizeflag) +{ + const struct dis386 *dp; + unsigned char floatop; + + floatop = codep[-1]; + + if (mod != 3) + { + if (intel_syntax) + putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag); + else + putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag); + obufp = op1out; + if (floatop == 0xdb) + OP_E (x_mode, sizeflag); + else if (floatop == 0xdd) + OP_E (d_mode, sizeflag); + else + OP_E (v_mode, sizeflag); + return; + } + codep++; + + dp = &float_reg[floatop - 0xd8][reg]; + if (dp->name == NULL) + { + putop (fgrps[dp->bytemode1][rm], sizeflag); + + /* instruction fnstsw is only one with strange arg */ + if (floatop == 0xdf && codep[-1] == 0xe0) + strcpy (op1out, names16[0]); + } + else + { + putop (dp->name, sizeflag); + + obufp = op1out; + if (dp->op1) + (*dp->op1)(dp->bytemode1, sizeflag); + obufp = op2out; + if (dp->op2) + (*dp->op2)(dp->bytemode2, sizeflag); + } +} + +/* ARGSUSED */ +static void +OP_ST (int ignore ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) +{ + oappend ("%st"); +} + +/* ARGSUSED */ +static void +OP_STi (int ignore ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) +{ + sprintf (scratchbuf, "%%st(%d)", rm); + oappend (scratchbuf); +} + + +/* capital letters in template are macros */ +static void +putop (const char *templ, int sizeflag) +{ + const char *p; + + for (p = templ; *p; p++) + { + switch (*p) + { + default: + *obufp++ = *p; + break; + case 'A': + if (intel_syntax) + break; + if (mod != 3 +#ifdef SUFFIX_ALWAYS + || (sizeflag & SUFFIX_ALWAYS) +#endif + ) + *obufp++ = 'b'; + break; + case 'B': + if (intel_syntax) + break; +#ifdef SUFFIX_ALWAYS + if (sizeflag & SUFFIX_ALWAYS) + *obufp++ = 'b'; +#endif + break; + case 'E': /* For jcxz/jecxz */ + if (sizeflag & AFLAG) + *obufp++ = 'e'; + break; + case 'L': + if (intel_syntax) + break; +#ifdef SUFFIX_ALWAYS + if (sizeflag & SUFFIX_ALWAYS) + *obufp++ = 'l'; +#endif + break; + case 'N': + if ((prefixes & PREFIX_FWAIT) == 0) + *obufp++ = 'n'; + else + used_prefixes |= PREFIX_FWAIT; + break; + case 'P': + if (intel_syntax) + break; + if ((prefixes & PREFIX_DATA) +#ifdef SUFFIX_ALWAYS + || (sizeflag & SUFFIX_ALWAYS) +#endif + ) + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } + break; + case 'Q': + if (intel_syntax) + break; + if (mod != 3 +#ifdef SUFFIX_ALWAYS + || (sizeflag & SUFFIX_ALWAYS) +#endif + ) + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } + break; + case 'R': + if (intel_syntax) + { + if (sizeflag & DFLAG) + { + *obufp++ = 'd'; + *obufp++ = 'q'; + } + else + { + *obufp++ = 'w'; + *obufp++ = 'd'; + } + } + else + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + } + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case 'S': + if (intel_syntax) + break; +#ifdef SUFFIX_ALWAYS + if (sizeflag & SUFFIX_ALWAYS) + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } +#endif + break; + case 'W': + /* operand size flag for cwtl, cbtw */ + if (sizeflag & DFLAG) + *obufp++ = 'w'; + else + *obufp++ = 'b'; + if (intel_syntax) + { + if (sizeflag & DFLAG) + { + *obufp++ = 'd'; + *obufp++ = 'e'; + } + else + { + *obufp++ = 'w'; + } + } + used_prefixes |= (prefixes & PREFIX_DATA); + break; + } + } + *obufp = 0; +} + +static void +oappend (const char *s) +{ + strcpy (obufp, s); + obufp += strlen (s); +} + +static void +append_seg () +{ + if (prefixes & PREFIX_CS) + { + oappend ("%cs:"); + used_prefixes |= PREFIX_CS; + } + if (prefixes & PREFIX_DS) + { + oappend ("%ds:"); + used_prefixes |= PREFIX_DS; + } + if (prefixes & PREFIX_SS) + { + oappend ("%ss:"); + used_prefixes |= PREFIX_SS; + } + if (prefixes & PREFIX_ES) + { + oappend ("%es:"); + used_prefixes |= PREFIX_ES; + } + if (prefixes & PREFIX_FS) + { + oappend ("%fs:"); + used_prefixes |= PREFIX_FS; + } + if (prefixes & PREFIX_GS) + { + oappend ("%gs:"); + used_prefixes |= PREFIX_GS; + } +} + +static void +OP_indirE (int bytemode, int sizeflag) +{ + if (!intel_syntax) + oappend ("*"); + OP_E (bytemode, sizeflag); +} + +static void +OP_E (int bytemode, int sizeflag) +{ + int disp; + + /* skip mod/rm byte */ + codep++; + + if (mod == 3) + { + switch (bytemode) + { + case b_mode: + oappend (names8[rm]); + break; + case w_mode: + oappend (names16[rm]); + break; + case d_mode: + oappend (names32[rm]); + break; + case v_mode: + if (sizeflag & DFLAG) + oappend (names32[rm]); + else + oappend (names16[rm]); + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case 0: + if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)) + BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */ + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } + return; + } + + disp = 0; + append_seg (); + + if (sizeflag & AFLAG) /* 32 bit address mode */ + { + int havesib; + int havebase; + int base; + int index = 0; + int scale = 0; + + havesib = 0; + havebase = 1; + base = rm; + + if (base == 4) + { + havesib = 1; + FETCH_DATA (the_info, codep + 1); + scale = (*codep >> 6) & 3; + index = (*codep >> 3) & 7; + base = *codep & 7; + codep++; + } + + switch (mod) + { + case 0: + if (base == 5) + { + havebase = 0; + disp = get32 (); + } + break; + case 1: + FETCH_DATA (the_info, codep + 1); + disp = *codep++; + if ((disp & 0x80) != 0) + disp -= 0x100; + break; + case 2: + disp = get32 (); + break; + } + + if (!intel_syntax) + if (mod != 0 || base == 5) + { + sprintf (scratchbuf, "0x%x", disp); + oappend (scratchbuf); + } + + if (havebase || (havesib && (index != 4 || scale != 0))) + { + if (intel_syntax) + { + switch (bytemode) + { + case b_mode: + oappend("BYTE PTR "); + break; + case w_mode: + oappend("WORD PTR "); + break; + case v_mode: + oappend("DWORD PTR "); + break; + case d_mode: + oappend("QWORD PTR "); + break; + case x_mode: + oappend("XWORD PTR "); + break; + default: + break; + } + } + *obufp++ = open_char; + *obufp = '\0'; + if (havebase) + oappend (names32[base]); + if (havesib) + { + if (index != 4) + { + if (intel_syntax) + { + if (havebase) + { + *obufp++ = separator_char; + *obufp = '\0'; + } + sprintf (scratchbuf, "%s", names32[index]); + } + else + sprintf (scratchbuf, ",%s", names32[index]); + oappend (scratchbuf); + } + if (!intel_syntax + || (intel_syntax + && bytemode != b_mode + && bytemode != w_mode + && bytemode != v_mode)) + { + *obufp++ = scale_char; + *obufp = '\0'; + sprintf (scratchbuf, "%d", 1 << scale); + oappend (scratchbuf); + } + } + if (intel_syntax) + if (mod != 0 || base == 5) + { + /* Don't print zero displacements */ + if (disp > 0) + { + sprintf (scratchbuf, "+%d", disp); + oappend (scratchbuf); + } + else if (disp < 0) + { + sprintf (scratchbuf, "%d", disp); + oappend (scratchbuf); + } + } + + *obufp++ = close_char; + *obufp = '\0'; + } + else if (intel_syntax) + { + if (mod != 0 || base == 5) + { + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) + ; + else + { + oappend (names_seg[3]); + oappend (":"); + } + sprintf (scratchbuf, "0x%x", disp); + oappend (scratchbuf); + } + } + } + else + { /* 16 bit address mode */ + switch (mod) + { + case 0: + if (rm == 6) + { + disp = get16 (); + if ((disp & 0x8000) != 0) + disp -= 0x10000; + } + break; + case 1: + FETCH_DATA (the_info, codep + 1); + disp = *codep++; + if ((disp & 0x80) != 0) + disp -= 0x100; + break; + case 2: + disp = get16 (); + if ((disp & 0x8000) != 0) + disp -= 0x10000; + break; + } + + if (!intel_syntax) + if (mod != 0 || rm == 6) + { + sprintf (scratchbuf, "%d", disp); + oappend (scratchbuf); + } + + if (mod != 0 || rm != 6) + { + *obufp++ = open_char; + *obufp = '\0'; + oappend (index16[rm]); + *obufp++ = close_char; + *obufp = '\0'; + } + } +} + +static void +OP_G (int bytemode, int sizeflag) +{ + switch (bytemode) + { + case b_mode: + oappend (names8[reg]); + break; + case w_mode: + oappend (names16[reg]); + break; + case d_mode: + oappend (names32[reg]); + break; + case v_mode: + if (sizeflag & DFLAG) + oappend (names32[reg]); + else + oappend (names16[reg]); + used_prefixes |= (prefixes & PREFIX_DATA); + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } +} + +static int +get32 () +{ + int x = 0; + + FETCH_DATA (the_info, codep + 4); + x = *codep++ & 0xff; + x |= (*codep++ & 0xff) << 8; + x |= (*codep++ & 0xff) << 16; + x |= (*codep++ & 0xff) << 24; + return x; +} + +static int +get16 () +{ + int x = 0; + + FETCH_DATA (the_info, codep + 2); + x = *codep++ & 0xff; + x |= (*codep++ & 0xff) << 8; + return x; +} + +static void +set_op (unsigned int op) +{ + op_index[op_ad] = op_ad; + op_address[op_ad] = op; +} + +static void +OP_REG (int code, int sizeflag) +{ + const char *s; + + switch (code) + { + case indir_dx_reg: + s = "(%dx)"; + break; + case ax_reg: case cx_reg: case dx_reg: case bx_reg: + case sp_reg: case bp_reg: case si_reg: case di_reg: + s = names16[code - ax_reg]; + break; + case es_reg: case ss_reg: case cs_reg: + case ds_reg: case fs_reg: case gs_reg: + s = names_seg[code - es_reg]; + break; + case al_reg: case ah_reg: case cl_reg: case ch_reg: + case dl_reg: case dh_reg: case bl_reg: case bh_reg: + s = names8[code - al_reg]; + break; + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: + if (sizeflag & DFLAG) + s = names32[code - eAX_reg]; + else + s = names16[code - eAX_reg]; + used_prefixes |= (prefixes & PREFIX_DATA); + break; + default: + s = INTERNAL_DISASSEMBLER_ERROR; + break; + } + oappend (s); +} + +static void +OP_I (int bytemode, int sizeflag) +{ + int op; + + switch (bytemode) + { + case b_mode: + FETCH_DATA (the_info, codep + 1); + op = *codep++ & 0xff; + break; + case v_mode: + if (sizeflag & DFLAG) + op = get32 (); + else + op = get16 (); + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case w_mode: + op = get16 (); + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + return; + } + + if (intel_syntax) + sprintf (scratchbuf, "0x%x", op); + else + sprintf (scratchbuf, "$0x%x", op); + oappend (scratchbuf); + scratchbuf[0] = '\0'; +} + +static void +OP_sI (int bytemode, int sizeflag) +{ + int op; + + switch (bytemode) + { + case b_mode: + FETCH_DATA (the_info, codep + 1); + op = *codep++; + if ((op & 0x80) != 0) + op -= 0x100; + break; + case v_mode: + if (sizeflag & DFLAG) + op = get32 (); + else + { + op = get16(); + if ((op & 0x8000) != 0) + op -= 0x10000; + } + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case w_mode: + op = get16 (); + if ((op & 0x8000) != 0) + op -= 0x10000; + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + return; + } + if (intel_syntax) + sprintf (scratchbuf, "%d", op); + else + sprintf (scratchbuf, "$0x%x", op); + oappend (scratchbuf); +} + +static void +OP_J (int bytemode, int sizeflag) +{ + int disp; + int mask = -1; + + switch (bytemode) + { + case b_mode: + FETCH_DATA (the_info, codep + 1); + disp = *codep++; + if ((disp & 0x80) != 0) + disp -= 0x100; + break; + case v_mode: + if (sizeflag & DFLAG) + disp = get32 (); + else + { + disp = get16 (); + /* for some reason, a data16 prefix on a jump instruction + means that the pc is masked to 16 bits after the + displacement is added! */ + mask = 0xffff; + } + used_prefixes |= (prefixes & PREFIX_DATA); + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + return; + } + disp = (start_pc + codep - start_codep + disp) & mask; + set_op (disp); + sprintf (scratchbuf, "0x%x", disp); + oappend (scratchbuf); +} + +/* ARGSUSED */ +static void +OP_SEG (int dummy, int sizeflag) +{ + static char *sreg[] = { + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", + }; + + oappend (sreg[reg]); +} + +/* ARGSUSED */ +static void +OP_DIR (int dummy, int sizeflag) +{ + int seg, offset; + + if (sizeflag & DFLAG) + { + offset = get32 (); + seg = get16 (); + } + else + { + offset = get16 (); + seg = get16 (); + } + used_prefixes |= (prefixes & PREFIX_DATA); + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); + oappend (scratchbuf); +} + +/* ARGSUSED */ +static void +OP_OFF (int ignore, int sizeflag) +{ + int off; + + append_seg (); + + if (sizeflag & AFLAG) + off = get32 (); + else + off = get16 (); + + if (intel_syntax) + { + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS + | PREFIX_ES | PREFIX_FS | PREFIX_GS))) + { + oappend (names_seg[3]); + oappend (":"); + } + } + sprintf (scratchbuf, "0x%x", off); + oappend (scratchbuf); +} + +static void +ptr_reg (int code, int sizeflag) +{ + const char *s; + oappend ("("); + if (sizeflag & AFLAG) + s = names32[code - eAX_reg]; + else + s = names16[code - eAX_reg]; + oappend (s); + oappend (")"); +} + +static void +OP_ESreg (int code, int sizeflag) +{ + oappend ("%es:"); + ptr_reg (code, sizeflag); +} + +static void +OP_DSreg (int code, int sizeflag) +{ + if ((prefixes + & (PREFIX_CS + | PREFIX_DS + | PREFIX_SS + | PREFIX_ES + | PREFIX_FS + | PREFIX_GS)) == 0) + prefixes |= PREFIX_DS; + append_seg(); + ptr_reg (code, sizeflag); +} + +/* ARGSUSED */ +static void +OP_C (int dummy, int sizeflag) +{ + sprintf (scratchbuf, "%%cr%d", reg); + oappend (scratchbuf); +} + +/* ARGSUSED */ +static void +OP_D (int dummy, int sizeflag) +{ + sprintf (scratchbuf, "%%db%d", reg); + oappend (scratchbuf); +} + +/* ARGSUSED */ +static void +OP_T (int dummy, int sizeflag) +{ + sprintf (scratchbuf, "%%tr%d", reg); + oappend (scratchbuf); +} + +static void +OP_Rd (int bytemode, int sizeflag) +{ + if (mod == 3) + OP_E (bytemode, sizeflag); + else + BadOp(); +} + +static void +OP_MMX (int ignore, int sizeflag) +{ + sprintf (scratchbuf, "%%mm%d", reg); + oappend (scratchbuf); +} + +static void +OP_XMM (int bytemode, int sizeflag) +{ + sprintf (scratchbuf, "%%xmm%d", reg); + oappend (scratchbuf); +} + +static void +OP_EM (int bytemode, int sizeflag) +{ + if (mod != 3) + { + OP_E (bytemode, sizeflag); + return; + } + + codep++; + sprintf (scratchbuf, "%%mm%d", rm); + oappend (scratchbuf); +} + +static void +OP_EX (int bytemode, int sizeflag) +{ + if (mod != 3) + { + OP_E (bytemode, sizeflag); + return; + } + + codep++; + sprintf (scratchbuf, "%%xmm%d", rm); + oappend (scratchbuf); +} + +static void +OP_MS (int bytemode, int sizeflag) +{ + if (mod == 3) + OP_EM (bytemode, sizeflag); + else + BadOp(); +} + +static const char *Suffix3DNow[] = { +/* 00 */ NULL, NULL, NULL, NULL, +/* 04 */ NULL, NULL, NULL, NULL, +/* 08 */ NULL, NULL, NULL, NULL, +/* 0C */ "pi2fw", "pi2fd", NULL, NULL, +/* 10 */ NULL, NULL, NULL, NULL, +/* 14 */ NULL, NULL, NULL, NULL, +/* 18 */ NULL, NULL, NULL, NULL, +/* 1C */ "pf2iw", "pf2id", NULL, NULL, +/* 20 */ NULL, NULL, NULL, NULL, +/* 24 */ NULL, NULL, NULL, NULL, +/* 28 */ NULL, NULL, NULL, NULL, +/* 2C */ NULL, NULL, NULL, NULL, +/* 30 */ NULL, NULL, NULL, NULL, +/* 34 */ NULL, NULL, NULL, NULL, +/* 38 */ NULL, NULL, NULL, NULL, +/* 3C */ NULL, NULL, NULL, NULL, +/* 40 */ NULL, NULL, NULL, NULL, +/* 44 */ NULL, NULL, NULL, NULL, +/* 48 */ NULL, NULL, NULL, NULL, +/* 4C */ NULL, NULL, NULL, NULL, +/* 50 */ NULL, NULL, NULL, NULL, +/* 54 */ NULL, NULL, NULL, NULL, +/* 58 */ NULL, NULL, NULL, NULL, +/* 5C */ NULL, NULL, NULL, NULL, +/* 60 */ NULL, NULL, NULL, NULL, +/* 64 */ NULL, NULL, NULL, NULL, +/* 68 */ NULL, NULL, NULL, NULL, +/* 6C */ NULL, NULL, NULL, NULL, +/* 70 */ NULL, NULL, NULL, NULL, +/* 74 */ NULL, NULL, NULL, NULL, +/* 78 */ NULL, NULL, NULL, NULL, +/* 7C */ NULL, NULL, NULL, NULL, +/* 80 */ NULL, NULL, NULL, NULL, +/* 84 */ NULL, NULL, NULL, NULL, +/* 88 */ NULL, NULL, "pfnacc", NULL, +/* 8C */ NULL, NULL, "pfpnacc", NULL, +/* 90 */ "pfcmpge", NULL, NULL, NULL, +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", +/* 98 */ NULL, NULL, "pfsub", NULL, +/* 9C */ NULL, NULL, "pfadd", NULL, +/* A0 */ "pfcmpgt", NULL, NULL, NULL, +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", +/* A8 */ NULL, NULL, "pfsubr", NULL, +/* AC */ NULL, NULL, "pfacc", NULL, +/* B0 */ "pfcmpeq", NULL, NULL, NULL, +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", +/* B8 */ NULL, NULL, NULL, "pswapd", +/* BC */ NULL, NULL, NULL, "pavgusb", +/* C0 */ NULL, NULL, NULL, NULL, +/* C4 */ NULL, NULL, NULL, NULL, +/* C8 */ NULL, NULL, NULL, NULL, +/* CC */ NULL, NULL, NULL, NULL, +/* D0 */ NULL, NULL, NULL, NULL, +/* D4 */ NULL, NULL, NULL, NULL, +/* D8 */ NULL, NULL, NULL, NULL, +/* DC */ NULL, NULL, NULL, NULL, +/* E0 */ NULL, NULL, NULL, NULL, +/* E4 */ NULL, NULL, NULL, NULL, +/* E8 */ NULL, NULL, NULL, NULL, +/* EC */ NULL, NULL, NULL, NULL, +/* F0 */ NULL, NULL, NULL, NULL, +/* F4 */ NULL, NULL, NULL, NULL, +/* F8 */ NULL, NULL, NULL, NULL, +/* FC */ NULL, NULL, NULL, NULL, +}; + +static void +OP_3DNowSuffix (int bytemode, int sizeflag) +{ + const char *mnemonic; + + FETCH_DATA (the_info, codep + 1); + /* AMD 3DNow! instructions are specified by an opcode suffix in the + place where an 8-bit immediate would normally go. ie. the last + byte of the instruction. */ + obufp = obuf + strlen(obuf); + mnemonic = Suffix3DNow[*codep++ & 0xff]; + if (mnemonic) + oappend (mnemonic); + else + { + /* Since a variable sized modrm/sib chunk is between the start + of the opcode (0x0f0f) and the opcode suffix, we need to do + all the modrm processing first, and don't know until now that + we have a bad opcode. This necessitates some cleaning up. */ + op1out[0] = '\0'; + op2out[0] = '\0'; + BadOp(); + } +} + + +static const char *simd_cmp_op [] = { + "eq", + "lt", + "le", + "unord", + "neq", + "nlt", + "nle", + "ord" +}; + +static void +OP_SIMD_Suffix (int bytemode, int sizeflag) +{ + unsigned int cmp_type; + + FETCH_DATA (the_info, codep + 1); + obufp = obuf + strlen(obuf); + cmp_type = *codep++ & 0xff; + if (cmp_type < 8) + { + sprintf (scratchbuf, "cmp%s%cs", + simd_cmp_op[cmp_type], + prefixes & PREFIX_REPZ ? 's' : 'p'); + used_prefixes |= (prefixes & PREFIX_REPZ); + oappend (scratchbuf); + } + else + { + /* We have a bad extension byte. Clean up. */ + op1out[0] = '\0'; + op2out[0] = '\0'; + BadOp(); + } +} + +static void +SIMD_Fixup (int extrachar, int sizeflag) +{ + /* Change movlps/movhps to movhlps/movlhps for 2 register operand + forms of these instructions. */ + if (mod == 3) + { + char *p = obuf + strlen(obuf); + *(p+1) = '\0'; + *p = *(p-1); + *(p-1) = *(p-2); + *(p-2) = *(p-3); + *(p-3) = extrachar; + } +} + +static void BadOp (void) +{ + codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */ + oappend ("(bad)"); +} + + +char *strncpy(char *dest, const char *src, int n) +{ + char* d = dest; + const char* s = src; + do { *d++ = *s; } while (*s++ && (--n)); + return dest; +}; +char *strcpy(char *dest, const char *src) +{ + char* d = dest; + const char* s = src; + do { *d++ = *s; } while (*s++); + return dest; +}; + +int rmf(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, + struct disassemble_info *info) L4_SECT_KDEBUG; +int rmf(bfd_vma memaddr, + bfd_byte *myaddr, unsigned int length, + struct disassemble_info *info) +{ + char* d = (char*) myaddr; + char* s = (char*) memaddr; + int len = length; + while (len--) + { + space_t *space = (space_t *) get_current_pgtable(); + if (!kdebug_get_mem(space, s, d)) + return 1; + d++; s++; + }; + return 0; +}; +void mef(int status, bfd_vma memaddr, + struct disassemble_info *info) L4_SECT_KDEBUG; +void mef(int status, + bfd_vma memaddr, + struct disassemble_info *info) +{ + //printf("%s(%x,%x,%x)\n", __FUNCTION__, status, memaddr, info); + printf("##"); +}; + +void paf(bfd_vma addr, struct disassemble_info *info) L4_SECT_KDEBUG; +void paf(bfd_vma addr, struct disassemble_info *info) +{ + printf("%x", addr); +}; + + + + +int do_printf(const char** format_p); + +int fprintf(char* f, const char* format, ...) +{ +// printf("%s(%x,%s)\n", __FUNCTION__, f, format); + return do_printf(&format); +}; + +int x86_disas(dword_t pc) L4_SECT_KDEBUG; +int x86_disas(dword_t pc) +{ + disassemble_info info = + { + NULL, + rmf, + mef, + bfd_mach_i386_i386, + 0, + NULL, + fprintf, + paf + }; + extern int print_insn_i386_att (bfd_vma pc, disassemble_info *info); + return print_insn_i386_att(pc, &info); +} + + + + + + + + + + +#if 1 +/**************************************************************************** + * + * the stuff from here on should probably go to sprint.c + * but I leave it in here since it's only used by this disassembler + * + ****************************************************************************/ + +static int print_hex(char** obuf, dword_t val) L4_SECT_KDEBUG; +static int print_hex(char** obuf, word_t val) L4_SECT_KDEBUG; +static int print_hex(char** obuf, byte_t val) L4_SECT_KDEBUG; +static int print_string(char** obuf, char* s) L4_SECT_KDEBUG; +static int print_dec(char** obuf, dword_t val, dword_t width = 0) L4_SECT_KDEBUG; + +static void putc(char** obuf, char c) +{ + (*(*obuf)++) = c; +} + +#define putc(x) putc(obuf, x) + +static int print_vhex(char** obuf, dword_t val) +{ + int i, n = 0; + char lzero=0; + for ( i = 28; i >= 0; i -= 4) + if (lzero |= (val >> i) & 0xF) + { + putc(hexchars[(val >> i) & 0xF]); + n++; + }; + return n; +} +#define print_vhex(x...) print_vhex(obuf, x) + +static int print_hex(char** obuf, dword_t val) +{ + int i, n = 1; + for ( i = 28; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} + +static int print_hex(char** obuf, word_t val) +{ + int i, n = 1; + for ( i = 12; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} + +static int print_hex(char** obuf, byte_t val) +{ + int i, n = 1; + for ( i = 4; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} +#define print_hex(x...) print_hex(obuf, x) + +static int print_string(char** obuf, char* s) +{ + int n = 0; + while ( *s ) { putc(*s++); n++; } + return n; +} +#define print_string(x) print_string(obuf, x) + +static int print_dec(char** obuf, dword_t val, dword_t width) +{ + char buff[16]; + int i = 14; + + buff[15] = '\0'; + do + { + buff[i] = (val % 10) + '0'; + val = val / 10; + i--; + if ( width > 0 ) width--; + } while( val ); + + while ( i >= 0 && width-- > 0 ) + buff[i--] = ' '; + + return print_string(&buff[i+1]); +} +#define print_dec(x...) print_dec(obuf, x) + + +static int do_sprintf(char** obuf, const char** format_p) +{ + const char* format = *format_p; + int n = 0; + int i = 0; + int width = 8; + +#define arg(x) (((dword_t*) format_p)[(x)+1]) + + /* sanity check */ + if (format == NULL) + return 0; + + while (*format) + { + switch (*(format)) + { + case '%': + width = 0; + reentry: + switch (*(++format)) + { + case '0'...'9': + width = width*10 + (*format)-'0'; + goto reentry; + break; + case 'c': + putc(arg(i)); + n++; + break; + case 'd': + n += print_dec(arg(i), width); + break; + case 'p': + width = 8; + case 'x': + switch(width) { + case 2: n += print_hex((byte_t) arg(i)); break; + case 4: n += print_hex((word_t) arg(i)); break; + case 8: n += print_hex((dword_t) arg(i)); break; + default: n += print_vhex((dword_t) arg(i)); break; + } + break; + case 's': + n += print_string((char*) arg(i)); + break; + case 'T': + if (l4_is_invalid_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("INVALID "); break; + } + if (l4_is_nil_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("NIL_ID "); break; + } + if (arg(i) < 17) + { + n += print_string("IRQ_"); + if (arg(i) < 11) { putc(' '); n++; } + n += print_dec(arg(i)-1); if (arg(i) < 11) putc(' '); + n += print_string(" "); + } + print_hex(arg(i)); + break; + case 't': + if (l4_is_invalid_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("INVALID"); break; + } + if (l4_is_nil_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("NIL_ID"); break; + } + if (arg(i) < 17) + { + n += print_string("IRQ_"); + n += print_dec(arg(i)-1); + } + else + { + print_hex((byte_t) (((l4_threadid_t) { + raw : arg(i)}).x0id.task)); + putc('.'); + print_hex((byte_t) (((l4_threadid_t) { + raw : arg(i)}).x0id.thread)); + n += 5; + } + break; + case '%': + putc('%'); + n++; + format++; + continue; + default: + n += print_string("?"); + break; + }; + i++; + break; + default: + putc(*format); + n++; + if(*format == '\n') + putc('\r'); + break; + } + format++; + } + return n; +} + +int sprintf(char* obuf, const char* format, ...) +{ + int printed; + char* buf = obuf; + printed = do_sprintf(&buf, &format); + obuf[printed] = '\0'; + return printed; +}; +#endif diff --git a/kernel/include/.cvsignore b/kernel/include/.cvsignore new file mode 100644 index 0000000..242a04b --- /dev/null +++ b/kernel/include/.cvsignore @@ -0,0 +1,3 @@ +config.h +tcb_layout.h +*.ii *.s diff --git a/kernel/include/arm/brutus/cpu.h b/kernel/include/arm/brutus/cpu.h new file mode 100644 index 0000000..423cbc6 --- /dev/null +++ b/kernel/include/arm/brutus/cpu.h @@ -0,0 +1,42 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/cpu.h + * Description: CPU related definitions specific to the Brutus. + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.4 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__BRUTUS__CPU_H__ +#define __ARM__BRUTUS__CPU_H__ + +#define DCACHE_SIZE 8192 + +#define Flush_ID_Cache() \ + do { \ + volatile dword_t *x; \ + \ + for ( x = (dword_t *) (0x00000000 - DCACHE_SIZE); \ + x != (dword_t *) 0x00000000; \ + x += 8) \ + { \ + __asm__ __volatile__ ("/* clean DCACHE */" : : "r"(*x)); \ + } \ + \ + __asm__ __volatile__ ( \ + " mcr p15, 0, r0, c7, c7, 0 @ Flush I+D \n" \ + " mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf \n" \ + : \ + : \ + : "r0"); \ + \ + } while (0) + + +#define CLOCK_FREQUENCY 3686400 + + +#endif /* !__ARM__BRUTUS__CPU_H__ */ diff --git a/kernel/include/arm/brutus/platform.h b/kernel/include/arm/brutus/platform.h new file mode 100644 index 0000000..5d099d9 --- /dev/null +++ b/kernel/include/arm/brutus/platform.h @@ -0,0 +1,106 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/platform.h + * Description: Definitions specific to the Brutus platform. + * + * @LICENSE@ + * + * $Id: platform.h,v 1.12 2001/12/12 22:28:03 ud3 Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__BRUTUS__PLATFORM_H +#define L4__ARM__BRUTUS__PLATFORM_H + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (10 * 1024) +/* 2 ms per tick */ +#define TIME_QUANTUM (2 * 1024) + + + + + +#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */ +#define angel_SWI_ARM (0xEF123456 & 0xffffff) + +/* Virtual Addresses */ + +#define INTCTRL_VBASE 0xFFF00000 +#define OSTIMER_VBASE 0xFFF10000 +#define UART_VBASE 0xFFF20000 +#define GPIO_VBASE 0xFFF30000 +#define RSTCTL_VBASE 0xFFF40000 + +/* Physical Addresses */ + +#define INTCTRL_PBASE 0x90050000 +#define OSTIMER_PBASE 0x90000000 +#define UART_PBASE 0x80050000 +#define GPIO_PBASE 0x90040000 +#define RSTCTL_PBASE 0x90030000 + +/* base address */ +#define DRAM_BASE 0xC0000000U +/* log2 of the populated size per bank */ +#define DRAM_BANKSIZE_BITS 22 /* 4M */ +/* log2 of the bank distance */ +#define DRAM_BANKDIST_BITS 27 /* 128M */ + +#define DRAM_BANKSIZE (1 << DRAM_BANKSIZE_BITS) +#define DRAM_BANKDIST (1 << DRAM_BANKDIST_BITS) + +/* overall DRAM memory size */ +#define DRAM_SIZE (4*DRAM_BANKSIZE) /* 16M */ + + + +/* + * Interrupt masks + */ +#define INTR_RTC (1<<31) +#define INTR_1HZ_CLOCK (1<<30) +#define INTR_OSTIMER3 (1<<29) +#define INTR_OSTIMER2 (1<<28) +#define INTR_OSTIMER1 (1<<27) +#define INTR_OSTIMER0 (1<<26) + +/* + * Interrupt controller registers. + */ +#define ICIP *((volatile dword_t *) (INTCTRL_VBASE + 0x00)) /* Pending IRQ */ +#define ICMR *((volatile dword_t *) (INTCTRL_VBASE + 0x04)) /* Mask register */ +#define ICLR *((volatile dword_t *) (INTCTRL_VBASE + 0x08)) /* Level reg. */ +#define ICFP *((volatile dword_t *) (INTCTRL_VBASE + 0x10)) /* Pending FIQs */ +#define ICPR *((volatile dword_t *) (INTCTRL_VBASE + 0x20)) /* Pending intr. */ +#define ICCR *((volatile dword_t *) (INTCTRL_VBASE + 0x0c)) /* Control reg. */ + +/* + * OS Timer registers. + */ +#define OSMR0 *((volatile dword_t *) (OSTIMER_VBASE + 0x00)) /* Match reg 0 */ +#define OSMR1 *((volatile dword_t *) (OSTIMER_VBASE + 0x04)) /* Match reg 1 */ +#define OSMR2 *((volatile dword_t *) (OSTIMER_VBASE + 0x08)) /* Match reg 2 */ +#define OSMR3 *((volatile dword_t *) (OSTIMER_VBASE + 0x0c)) /* Match reg 3 */ +#define OSCR *((volatile dword_t *) (OSTIMER_VBASE + 0x10)) /* Count reg. */ +#define OSSR *((volatile dword_t *) (OSTIMER_VBASE + 0x14)) /* Status reg. */ +#define OWER *((volatile dword_t *) (OSTIMER_VBASE + 0x18)) /* Watchdg enbl */ +#define OIER *((volatile dword_t *) (OSTIMER_VBASE + 0x1c)) /* Intr. enable */ + + +/* + * Number of bytes in a cache line. + */ +#define CACHE_LINE_SIZE 32 + + +/* + * For aligning structures on cache line boundaries. + */ +#define CACHE_ALIGN __attribute__ ((aligned (CACHE_LINE_SIZE))) + + +#endif /* !L4__ARM__BRUTUS__PLATFORM_H */ diff --git a/kernel/include/arm/brutus/uart.h b/kernel/include/arm/brutus/uart.h new file mode 100644 index 0000000..7da8d2c --- /dev/null +++ b/kernel/include/arm/brutus/uart.h @@ -0,0 +1,98 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/uart.h + * Description: Definitions for the Brutus UART. + * + * @LICENSE@ + * + * $Id: uart.h,v 1.5 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__BRUTUS__UART_H +#define L4__ARM__BRUTUS__UART_H + +/* + * Base address of UART + */ +#define L4_UART_PBASE 0x80050000 +#define L4_UART_BASE UART_VBASE /* In platform.h */ + +/* Control registers */ +#define L4_UART_UTCR0 *((volatile dword_t *) (L4_UART_BASE + 0x00)) +#define L4_UART_UTCR1 *((volatile dword_t *) (L4_UART_BASE + 0x04)) +#define L4_UART_UTCR2 *((volatile dword_t *) (L4_UART_BASE + 0x08)) +#define L4_UART_UTCR3 *((volatile dword_t *) (L4_UART_BASE + 0x0c)) + +/* Data register */ +#define L4_UART_UTDR *((volatile dword_t *) (L4_UART_BASE + 0x14)) + +/* Status registers */ +#define L4_UART_UTSR0 *((volatile dword_t *) (L4_UART_BASE + 0x1c)) +#define L4_UART_UTSR1 *((volatile dword_t *) (L4_UART_BASE + 0x20)) + + + +/* + * Bits defined in control register 0. + */ +#define L4_UART_PE (1 << 0) /* Parity enable */ +#define L4_UART_OES (1 << 1) /* Odd/even parity select */ +#define L4_UART_SBS (1 << 2) /* Stop bit select */ +#define L4_UART_DSS (1 << 3) /* Data size select */ +#define L4_UART_SCE (1 << 4) /* Sample clock rate enable */ +#define L4_UART_RCE (1 << 5) /* Receive clk. rate edge select */ +#define L4_UART_TCE (1 << 6) /* Transmit clk. rate edge select */ + + +/* + * Bits defined in control register 3. + */ +#define L4_UART_RXE (1 << 0) /* Receiver enable */ +#define L4_UART_TXE (1 << 1) /* Transmitter enable */ +#define L4_UART_BRK (1 << 2) /* Break */ +#define L4_UART_RIO (1 << 3) /* Receive FIFO interrupt enable */ +#define L4_UART_TIE (1 << 4) /* Transmit FIFO interrupt enable */ +#define L4_UART_LBM (1 << 5) /* Loopback mode */ + + +/* + * Baud rate devisror (contained in control registers 1 and 2). + */ +#define L4_UART_GET_BRD() \ + ( (((l4_uint32_t) L4_UART_UTCR1 & 0x0f) << 8) + \ + (l4_uint8_t) L4_UART_UTCR2 ) + +#define L4_UART_SET_BRD(brd) \ + ( *(l4_uint32_t *) L4_UART_UTCR1 = brd & 0xff, \ + *(l4_uint32_t *) L4_UART_UTCR2 = (brd >> 8) & 0x0f ) \ + +#define L4_BRD_TO_BAUDRATE(brd) (3686400 / ((brd+1) << 4)) +#define L4_BAUDRATE_TO_BRD(rate) (3686400 / (rate << 4) - 1) + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TFS (1 << 0) /* Transmit FIFO service req. */ +#define L4_UART_RFS (1 << 1) /* Receive FIFO service req. */ +#define L4_UART_RID (1 << 2) /* Receiver idle */ +#define L4_UART_RBB (1 << 3) /* Receiver begin of break */ +#define L4_UART_REB (1 << 4) /* Receiver end of break */ +#define L4_UART_EIF (1 << 5) /* Error in FIFO */ + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TBY (1 << 0) /* Transmitter busy flag */ +#define L4_UART_RNE (1 << 1) /* Receiver FIFO not empty */ +#define L4_UART_TNF (1 << 2) /* Transmitter FIFO not full */ +#define L4_UART_PRE (1 << 3) /* Parity error */ +#define L4_UART_FRE (1 << 4) /* Framing error */ +#define L4_UART_ROR (1 << 5) /* Receive FIFO overrun */ + + + +#endif /* !L4__ARM__BRUTUS__UART_H */ diff --git a/kernel/include/arm/config.h b/kernel/include/arm/config.h new file mode 100755 index 0000000..d3fd73e --- /dev/null +++ b/kernel/include/arm/config.h @@ -0,0 +1,56 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/config.h + * Description: Various kernel configuration stuff for ARM. + * + * @LICENSE@ + * + * $Id: config.h,v 1.14 2001/11/22 15:09:12 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__CONFIG_H__ +#define __ARM__CONFIG_H__ + +/* On ARM we need farcalls for invoking certain functions. */ +#define NEED_FARCALLS 1 + + +#include INC_PLATFORM(platform.h) + +/* thread configuration */ +#define TCB_AREA 0xE0000000 +#define TCB_AREA_SIZE 0x01000000 + +#define L4_NUMBITS_TCBS 10 +#define L4_NUMBITS_THREADS 22 + +#define L4_TOTAL_TCB_SIZE (1 << L4_NUMBITS_TCBS) +#define L4_TCB_DATA_SIZE 88 +#define L4_TCB_STACK_SIZE (L4_TOTAL_TCB_SIZE - L4_TCB_DATA_SIZE) + +#define L4_TCB_MASK ((~0) << L4_NUMBITS_TCBS) + + +#define KERNEL_VIRT 0xFFFF0000 +#define KERNEL_SIZE 0x00010000 + +#define KERNEL_OFFSET (KERNEL_VIRT - KERNEL_PHYS) + +#define cpaddr 0xF0000000U + +#define IN_KERNEL_AREA(x) ((x) > TCB_AREA) + + +/* the copy areas cover two 1st level entries */ +#define MEM_COPYAREA1 0xFF800000 +#define MEM_COPYAREA2 (MEM_COPYAREA1 + (PAGEDIR_SIZE * 2)) +#define MEM_COPYAREA_END (MEM_COPYAREA2 + (PAGEDIR_SIZE * 2)) + + +#if defined(CONFIG_USE_ARCH_KMEMORY) +#define HAVE_ARCH_KMEMORY +#endif + +#endif /* __ARM__CONFIG_H__ */ diff --git a/kernel/include/arm/cpu.h b/kernel/include/arm/cpu.h new file mode 100644 index 0000000..c8bf478 --- /dev/null +++ b/kernel/include/arm/cpu.h @@ -0,0 +1,137 @@ +/********************************************************************* + * + * Copyright (C) 1999 2000, 2001, Karlsruhe University + * + * File path: arm/cpu.h + * Description: ARM specific declarations. + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.19 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__CPU_H__ +#define __ARM__CPU_H__ + +/* CP15 Control Register */ + +#define CTL_MMU_ENABLED 0x0001 +#define CTL_ADDR_FAULT 0x0002 +#define CTL_DCACHE 0x0004 +#define CTL_WRITE_BUF 0x0008 +#define CTL_BIG_ENDIAN 0x0080 +#define CTL_SYS_PROT 0x0100 +#define CTL_ROM_PROT 0x0200 +#define CTL_ICACHE 0x1000 +#define CTL_IVECTOR 0x2000 + +/* Control Bits */ + +#define IRQ_MASK (1 << 7) /* IRQ Disable Bit */ +#define FIQ_MASK (1 << 6) /* FIQ Disable Bit */ +#define THUMB_CODE (1 << 5) /* thumb code mode */ +#define USER_MODE (0x10) /* USER Mode */ +#define FIQ_MODE (0x11) /* FIQ Mode */ +#define IRQ_MODE (0x12) /* IRQ Mode */ +#define SVC_MODE (0x13) /* SVC Mode */ +#define ABORT_MODE (0x17) /* ABORT Mode */ +#define UNDEF_MODE (0x1B) /* UNDEF Mode */ +#define SYSTEM_MODE (0x1F) /* SYSTEM Mode */ + +/* the mode all kernel activities are executed in */ +#define KERNEL_MODE (SVC_MODE) + +#define MODE_MASK 0x0000000F + +/* kernel identification - we are on ARM */ +#define KERNEL_VERSION_VER KERNEL_VERSION_CPU_ARM + +#ifndef ASSEMBLY + +#include INC_PLATFORM(cpu.h) + +/********* +* Macros * +*********/ + + +/* CP15 Flush Instruction TLB & Data TLB */ +INLINE void flush_tlb() +{ + __asm__ __volatile__ + ("mcr p15, 0, r0, c8, c7, 0"); +} + + +INLINE void flush_tlbent(ptr_t addr) +{ + __asm__ __volatile__ + ("mcr p15, 0, r0, c8, c7, 0"); +} + + +INLINE void enable_interrupts() +{ + register dword_t foo; + __asm__ __volatile__ ( + "/* enable_interrupts() */ \n" + " mrs %0, cpsr \n" + " and %0, %0, %1 \n" + " msr cpsr, %0 \n" + : "=r" (foo) + : "i" (~(IRQ_MASK|FIQ_MASK))); +} + +INLINE void disable_interrupts() +{ + register dword_t foo; + __asm__ __volatile__ ( + "/* disable_interrupts() */ \n" + " mrs %0, cpsr \n" + " or %0, %0, %1 \n" + " msr cpsr, %0 \n" + : "=r" (foo) + : "i" (IRQ_MASK|FIQ_MASK)); +} + + +INLINE void system_sleep() +{ + /* we have no sleep, haven't we? */ + register dword_t foo, foo2; + __asm__ __volatile__ ( + "/* enable_interrupts(start) */ \n" + " mrs %0, cpsr \n" + " mov %1, %2 \n" + " msr cpsr, %1 \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " msr cpsr, %0 \n" + : "=r" (foo), "=r" (foo2) + : "i" (KERNEL_MODE)); +} + + +typedef struct { + dword_t r0, r1, r2 , r3 , r4 , r5, r6, r7; + dword_t r8, r9, r10, r11, r12, r13, r14; + dword_t sp, lr, cpsr, spsr; + dword_t excp_no; +} exception_frame_t; + +#endif /* ASSEMBLY */ + +#endif /* __ARM__CPU_H__ */ diff --git a/kernel/include/arm/dnard/cpu.h b/kernel/include/arm/dnard/cpu.h new file mode 100644 index 0000000..9937451 --- /dev/null +++ b/kernel/include/arm/dnard/cpu.h @@ -0,0 +1,33 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/dnard/cpu.h + * Description: DNARD specific functions and declarations. + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.2 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__DNARD__CPU_H__ +#define __ARM__DNARD__CPU_H__ + +/* CP15 Flush Instruction Cache & Data Cache */ +#define Flush_ID_Cache() \ + do { \ + \ + volatile dword_t* x; \ + for (x = (dword_t*) 0xFFFFC000; \ + x != (dword_t*) 0x00000000; \ + x += 4) \ + __asm__ __volatile__ ("/* clean DCACHE */" : : "r"(*x)); \ + \ + __asm__ __volatile__ \ + ( \ + "mcr p15, 0, r0, c7, c7, 0 \n" \ + "mcr p15, 0, r0, c7, c10, 4 \n" \ + : : : "r0" ); \ + } while (0) + +#endif /* !__ARM__DNARD__CPU_H__ */ diff --git a/kernel/include/arm/dnard/platform.h b/kernel/include/arm/dnard/platform.h new file mode 100644 index 0000000..8c41bf2 --- /dev/null +++ b/kernel/include/arm/dnard/platform.h @@ -0,0 +1,104 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/dnard/platform.h + * Description: Platform configurations for DNARD. + * + * @LICENSE@ + * + * $Id: platform.h,v 1.12 2001/12/11 23:25:39 ud3 Exp $ + * + ********************************************************************/ + +/* this file contains ARM specific declarations */ +#ifndef __ARM_DNARD_PLATFORM_H__ +#define __ARM_DNARD_PLATFORM_H__ + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (10 * 1024) +/* 2 ms per tick */ +#define TIME_QUANTUM (2 * 1024) + + + + +#define IO_PBASE 0x40000000 +#define IO_VBASE 0xFFF00000 + +/* base address */ +#define DRAM_BASE 0x08000000U +/* log2 of the populated size per bank */ +#define DRAM_BANKSIZE_BITS 23 /* 8M */ +/* log2 of the bank distance */ +#define DRAM_BANKDIST_BITS 25 /* 32M */ + +#define DRAM_BANKSIZE (1 << DRAM_BANKSIZE_BITS) +#define DRAM_BANKDIST (1 << DRAM_BANKDIST_BITS) + +/* overall DRAM memory size */ +#define DRAM_SIZE (4*DRAM_BANKSIZE) /* 32M */ + + + +#define COM1_BASE 0x000003F8 + + +#define RTC_REG 0x70 +#define RTC_DATA 0x71 + + + +#ifndef ASSEMBLY +INLINE void outb(dword_t port, byte_t val) +{ + __asm__("@ outb <<<<<"); + *(volatile byte_t*) (IO_VBASE + port) = val; + __asm__("@ outb >>>>>"); +} + +INLINE byte_t inb(dword_t port) +{ + __asm__("@ inb <<<<<"); + return *(volatile byte_t*) (IO_VBASE + port); + __asm__("@ inb >>>>>"); +} + +INLINE void outw(dword_t port, word_t val) +{ + __asm__("@ outw <<<<<"); + *(volatile word_t*) (IO_VBASE + port) = val; + __asm__("@ outw >>>>>"); +} + +INLINE word_t inw(dword_t port) +{ + __asm__("@ inw <<<<<"); + return *(volatile word_t*) (IO_VBASE + port); + __asm__("@ inw >>>>>"); +} + +INLINE void out_rtc(dword_t reg, byte_t val) +{ + __asm__("@ out_rtc <<<<<"); + *(volatile byte_t*) (IO_VBASE + RTC_REG) = reg; + __asm__("@ out_rtc -----"); + *(volatile byte_t*) (IO_VBASE + RTC_DATA) = val; + __asm__("@ out_rtc >>>>>>"); +} + +INLINE byte_t in_rtc(dword_t reg) +{ + __asm__("@ in_rtc <<<<<"); + *(volatile byte_t*) (IO_VBASE + RTC_REG) = reg; + __asm__("@ in_rtc -----"); + return *(volatile char*) (IO_VBASE + RTC_DATA); + __asm__("@ in_rtc >>>>>"); +} +#endif /* !ASSEMBLY */ + + + +#endif /* __ARM_DNARD_PLATFORM_H__ */ diff --git a/kernel/include/arm/ep7211/cpu.h b/kernel/include/arm/ep7211/cpu.h new file mode 100644 index 0000000..889a165 --- /dev/null +++ b/kernel/include/arm/ep7211/cpu.h @@ -0,0 +1,35 @@ +/********************************************************************* + * + * Copyright (C) 1999, 200, 2001, Karlsruhe University + * + * File path: arm/ep7211/cpu.h + * Description: CPU related declarations specific to EP7211. + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.2 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__EP7211__CPU_H__ +#define __ARM__EP7211__CPU_H__ + +/* CP15 Flush Instruction Cache & Data Cache */ +#define Flush_ID_Cache() \ + do { \ + \ + volatile dword_t* x; \ + for (x = (dword_t*) 0xFFFFC000; \ + x != (dword_t*) 0x00000000; \ + x += 4) \ + __asm__ __volatile__ ("/* clean DCACHE */" : : "r"(*x)); \ + \ + __asm__ __volatile__ \ + ( \ + "mcr p15, 0, r0, c7, c7, 0 \n" \ + "mcr p15, 0, r0, c7, c10, 4 \n" \ + : : : "r0" ); \ + } while (0) + +#endif /* !__ARM__EP7211__CPU_H__ */ + + diff --git a/kernel/include/arm/ep7211/platform.h b/kernel/include/arm/ep7211/platform.h new file mode 100644 index 0000000..8bebaeb --- /dev/null +++ b/kernel/include/arm/ep7211/platform.h @@ -0,0 +1,137 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ep7211/platform.h + * Description: Definitions specific to the EP7211 platform. + * + * @LICENSE@ + * + * $Id: platform.h,v 1.9 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__EP7211__PLATFORM_H__ +#define __ARM__EP7211__PLATFORM_H__ + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (15 * 1024) +/* 2 ms per tick */ +#define TIME_QUANTUM (15 * 1024) + + +/* + * Physical memory description + + | | + +------------+ + | empty | + +------------+ + | DRAM3 | + +------------+ + | empty | + +------------+ + | DRAM2 | + +------------+ + | empty | + +------------+ + | DRAM1 | + +------------+ DRAM_BASE + DRAM_BANKDIST + | empty | + +------------+ DRAM_BASE + DRAM_BANKSIZE + | DRAM0 | + +------------+ DRAM_BASE + | | +*/ + +/* base address */ +#define DRAM_BASE 0xC0000000U +/* log2 of the populated size per bank */ +#define DRAM_BANKSIZE_BITS 23 /* 8M */ +/* log2 of the bank distance */ +#define DRAM_BANKDIST_BITS 28 /* 256M */ + +#define DRAM_BANKSIZE (1 << DRAM_BANKSIZE_BITS) +#define DRAM_BANKDIST (1 << DRAM_BANKDIST_BITS) + +/* overall DRAM memory size */ +#define DRAM_SIZE (1*DRAM_BANKSIZE) /* 8M ??? */ + + + +#define IO_PBASE 0x80000000U +#define IO_VBASE 0xFFF00000 + +#define COM1_BASE 0x00000480 +#define COM2_BASE 0x00001480 +#define SYSFLG 0x00000140 /*System status registers*/ +#define SYSFLG2 0x00001140 +#define SYSCON 0x00000100 /*System control registers*/ +#define SYSCON2 0x00001100 +#define SYSCON3 0x00002200 + +#ifndef ASSEMBLY +static inline void outb(dword_t port, char val) +{ +// printf("%s(%x,%x)\n", __FUNCTION__, port, val); + __asm__("@ outb >>>>>"); + *(volatile char*) (IO_VBASE + port) = val; + __asm__("@ outb <<<<< "); +} + +static inline char inb(dword_t port) +{ + char t; + __asm__("@ inb >>>>>"); + t = *(volatile char*) (IO_VBASE + port); + __asm__("@ inb <<<<< "); +// printf("%s(%x)=%x\n", __FUNCTION__, port, t); + return t; +} + +static inline void outdw(dword_t port, dword_t val) +{ +// printf("%s(%x,%x)\n", __FUNCTION__, port, val); + __asm__("@ outw >>>>>"); + *(volatile dword_t*) (IO_VBASE + port) = val; + __asm__("@ outw <<<<< "); +} + +static inline dword_t indw(dword_t port) +{ + dword_t t; + __asm__("@ inw >>>>>"); + t = *(volatile dword_t*) (IO_VBASE + port); + __asm__("@ inw <<<<< "); +// printf("%s(%x)=%x\n", __FUNCTION__, port, t); + return t; +} + +#define RTC_MATCH 0x3C0 //generate interrupt if DATA=MATCH +#define RTC_DATA 0x380 //RTC data 32 bit, direkt R/W + +/* hier wird es noch krachen +static inline void out_rtc(dword_t reg, dword_t val) +{ +// printf("%s(%x,%x)\n", __FUNCTION__, reg, val); + __asm__("@ out_rtc >>>>>"); + *(volatile dword_t*) (IO_VBASE + RTC_DATA) = val; + __asm__("@ out_rtc <<<<< "); +} + +static inline char in_rtc(dword_t reg) +{ + char t; + __asm__("@ in_rtc >>>>>"); + t = *(volatile dword_t*) (IO_VBASE + RTC_DATA); + __asm__("@ in_rtc <<<<< "); +// printf("%s(%x)=%x\n", __FUNCTION__, reg, t); + return t; +} + +*/ +#endif /* ASSEMBLY */ + +#endif /* __ARM__EP7211__PLATFORM_H__ */ + diff --git a/kernel/include/arm/farcalls.h b/kernel/include/arm/farcalls.h new file mode 100644 index 0000000..d14e694 --- /dev/null +++ b/kernel/include/arm/farcalls.h @@ -0,0 +1,24 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/farcalls.h + * Description: Farcall wrappers. + * + * @LICENSE@ + * + * $Id: farcalls.h,v 1.10 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__FARCALLS_H__ +#define __ARM__FARCALLS_H__ + +extern int (*__farcall_printf)(const char *, ...); +extern void (*__farcall_panic)(const char*); +extern void (*__farcall_kmem_free)(ptr_t address, dword_t size); + +#define printf __farcall_printf +#define panic __farcall_panic +#define kmem_free __farcall_kmem_free + +#endif /* __ARM__FARCALLS_H__ */ diff --git a/kernel/include/arm/ipaq/cpu.h b/kernel/include/arm/ipaq/cpu.h new file mode 100644 index 0000000..7265cb3 --- /dev/null +++ b/kernel/include/arm/ipaq/cpu.h @@ -0,0 +1,43 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/cpu.h + * Description: CPU related definitions specific to the IPaq. + * based on Brutus code + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.1 2002/01/24 07:15:41 uhlig Exp $ + * + ********************************************************************/ +#ifndef __ARM__IPAQ__CPU_H__ +#define __ARM__IPAQ__CPU_H__ + +#define DCACHE_SIZE 8192 + +#define Flush_ID_Cache() \ + do { \ + volatile dword_t *x; \ + \ + for ( x = (dword_t *) (0x00000000 - DCACHE_SIZE); \ + x != (dword_t *) 0x00000000; \ + x += 8) \ + { \ + __asm__ __volatile__ ("/* clean DCACHE */" : : "r"(*x)); \ + } \ + \ + __asm__ __volatile__ ( \ + " mcr p15, 0, r0, c7, c7, 0 @ Flush I+D \n" \ + " mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf \n" \ + : \ + : \ + : "r0"); \ + \ + } while (0) + + +#define CLOCK_FREQUENCY 3686400 + + +#endif /* !__ARM__IPAQ__CPU_H__ */ diff --git a/kernel/include/arm/ipaq/platform.h b/kernel/include/arm/ipaq/platform.h new file mode 100644 index 0000000..f979285 --- /dev/null +++ b/kernel/include/arm/ipaq/platform.h @@ -0,0 +1,106 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/platform.h + * Description: Definitions specific to the IPaq platform. + * + * @LICENSE@ + * + * $Id: platform.h,v 1.1 2002/01/24 07:15:41 uhlig Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__IPAQ__PLATFORM_H +#define L4__ARM__IPAQ__PLATFORM_H + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (10 * 1024) +/* 2 ms per tick */ +#define TIME_QUANTUM (2 * 1024) + + + + + +#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */ +#define angel_SWI_ARM (0xEF123456 & 0xffffff) + +/* Virtual Addresses */ + +#define INTCTRL_VBASE 0xFFF00000 +#define OSTIMER_VBASE 0xFFF10000 +#define UART_VBASE 0xFFF20000 +#define GPIO_VBASE 0xFFF30000 +#define RSTCTL_VBASE 0xFFF40000 + +/* Physical Addresses */ + +#define INTCTRL_PBASE 0x90050000 +#define OSTIMER_PBASE 0x90000000 +#define UART_PBASE 0x80050000 +#define GPIO_PBASE 0x90040000 +#define RSTCTL_PBASE 0x90030000 + +/* base address */ +#define DRAM_BASE 0xC0000000U +/* log2 of the populated size per bank */ +#define DRAM_BANKSIZE_BITS 22 /* 4M */ +/* log2 of the bank distance */ +#define DRAM_BANKDIST_BITS 27 /* 128M */ + +#define DRAM_BANKSIZE (1 << DRAM_BANKSIZE_BITS) +#define DRAM_BANKDIST (1 << DRAM_BANKDIST_BITS) + +/* overall DRAM memory size */ +#define DRAM_SIZE (4*DRAM_BANKSIZE) /* 16M */ + + + +/* + * Interrupt masks + */ +#define INTR_RTC (1<<31) +#define INTR_1HZ_CLOCK (1<<30) +#define INTR_OSTIMER3 (1<<29) +#define INTR_OSTIMER2 (1<<28) +#define INTR_OSTIMER1 (1<<27) +#define INTR_OSTIMER0 (1<<26) + +/* + * Interrupt controller registers. + */ +#define ICIP *((volatile dword_t *) (INTCTRL_VBASE + 0x00)) /* Pending IRQ */ +#define ICMR *((volatile dword_t *) (INTCTRL_VBASE + 0x04)) /* Mask register */ +#define ICLR *((volatile dword_t *) (INTCTRL_VBASE + 0x08)) /* Level reg. */ +#define ICFP *((volatile dword_t *) (INTCTRL_VBASE + 0x10)) /* Pending FIQs */ +#define ICPR *((volatile dword_t *) (INTCTRL_VBASE + 0x20)) /* Pending intr. */ +#define ICCR *((volatile dword_t *) (INTCTRL_VBASE + 0x0c)) /* Control reg. */ + +/* + * OS Timer registers. + */ +#define OSMR0 *((volatile dword_t *) (OSTIMER_VBASE + 0x00)) /* Match reg 0 */ +#define OSMR1 *((volatile dword_t *) (OSTIMER_VBASE + 0x04)) /* Match reg 1 */ +#define OSMR2 *((volatile dword_t *) (OSTIMER_VBASE + 0x08)) /* Match reg 2 */ +#define OSMR3 *((volatile dword_t *) (OSTIMER_VBASE + 0x0c)) /* Match reg 3 */ +#define OSCR *((volatile dword_t *) (OSTIMER_VBASE + 0x10)) /* Count reg. */ +#define OSSR *((volatile dword_t *) (OSTIMER_VBASE + 0x14)) /* Status reg. */ +#define OWER *((volatile dword_t *) (OSTIMER_VBASE + 0x18)) /* Watchdg enbl */ +#define OIER *((volatile dword_t *) (OSTIMER_VBASE + 0x1c)) /* Intr. enable */ + + +/* + * Number of bytes in a cache line. + */ +#define CACHE_LINE_SIZE 32 + + +/* + * For aligning structures on cache line boundaries. + */ +#define CACHE_ALIGN __attribute__ ((aligned (CACHE_LINE_SIZE))) + + +#endif /* !L4__ARM__IPAQ__PLATFORM_H */ diff --git a/kernel/include/arm/ipaq/uart.h b/kernel/include/arm/ipaq/uart.h new file mode 100644 index 0000000..02373e4 --- /dev/null +++ b/kernel/include/arm/ipaq/uart.h @@ -0,0 +1,98 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/uart.h + * Description: Definitions for the IPaq UART. + * + * @LICENSE@ + * + * $Id: uart.h,v 1.1 2002/01/24 07:15:41 uhlig Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__IPAQ__UART_H +#define L4__ARM__IPAQ__UART_H + +/* + * Base address of UART + */ +#define L4_UART_PBASE 0x80050000 +#define L4_UART_BASE UART_VBASE /* In platform.h */ + +/* Control registers */ +#define L4_UART_UTCR0 *((volatile dword_t *) (L4_UART_BASE + 0x00)) +#define L4_UART_UTCR1 *((volatile dword_t *) (L4_UART_BASE + 0x04)) +#define L4_UART_UTCR2 *((volatile dword_t *) (L4_UART_BASE + 0x08)) +#define L4_UART_UTCR3 *((volatile dword_t *) (L4_UART_BASE + 0x0c)) + +/* Data register */ +#define L4_UART_UTDR *((volatile dword_t *) (L4_UART_BASE + 0x14)) + +/* Status registers */ +#define L4_UART_UTSR0 *((volatile dword_t *) (L4_UART_BASE + 0x1c)) +#define L4_UART_UTSR1 *((volatile dword_t *) (L4_UART_BASE + 0x20)) + + + +/* + * Bits defined in control register 0. + */ +#define L4_UART_PE (1 << 0) /* Parity enable */ +#define L4_UART_OES (1 << 1) /* Odd/even parity select */ +#define L4_UART_SBS (1 << 2) /* Stop bit select */ +#define L4_UART_DSS (1 << 3) /* Data size select */ +#define L4_UART_SCE (1 << 4) /* Sample clock rate enable */ +#define L4_UART_RCE (1 << 5) /* Receive clk. rate edge select */ +#define L4_UART_TCE (1 << 6) /* Transmit clk. rate edge select */ + + +/* + * Bits defined in control register 3. + */ +#define L4_UART_RXE (1 << 0) /* Receiver enable */ +#define L4_UART_TXE (1 << 1) /* Transmitter enable */ +#define L4_UART_BRK (1 << 2) /* Break */ +#define L4_UART_RIO (1 << 3) /* Receive FIFO interrupt enable */ +#define L4_UART_TIE (1 << 4) /* Transmit FIFO interrupt enable */ +#define L4_UART_LBM (1 << 5) /* Loopback mode */ + + +/* + * Baud rate devisror (contained in control registers 1 and 2). + */ +#define L4_UART_GET_BRD() \ + ( (((l4_uint32_t) L4_UART_UTCR1 & 0x0f) << 8) + \ + (l4_uint8_t) L4_UART_UTCR2 ) + +#define L4_UART_SET_BRD(brd) \ + ( *(l4_uint32_t *) L4_UART_UTCR1 = brd & 0xff, \ + *(l4_uint32_t *) L4_UART_UTCR2 = (brd >> 8) & 0x0f ) \ + +#define L4_BRD_TO_BAUDRATE(brd) (3686400 / ((brd+1) << 4)) +#define L4_BAUDRATE_TO_BRD(rate) (3686400 / (rate << 4) - 1) + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TFS (1 << 0) /* Transmit FIFO service req. */ +#define L4_UART_RFS (1 << 1) /* Receive FIFO service req. */ +#define L4_UART_RID (1 << 2) /* Receiver idle */ +#define L4_UART_RBB (1 << 3) /* Receiver begin of break */ +#define L4_UART_REB (1 << 4) /* Receiver end of break */ +#define L4_UART_EIF (1 << 5) /* Error in FIFO */ + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TBY (1 << 0) /* Transmitter busy flag */ +#define L4_UART_RNE (1 << 1) /* Receiver FIFO not empty */ +#define L4_UART_TNF (1 << 2) /* Transmitter FIFO not full */ +#define L4_UART_PRE (1 << 3) /* Parity error */ +#define L4_UART_FRE (1 << 4) /* Framing error */ +#define L4_UART_ROR (1 << 5) /* Receive FIFO overrun */ + + + +#endif /* !L4__ARM__IPAQ__UART_H */ diff --git a/kernel/include/arm/kdebug.h b/kernel/include/arm/kdebug.h new file mode 100644 index 0000000..1f8165e --- /dev/null +++ b/kernel/include/arm/kdebug.h @@ -0,0 +1,66 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/kdebug.h + * Description: Kdebug macros specific to ARM. + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.11 2001/12/11 23:27:21 ud3 Exp $ + * + ********************************************************************/ +#ifndef __ARM__KDEBUG_H__ +#define __ARM__KDEBUG_H__ + +INLINE void spin(int pos = 80) +{ + panic(__FUNCTION__); + while (1); +} + +INLINE void spin1(dword_t x) +{ + //putc('_'); +} + +#if 0 +INLINE void enter_kdebug(const char* message = NULL) +{ + if (message) + printf(message); + + __asm__ __volatile__ ( + "2: adr lr, 1f \n" + " ldr pc, 0f \n" + "0: .word kern_kdebug_entry \n" + "1: \n" + ); +} +#else +#define enter_kdebug(args...) \ +{ \ + printf("KD# " args ); \ + \ + __asm__ __volatile__ ( \ + "2: adr lr, 1f \n" \ + " ldr pc, 0f \n" \ + "0: .word kern_kdebug_entry \n" \ + "1: \n" \ + ); \ +} +#endif + +INLINE ptr_t get_current_pgtable() +{ + dword_t x; + + __asm__ __volatile__ ( + " mrc p15, 0, %0, c2, c0, 0 \n" + :"=r"(x)); + + return (ptr_t) (x & ~((1<<14) - 1)); +} + +#endif /* __ARM__KDEBUG_H__ */ + diff --git a/kernel/include/arm/kmemory.h b/kernel/include/arm/kmemory.h new file mode 100644 index 0000000..58021eb --- /dev/null +++ b/kernel/include/arm/kmemory.h @@ -0,0 +1,92 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/kmemory.h + * Description: ARM specific kernel memory allocator. + * + * @LICENSE@ + * + * $Id: kmemory.h,v 1.4 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__KMEMORY_H__ +#define __ARM__KMEMORY_H__ + +void panic(const char *msg) L4_SECT_KDEBUG; + + +/* + * Prototypes. + */ +ptr_t kmem_alloc_1k(void); +ptr_t kmem_alloc_4k(void); +ptr_t kmem_alloc_16k(void); +void kmem_free_1k(ptr_t); +void kmem_free_4k(ptr_t); +void kmem_free_16k(ptr_t); + + +/* + * Macro kmem_alloc (size) + * + * Allocate an aligned buffer of the indicated size (1K, 4K, or + * 16K). Gcc should be able to optimize away the if's. + * + */ +#define kmem_alloc(size) \ +({ \ + ptr_t r; \ + \ + if ( size == 1024 ) \ + r = kmem_alloc_1k(); \ + else if ( size == 4096 ) \ + r = kmem_alloc_4k(); \ + else if ( size == 16384 ) \ + r = kmem_alloc_16k(); \ + else \ + panic("kmem_alloc() -- unsopported block size.\n"); \ + \ + r; \ +}) + + +/* + * Function kmem_free (addr, size) + * + * Free the indicated buffer (of 1K, 4K, or 16K size). + * + */ +INLINE void kmem_free(ptr_t addr, dword_t size) +{ + if ( size == 1024 ) + return kmem_free_1k(addr); + else if ( size == 4096 ) + return kmem_free_4k(addr); + else if ( size == 16384 ) + return kmem_free_16k(addr); + else + panic("kmem_free() -- unsopported block size.\n"); +} + + +/* + * Masks and shift numbers for kmem pages. + */ +#define KMEM_16K_MASK 0x3fff +#define KMEM_4K_MASK 0x0fff +#define KMEM_1K_MASK 0x03ff + +#define KMEM_16K_SHIFT 14 +#define KMEM_4K_SHIFT 12 +#define KMEM_1K_SHIFT 10 + + +/* + * Amount of initial memory to allocate to the different freelists. + */ +#define KMEM_INIT_4K_RATIO 1 / 1 +#define KMEM_INIT_1K_RATIO 0 + + +#endif /* !__ARM__KMEMORY_H__ */ diff --git a/kernel/include/arm/mapping.h b/kernel/include/arm/mapping.h new file mode 100644 index 0000000..530bd2b --- /dev/null +++ b/kernel/include/arm/mapping.h @@ -0,0 +1,211 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm/mapping.h + * Description: ARM specific mapping database settings. + * + * @LICENSE@ + * + * $Id: mapping.h,v 1.3 2001/12/07 19:06:32 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__MAPPING_H__ +#define __ARM__MAPPING_H__ + + +#define SIGMA0_PGDIR_ID 0 +#define NUM_PAGESIZES 4 + + +#define MDB_BIT_LOCK(word, bit) +#define MDB_BIT_TRYLOCK(word, bit) (1) +#define MDB_BIT_UNLOCK(word, bit) + + + +class pgent_t; +class rnode_t; + + +#define MDB_NEXT_ROOT 0x01 +#define MDB_PREV_ROOT 0x01 + +#define MDB_SPACE_MASK 0xfffff000 +#define MDB_DEPTH_MASK 0x000000ff +#define MDB_UPLOCK_BIT 8 +#define MDB_DOWNLOCK_BIT 9 +#define MDB_UPLOCK (1 << MDB_UPLOCK_BIT) +#define MDB_DOWNLOCK (1 << MDB_DOWNLOCK_BIT) + + +class mnode_t +{ + public: + volatile unsigned long w1; // Prev pointer, pgent_t pointer + volatile unsigned long w2; // Space, tree depth, type bits + volatile unsigned long w3; // Next pointer + + inline void down_lock(void) + { MDB_BIT_LOCK(w2, MDB_DOWNLOCK_BIT); } + + inline int down_trylock(void) + { return MDB_BIT_TRYLOCK(w2, MDB_DOWNLOCK_BIT); } + + inline void down_unlock(void) + { MDB_BIT_UNLOCK(w2, MDB_DOWNLOCK_BIT); } + + inline void up_lock(void) + { MDB_BIT_LOCK(w2, MDB_UPLOCK_BIT); } + + inline int up_trylock(void) + { return MDB_BIT_TRYLOCK(w2, MDB_UPLOCK_BIT); } + + inline void up_unlock(void) + { MDB_BIT_UNLOCK(w2, MDB_UPLOCK_BIT); } + + inline void clear_locks(void) + { w2 &= ~(MDB_UPLOCK | MDB_DOWNLOCK); } + + + // Previous pointer and backing pointer + + inline pgent_t *get_pgent(mnode_t *prev) + { + return (pgent_t *) (w1 ^ (dword_t) prev); + } + + inline pgent_t *get_pgent(rnode_t *prev) + { + return (pgent_t *) ((w1 ^ (dword_t) prev) & ~MDB_PREV_ROOT); + } + + inline mnode_t *get_prevm(pgent_t *pg) + { + return (mnode_t *) ((w1 ^ (dword_t) pg) & ~MDB_PREV_ROOT); + } + + inline rnode_t *get_prevr(pgent_t *pg) + { + return (rnode_t *) ((w1 ^ (dword_t) pg) & ~MDB_PREV_ROOT); + } + + inline void set_backlink(mnode_t *prev, pgent_t *pg) + { + w1 = (dword_t) prev ^ (dword_t) pg; + } + + inline void set_backlink(rnode_t *prev, pgent_t *pg) + { + w1 = ((dword_t) prev ^ (dword_t) pg) | MDB_PREV_ROOT; + } + + inline int is_prev_root(void) + { + return w1 & MDB_PREV_ROOT; + } + + + // Next pointer + + inline mnode_t *get_nextm(void) + { + return (mnode_t *) (w3 & ~MDB_NEXT_ROOT); + } + + inline rnode_t *get_nextr(void) + { + return (rnode_t *) (w3 & ~MDB_NEXT_ROOT); + } + + inline void set_next(mnode_t *map) + { + w3 = (dword_t) map; + } + + inline void set_next(rnode_t *root) + { + w3 = (dword_t) root | MDB_NEXT_ROOT; + } + + inline int is_next_root(void) + { + return w3 & MDB_NEXT_ROOT; + } + + + // Address space identifier + + inline space_t * get_space (void) + { + return (space_t *) (w2 & MDB_SPACE_MASK); + } + + inline void set_space (space_t * space) + { + w2 = (w2 & ~MDB_SPACE_MASK) | ((dword_t) space & MDB_SPACE_MASK); + } + + + // Tree depth + + inline dword_t get_depth(void) + { + return w2 & MDB_DEPTH_MASK; + } + + inline void set_depth(dword_t depth) + { + w2 = (w2 & ~MDB_DEPTH_MASK) | (depth & MDB_DEPTH_MASK); + } + +} __attribute__ ((packed)); + + +#define MDB_RNEXT_ROOT 0x01 +#define MDB_RDOWNLOCK_BIT 1 +#define MDB_RDOWNLOCK (1 << MDB_RDOWNLOCK_BIT) +#define MDB_RPTR_MASK 0xfffffffc + + +class rnode_t +{ + public: + unsigned long w1; + + inline void down_lock(void) + { MDB_BIT_LOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline int down_trylock(void) + { return MDB_BIT_TRYLOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline void down_unlock(void) + { MDB_BIT_UNLOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline void clear_locks(void) + { w1 &= ~MDB_RDOWNLOCK; } + + inline mnode_t *get_map(void) + { + return (mnode_t *) (w1 & MDB_RPTR_MASK); + } + + inline void set_ptr(mnode_t *map) + { + w1 = (dword_t) map | MDB_RDOWNLOCK; + } + + inline void set_ptr(rnode_t *root) + { + w1 = (dword_t) root | MDB_RNEXT_ROOT | MDB_RDOWNLOCK; + } + + inline int is_next_root(void) + { + return w1 & MDB_RNEXT_ROOT; + } +}; + + + +#endif /* !__ARM__MAPPING_H__ */ diff --git a/kernel/include/arm/memory.h b/kernel/include/arm/memory.h new file mode 100644 index 0000000..6c357ca --- /dev/null +++ b/kernel/include/arm/memory.h @@ -0,0 +1,635 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, 2002, Karlsruhe University + * + * File path: arm/memory.h + * Description: ARM specific pagetable manipulation code. + * + * @LICENSE@ + * + * $Id: memory.h,v 1.7 2002/06/07 17:04:26 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__MEMORY_H__ +#define __ARM__MEMORY_H__ + +#include INC_ARCH(config.h) +#include INC_ARCH(mapping.h) + + +#define PAGE_BITS 12 +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE - 1)) + + +#define PAGEDIR_BITS 20 +#define PAGEDIR_SIZE (1 << PAGEDIR_BITS) +#define PAGEDIR_MASK (~(PAGEDIR_SIZE - 1)) + + +/* + * Generic page table configuration + */ + +#define HW_NUM_PGSIZES 3 +#define HW_VALID_PGSIZES ((1<<20) + (1<<16) + (1<<12)) +extern dword_t hw_pgshifts[]; + + + +#define USER_DOMAIN 0x1 + + +/* +** +** First level descriptors. +** +*/ + +/* First-Level Formats */ + +#define FLD_INVALID 0 /* Fault Entry */ +#define FLD_PAGE 1 /* Page Entry (has 2nd-level discriptor) */ +#define FLD_SECTION 2 /* Section Entry (1MB mapping) */ +#define FLD_RESERVED 3 /* Reserved Entry */ + +/* First-Level Shifts */ + +#define FLD_SH_DOMAIN 5 /* Domain Shift, 4bits */ +#define FLD_SH_AP 10 /* Access Permissions, 2bits */ +#define FLD_SH_PTBA 10 /* Page Table Base Address, 22bits */ +#define FLD_SH_SBA 20 /* Section Base Address, 12bits */ + +typedef struct { + unsigned type :2; + unsigned :30; +} fld_invalid_t; + +typedef struct { + unsigned type :2; + unsigned :3; + unsigned domain :4; + unsigned :1; + unsigned ptba :22; +} fld_page_t; + +typedef struct { + unsigned type :2; + unsigned buf :1; + unsigned cache :1; + unsigned :1; + unsigned domain :4; + unsigned :1; + unsigned ap :2; + unsigned :8; + unsigned sba :12; +} fld_section_t; + +typedef fld_invalid_t fld_reserved_t; + +typedef union fld_t { + dword_t init; + fld_invalid_t invalid; + fld_page_t page; + fld_section_t section; + fld_reserved_t reserved; +} fld_t; + +#define fld_type(fld) (((fld_t *) fld)->invalid.type) + + +/* +** +** Second level descriptors. +** +*/ + +/* Second-Level Formats */ + +#define SLD_INVALID 0 /* Fault Entry */ +#define SLD_LARGE 1 /* Large Page Entry (64KB mapping) */ +#define SLD_SMALL 2 /* Small Page Entry (4KB mapping) */ +#define SLD_RESERVED 3 /* Reserved Entry */ + +/* Second-Level Shifts */ + +#define SLD_SH_AP0 4 /* 1st Sub-Page Access Permissions, 2bits */ +#define SLD_SH_AP1 6 /* 2nd Sub-Page Access Permissions, 2bits */ +#define SLD_SH_AP2 8 /* 3rd Sub-Page Access Permissions, 2bits */ +#define SLD_SH_AP3 10 /* 4th Sub-Page Access Permissions, 2bits */ +#define SLD_SH_LPBA 16 /* Large Page Base Address, 16bits */ +#define SLD_SH_SPBA 12 /* Small Page Base ADdress, 20bits */ + +typedef struct { + unsigned type :2; + unsigned :30; +} sld_invalid_t; + +typedef struct { + unsigned type :2; + unsigned buf :1; + unsigned cache :1; + unsigned ap0 :2; + unsigned ap1 :2; + unsigned ap2 :2; + unsigned ap3 :2; + unsigned :4; + unsigned lpba :16; +} sld_largepage_t; + +typedef struct { + unsigned type :2; + unsigned buf :1; + unsigned cache :1; + unsigned ap0 :2; + unsigned ap1 :2; + unsigned ap2 :2; + unsigned ap3 :2; + unsigned spba :20; +} sld_smallpage_t; + +typedef sld_invalid_t sld_reserved_t; + +typedef union { + dword_t init; + sld_invalid_t invalid; + sld_largepage_t large; + sld_smallpage_t small; + sld_reserved_t reserved; +} sld_t; + +#define sld_type(sld) (((sld_t *) sld)->invalid.type) + + +/* +** +** MMU defines. +** +*/ + +#define FLD_SHIFT (32 - 12) /* Bitshift for index into 1st level */ +#define SLD_SHIFT (32 - 20) /* Bitshift for Index into 2nd level */ +#define SLD_MASK (0x000000FF) +#define FLD_SIZE (1 << 14) /* Size of 1st level PT in bytes */ +#define SLD_SIZE (1 << 10) /* Size of 2nd level PT in bytes */ +#define FLD_MAX (FLD_SIZE >> 2) /* Number of 1st level entries */ +#define SLD_MAX (SLD_SIZE >> 2) /* Number of 2nd level entries */ +#define LRG_ENTS 16 /* Number of 2nd level entries for + a single large page */ + +/* Caching Attributes */ + +#define CB_CACHABLE (1 << 3) /* Entry is Cachable */ +#define CB_BUFFERABLE (1 << 2) /* Entry is Bufferable */ +#define CB_IDEPENDENT (1 << 4) /* Implimentation Dependent */ + +/* Access Permitions */ + +#define AP_RESTRICTED 0 /* Supervisor: Restricted, User: Restricted */ +#define AP_NOACCESS 1 /* Supervisor: Read/Write, User: No Access */ +#define AP_READACCESS 2 /* Supervisor: Read/Write, User: Read Only */ +#define AP_ALLACCESS 3 /* Supervisor: Read/Write, User: Read/Write */ + +/* Domain Access Types */ + +#define DAT_NOACCESS 0 /* No Access (acceses cause domain fault) */ +#define DAT_CLIENT 1 /* Client Domain (access permitions checked) */ +#define DAT_RESERVED 2 /* Reserved Domain Type */ +#define DAT_MANAGER 3 /* Manager Domain (no access checks) */ + +/* Fault Types */ + +#define TRANSLATION_FAULT_S 0x00000005 +#define TRANSLATION_FAULT_P 0x00000007 +#define DOMAIN_FAULT_S 0x00000009 +#define DOMAIN_FAULT_P 0x0000000B +#define PERMISSION_FAULT_S 0x0000000D +#define PERMISSION_FAULT_P 0x0000000F + +#define STATUS_MASK 0x0000000F + + +/* +** +** Macros +** +*/ + +/* Virtual Address to FLD Index */ +#define vaddr_to_fld(vaddr) ((vaddr) >> FLD_SHIFT) + +/* FLD Index to Virtual Address */ +#define fld_to_vaddr(fld) ((fld) << FLD_SHIFT) + +/* Physical Address to Section Base Address */ +#define paddr_to_sba(paddr) ((paddr) >> FLD_SH_SBA) + +/* Section Base Address to Physical Address */ +#define sba_to_paddr(sba) ((sba) << FLD_SH_SBA) + +/* Page Table Base Address to Physical Address */ +#define ptba_to_paddr(ptba) ((ptba) << FLD_SH_PTBA) + +/* Physical Address to Page Table Base Address */ +#define paddr_to_ptba(paddr) ((paddr) >> FLD_SH_PTBA) + +/* Virtual Address to SLD Index */ +#define vaddr_to_sld(vaddr) (SLD_MASK & ((vaddr) >> SLD_SHIFT)) + +/* SLD Index to Partial Virtual Address */ +#define sld_to_vaddr(sld) ((sld) << SLD_SHIFT) + +/* Physical Address to Large Page Base Address */ +#define paddr_to_lpba(paddr) ((paddr) >> SLD_SH_LPBA) + +/* Large Page Base Address to Physical Address */ +#define lpba_to_paddr(lpba) ((lpba) << SLD_SH_LPBA) + +/* Physical Address to Small Page Base Address */ +#define paddr_to_spba(paddr) ((paddr) >> SLD_SH_SPBA) + +/* Small Page Base Address to Physical Address */ +#define spba_to_paddr(spba) ((spba) << SLD_SH_SPBA) + +#if 0 +/* Physical Address to Virtual Address (bank0 and kernel only) */ +#define paddr_to_vaddr0(paddr) (0xF0000000 | ((paddr) - DRAM0_PBASE)) + +/* Virtual Address to Physical Address (bank0 and kernel only) */ +#define vaddr_to_paddr0(vaddr) ((0x0FFFFFFF & (vaddr)) + DRAM0_PBASE) + + +/* Contigous physical address to real physical address */ +#define cpaddr_to_paddr(addr) \ +({ \ + dword_t off; \ + \ + off = ((dword_t) (addr) - (dword_t) cpaddr); \ + off = ((off >> MEM_BANKSHIFT) << DRAM_BANKSHIFT) + \ + DRAM0_PBASE + (off & ((1 << MEM_BANKSHIFT)-1)); \ + off; \ +}) + +/* Real physical address to contigous physical address */ +#define paddr_to_cpaddr(addr) \ +({ \ + dword_t off; \ + \ + off = ((dword_t) (addr) - DRAM0_PBASE); \ + off = ((off >> DRAM_BANKSHIFT) << MEM_BANKSHIFT) + \ + (dword_t) cpaddr + (off & ((1 << MEM_BANKSHIFT)-1)); \ + off; \ +}) + +#if 0 +#define virt_to_phys(x) cpaddr_to_paddr(x) +#else +#define virt_to_phys(x) ({ typeof(x) _x = (typeof(x)) (cpaddr_to_paddr((dword_t) (x))); _x;}) +#endif + +#if 0 +#define phys_to_virt(x) paddr_to_cpaddr(x) +#else +#define phys_to_virt(x) ({ typeof(x) _x = (typeof(x)) (paddr_to_cpaddr((dword_t) (x))); _x;}) +#endif + +#else + +typedef union { + dword_t r; + struct { + dword_t o:DRAM_BANKSIZE_BITS; /* offset */ + dword_t s:32-DRAM_BANKSIZE_BITS; /* rest */ + } x; +} _addr_t; + + +#define _p2v_(_x_) ({_addr_t y = (_addr_t) {r : ((dword_t) (_x_)) - DRAM_BASE}; y.x.s >>= (DRAM_BANKDIST_BITS-DRAM_BANKSIZE_BITS); y.r + cpaddr;}) +#define _v2p_(_x_) ({_addr_t y = (_addr_t) {r : ((dword_t) (_x_)) - cpaddr}; y.x.s <<= (DRAM_BANKDIST_BITS-DRAM_BANKSIZE_BITS); y.r + DRAM_BASE;}) + +#define phys_to_virt(x) ({ typeof(x) _x = (typeof(x)) (_p2v_((dword_t) (x))); _x;}) +#define virt_to_phys(x) ({ typeof(x) _x = (typeof(x)) (_v2p_((dword_t) (x))); _x;}) +#endif + + +/* + * Macro get_ttb () + * + * Return Translation Table Base. + * + */ +#define get_ttb() \ +({ \ + dword_t x; \ + \ + __asm__ __volatile__ ( \ + " mrc p15, 0, %0, c2, c0, 0 \n" \ + :"=r"(x)); \ + \ + (x & ~((1<<14) - 1)); \ +}) + + +/* + * Macro set_ttb (x) + * + * Set Translation Table Base to `x'. + * + */ +#define set_ttb(x) \ +({ \ + __asm__ __volatile__ ( \ + " mcr p15, 0, %0, c2, c0, 0 \n" \ + : \ + :"r"(x)); \ +}) + +INLINE ptr_t get_current_pagetable() +{ + return (ptr_t) get_ttb(); +} + + +extern dword_t* kernel_ptdir; +extern fld_t kernel_ptdir_p[]; +extern sld_t kernel_pgtable_p[]; +extern ptr_t __zero_page; + +INLINE ptr_t get_kernel_pagetable() +{ + return kernel_ptdir; +} + + +#define PGSIZE_1MB (HW_NUM_PGSIZES-1) +#define PGSIZE_64KB (HW_NUM_PGSIZES-2) +#define PGSIZE_4KB (HW_NUM_PGSIZES-3) +#define PGSIZE_1KB (HW_NUM_PGSIZES-4) + +#define NUM_PAGESIZES 4 + +#define PAGE_SMALL_BITS 12 +#define PAGE_SMALL_SIZE (1 << PAGE_SMALL_BITS) +#define PAGE_SMALL_MASK (~(PAGE_SMALL_SIZE - 1)) + +#define PAGE_LARGE_BITS 16 +#define PAGE_LARGE_SIZE (1 << PAGE_LARGE_BITS) +#define PAGE_LARGE_MASK (~(PAGE_LARGE_SIZE - 1)) + +#define PAGE_SECTION_BITS 20 +#define PAGE_SECTION_SIZE (1 << PAGE_SECTION_BITS) +#define PAGE_SECTION_MASK (~(PAGE_SECTION_SIZE - 1)) + +#define PAGE_TABLE_BITS 10 +#define PAGE_TABLE_MASK (~((1 << PAGE_TABLE_BITS) - 1)) + +#define PAGE_TYPE_MASK 0x03 + +#define PAGE_AP_RESTRICTED 0 /* S: Restricted, U: Restricted */ +#define PAGE_AP_NOACCESS 1 /* S: Read/Write, U: No Access */ +#define PAGE_AP_READONLY 2 /* S: Read/Write, U: Read Only */ +#define PAGE_AP_WRITABLE 3 /* S: Read/Write, U: Read/Write */ + +/* + * This bit marks the 64K page valid even if the type field is 0. It + * indicates that the 64K page has a subtree (i.e. valid 4K pages). + */ +#define PAGE_64K_VALID 0x80000000 + + +INLINE dword_t pgdir_idx(dword_t addr) +{ + return addr >> PAGE_SECTION_BITS; +} + +INLINE dword_t pgtab_idx(dword_t addr) +{ + /* Assumption: 4k pages only */ + return (addr >> PAGE_SMALL_BITS) & ~(PAGE_SMALL_MASK >> 2); +} + + + + + + +class pgent_t +{ + public: + union { + struct { + unsigned type :2; // 0 + unsigned buf :1; // 2 + unsigned cache :1; // 3 + unsigned :1; // 4 + unsigned domain :4; // 5 + unsigned :1; // 9 + unsigned ap :2; // 10 + unsigned :8; // 12 + unsigned sba :12; // 20 + } section; + + struct { + unsigned type :2; // 0 + unsigned :3; // 2 + unsigned domain :4; // 5 + unsigned :1; // 9 + unsigned base :22; // 10 + } table; + + struct { + unsigned type :2; // 0 + unsigned buf :1; // 2 + unsigned cache :1; // 3 + unsigned ap0 :2; // 4 + unsigned ap1 :2; // 6 + unsigned ap2 :2; // 8 + unsigned ap3 :2; // 10 + unsigned :4; // 12 + unsigned lpba :16; // 16 + } large; + + struct { + unsigned type :2; // 0 + unsigned buf :1; // 2 + unsigned cache :1; // 3 + unsigned ap0 :2; // 4 + unsigned ap1 :2; // 6 + unsigned ap2 :2; // 8 + unsigned ap3 :2; // 10 + unsigned spba :20; // 12 + } small; + + dword_t raw; + } x; + +#define __MNOFF ((pgsize == PGSIZE_1MB) ? 16384 : 1024) + +#define GET_MAPNODE() (*(dword_t*) ((dword_t)this + __MNOFF)) +#define SET_MAPNODE(x) (*(dword_t*) ((dword_t)this + __MNOFF)) = (x) + + // Predicates + + inline dword_t is_valid (space_t * s, dword_t pgsize) + { + dword_t type = (x.raw & PAGE_TYPE_MASK); + return type == 1 || type == 2 || + (pgsize == PGSIZE_64KB && type == 0 && + (x.raw & PAGE_64K_VALID)); + } + + inline dword_t is_writable (space_t * s, dword_t pgsize) + { + return x.section.ap == PAGE_AP_WRITABLE; + } + + inline dword_t is_subtree (space_t * s, dword_t pgsize) + { + dword_t type = (x.raw & PAGE_TYPE_MASK); + return (pgsize == PGSIZE_1MB && type == 1) || + (pgsize == PGSIZE_64KB && + (type == 2 || (type == 0 && (x.raw & PAGE_64K_VALID)))); + } + + // Retrieval operations + + inline dword_t address (space_t * s, dword_t pgsize) + { + return pgsize == PGSIZE_1MB ? + (x.raw & PAGE_SECTION_MASK) : + (x.raw & PAGE_SMALL_MASK); + } + + inline pgent_t * subtree (space_t * s, dword_t pgsize) + { + return pgsize == PGSIZE_1MB ? + (pgent_t *) phys_to_virt(x.raw & PAGE_TABLE_MASK) : + this; + } + + inline mnode_t * mapnode (space_t * s, dword_t pgsize, dword_t vaddr) + { return (mnode_t *) (GET_MAPNODE() ^ vaddr); } + + inline dword_t vaddr (space_t * s, dword_t pgsize, mnode_t *map) + { return (GET_MAPNODE() ^ (dword_t) map); } + + // Change operations + + inline void clear (space_t * s, dword_t pgsize) + { + if ( pgsize == PGSIZE_4KB ) + x.raw = PAGE_64K_VALID; + else { + x.raw = 0; + if ( pgsize == PGSIZE_64KB ) + for ( int i = 1; i < 16; i++ ) + this[i].x.raw = 0; + } + SET_MAPNODE(0); + } + + inline void make_subtree (space_t * s, dword_t pgsize) + { + if ( pgsize == PGSIZE_1MB ) { + x.raw = (dword_t) virt_to_phys(kmem_alloc(1024*2)) | 0x01; + } else { + for ( int i = 0; i < 16; i++ ) { + this[i].x.raw = PAGE_64K_VALID; + } + } + } + + inline void remove_subtree (space_t * s, dword_t pgsize) + { + if ( pgsize == PGSIZE_64KB ) { + for ( int i = 0; i < 16; i++ ) + this[i].x.raw = 0; + } else { + kmem_free((ptr_t) phys_to_virt(x.raw & PAGE_TABLE_MASK), + 1024*2); + x.raw = 0; + } + } + + inline void set_entry (space_t * s, dword_t addr, + dword_t writable, dword_t pgsize) + { + if ( pgsize == PGSIZE_1MB ) { + x.raw = (addr & PAGE_SECTION_MASK) | 0x02; + x.section.ap = writable ? PAGE_AP_WRITABLE : PAGE_AP_READONLY; + } else { + x.raw = pgsize == PGSIZE_64KB ? + (addr & PAGE_LARGE_MASK) | 0x1 : + (addr & PAGE_SMALL_MASK) | 0x2; + x.small.ap0 = x.small.ap1 = x.small.ap2 = x.small.ap3 = + writable ? PAGE_AP_WRITABLE : PAGE_AP_READONLY; + if ( pgsize == PGSIZE_64KB ) + for ( int i = 1; i < 16; i++ ) + this[i].x.raw = x.raw; + } + } + + inline void set_access_bits (space_t * s, dword_t pgsize, dword_t ap, int c, int b) + { + if (pgsize == PGSIZE_1MB) { + x.section.ap = ap; + x.section.cache = c; + x.section.buf = b; + } else { + x.small.ap0 = x.small.ap1 = x.small.ap2 = x.small.ap3 = ap; + x.section.cache = c; + x.section.buf = b; + if (pgsize == PGSIZE_64KB) + for (int i = 1; i < 16; i++) + this[i].x.raw = x.raw; + } + } + + inline void set_writable (space_t * s, dword_t pgsize) + { + if ( pgsize == PGSIZE_1MB ) { + x.section.ap = PAGE_AP_WRITABLE; + } else { + x.small.ap0 = x.small.ap1 = x.small.ap2 = x.small.ap3 = + PAGE_AP_WRITABLE; + if ( pgsize == PGSIZE_64KB ) + for ( int i = 1; i < 16; i++ ) + this[i].x.raw = x.raw; + } + } + + inline void set_readonly (space_t * s, dword_t pgsize) + { + if ( pgsize == PGSIZE_1MB ) { + x.section.ap = PAGE_AP_READONLY; + } else { + x.small.ap0 = x.small.ap1 = x.small.ap2 = x.small.ap3 = + PAGE_AP_READONLY; + if ( pgsize == PGSIZE_64KB ) + for ( int i = 1; i < 16; i++ ) + this[i].x.raw = x.raw; + } + } + + inline void set_uncacheable (space_t * s, int pgsize) + { } + + inline void set_unbufferable (space_t * s, int pgsize) + { } + + inline void set_mapnode (space_t * s, dword_t pgsize, + mnode_t *map, dword_t vaddr) + { SET_MAPNODE((dword_t) map ^ vaddr); } + + // Movement + + inline pgent_t * next (space_t * s, dword_t num, dword_t pgsize) + { + return pgsize == PGSIZE_64KB ? + this + (16 * num) : this + num; + } + +}; + + +#endif /* !__ARM__MEMORY_H__ */ diff --git a/kernel/include/arm/notify.h b/kernel/include/arm/notify.h new file mode 100644 index 0000000..dd1672b --- /dev/null +++ b/kernel/include/arm/notify.h @@ -0,0 +1,48 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/notify.h + * Description: Wrappers for invoking notification functions within + * the context of other threads. + * + * @LICENSE@ + * + * $Id: notify.h,v 1.3 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__NOTIFY_H__ +#define __ARM__NOTFIY_H__ + +#define notify_thread(tcb, func) \ +{ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_1(tcb, func, param0) \ +{ \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_2(tcb, func, param0, param1) \ +{ \ + tcb_stack_push(tcb, param1); \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define comma_nightmare(params...) params + +#define notify_procedure(func, params...) \ +void notify_##func( comma_nightmare(params##,) dword_t __final) + +/* restore stackpointer */ +#define notify_return \ + asm("movl %0, %%esp\n" \ + "ret\n" \ + : \ + : "r"(&__final)); + + +#endif /* __ARM__NOTIFY_H__ */ diff --git a/kernel/include/arm/pleb/cpu.h b/kernel/include/arm/pleb/cpu.h new file mode 100644 index 0000000..c966a53 --- /dev/null +++ b/kernel/include/arm/pleb/cpu.h @@ -0,0 +1,42 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/cpu.h + * Description: SA-1100 specific functions + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.1 2002/01/24 20:32:30 ud3 Exp $ + * + ********************************************************************/ +#ifndef __ARM__PLEB__CPU_H__ +#define __ARM__PLEB__CPU_H__ + +#define DCACHE_SIZE 8192 + +#define Flush_ID_Cache() \ + do { \ + volatile dword_t *x; \ + \ + for ( x = (dword_t *) (0x00000000 - DCACHE_SIZE); \ + x != (dword_t *) 0x00000000; \ + x += 8) \ + { \ + __asm__ __volatile__ ("/* clean DCACHE */" : : "r"(*x)); \ + } \ + \ + __asm__ __volatile__ ( \ + " mcr p15, 0, r0, c7, c7, 0 @ Flush I+D \n" \ + " mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf \n" \ + : \ + : \ + : "r0"); \ + \ + } while (0) + + +#define CLOCK_FREQUENCY 3686400 + + +#endif /* !__ARM__PLEB__CPU_H__ */ diff --git a/kernel/include/arm/pleb/platform.h b/kernel/include/arm/pleb/platform.h new file mode 100644 index 0000000..04bb016 --- /dev/null +++ b/kernel/include/arm/pleb/platform.h @@ -0,0 +1,106 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/platform.h + * Description: SA-1100 and PLEB platform specifications + * + * @LICENSE@ + * + * $Id: platform.h,v 1.1 2002/01/24 20:32:30 ud3 Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__PLEB__PLATFORM_H +#define L4__ARM__PLEB__PLATFORM_H + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (10 * 1024) +/* 2 ms per tick */ +#define TIME_QUANTUM (2 * 1024) + + + + + +#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */ +#define angel_SWI_ARM (0xEF123456 & 0xffffff) + +/* Virtual Addresses */ + +#define INTCTRL_VBASE 0xFFF00000 +#define OSTIMER_VBASE 0xFFF10000 +#define UART_VBASE 0xFFF20000 +#define GPIO_VBASE 0xFFF30000 +#define RSTCTL_VBASE 0xFFF40000 + +/* Physical Addresses */ + +#define INTCTRL_PBASE 0x90050000 +#define OSTIMER_PBASE 0x90000000 +#define UART_PBASE 0x80050000 +#define GPIO_PBASE 0x90040000 +#define RSTCTL_PBASE 0x90030000 + +/* base address */ +#define DRAM_BASE 0xC0000000U +/* log2 of the populated size per bank */ +#define DRAM_BANKSIZE_BITS 22 /* 4M */ +/* log2 of the bank distance */ +#define DRAM_BANKDIST_BITS 27 /* 128M */ + +#define DRAM_BANKSIZE (1 << DRAM_BANKSIZE_BITS) +#define DRAM_BANKDIST (1 << DRAM_BANKDIST_BITS) + +/* overall DRAM memory size */ +#define DRAM_SIZE (4*DRAM_BANKSIZE) /* 16M */ + + + +/* + * Interrupt masks + */ +#define INTR_RTC (1<<31) +#define INTR_1HZ_CLOCK (1<<30) +#define INTR_OSTIMER3 (1<<29) +#define INTR_OSTIMER2 (1<<28) +#define INTR_OSTIMER1 (1<<27) +#define INTR_OSTIMER0 (1<<26) + +/* + * Interrupt controller registers. + */ +#define ICIP *((volatile dword_t *) (INTCTRL_VBASE + 0x00)) /* Pending IRQ */ +#define ICMR *((volatile dword_t *) (INTCTRL_VBASE + 0x04)) /* Mask register */ +#define ICLR *((volatile dword_t *) (INTCTRL_VBASE + 0x08)) /* Level reg. */ +#define ICFP *((volatile dword_t *) (INTCTRL_VBASE + 0x10)) /* Pending FIQs */ +#define ICPR *((volatile dword_t *) (INTCTRL_VBASE + 0x20)) /* Pending intr. */ +#define ICCR *((volatile dword_t *) (INTCTRL_VBASE + 0x0c)) /* Control reg. */ + +/* + * OS Timer registers. + */ +#define OSMR0 *((volatile dword_t *) (OSTIMER_VBASE + 0x00)) /* Match reg 0 */ +#define OSMR1 *((volatile dword_t *) (OSTIMER_VBASE + 0x04)) /* Match reg 1 */ +#define OSMR2 *((volatile dword_t *) (OSTIMER_VBASE + 0x08)) /* Match reg 2 */ +#define OSMR3 *((volatile dword_t *) (OSTIMER_VBASE + 0x0c)) /* Match reg 3 */ +#define OSCR *((volatile dword_t *) (OSTIMER_VBASE + 0x10)) /* Count reg. */ +#define OSSR *((volatile dword_t *) (OSTIMER_VBASE + 0x14)) /* Status reg. */ +#define OWER *((volatile dword_t *) (OSTIMER_VBASE + 0x18)) /* Watchdg enbl */ +#define OIER *((volatile dword_t *) (OSTIMER_VBASE + 0x1c)) /* Intr. enable */ + + +/* + * Number of bytes in a cache line. + */ +#define CACHE_LINE_SIZE 32 + + +/* + * For aligning structures on cache line boundaries. + */ +#define CACHE_ALIGN __attribute__ ((aligned (CACHE_LINE_SIZE))) + + +#endif /* !L4__ARM__PLEB__PLATFORM_H */ diff --git a/kernel/include/arm/pleb/uart.h b/kernel/include/arm/pleb/uart.h new file mode 100644 index 0000000..a0498a4 --- /dev/null +++ b/kernel/include/arm/pleb/uart.h @@ -0,0 +1,98 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/uart.h + * Description: Definitions for the SA-1100 UART + * + * @LICENSE@ + * + * $Id: uart.h,v 1.1 2002/01/24 20:32:30 ud3 Exp $ + * + ********************************************************************/ +#ifndef L4__ARM__PLEB__UART_H +#define L4__ARM__PLEB__UART_H + +/* + * Base address of UART + */ +#define L4_UART_PBASE 0x80050000 +#define L4_UART_BASE UART_VBASE /* In platform.h */ + +/* Control registers */ +#define L4_UART_UTCR0 *((volatile dword_t *) (L4_UART_BASE + 0x00)) +#define L4_UART_UTCR1 *((volatile dword_t *) (L4_UART_BASE + 0x04)) +#define L4_UART_UTCR2 *((volatile dword_t *) (L4_UART_BASE + 0x08)) +#define L4_UART_UTCR3 *((volatile dword_t *) (L4_UART_BASE + 0x0c)) + +/* Data register */ +#define L4_UART_UTDR *((volatile dword_t *) (L4_UART_BASE + 0x14)) + +/* Status registers */ +#define L4_UART_UTSR0 *((volatile dword_t *) (L4_UART_BASE + 0x1c)) +#define L4_UART_UTSR1 *((volatile dword_t *) (L4_UART_BASE + 0x20)) + + + +/* + * Bits defined in control register 0. + */ +#define L4_UART_PE (1 << 0) /* Parity enable */ +#define L4_UART_OES (1 << 1) /* Odd/even parity select */ +#define L4_UART_SBS (1 << 2) /* Stop bit select */ +#define L4_UART_DSS (1 << 3) /* Data size select */ +#define L4_UART_SCE (1 << 4) /* Sample clock rate enable */ +#define L4_UART_RCE (1 << 5) /* Receive clk. rate edge select */ +#define L4_UART_TCE (1 << 6) /* Transmit clk. rate edge select */ + + +/* + * Bits defined in control register 3. + */ +#define L4_UART_RXE (1 << 0) /* Receiver enable */ +#define L4_UART_TXE (1 << 1) /* Transmitter enable */ +#define L4_UART_BRK (1 << 2) /* Break */ +#define L4_UART_RIO (1 << 3) /* Receive FIFO interrupt enable */ +#define L4_UART_TIE (1 << 4) /* Transmit FIFO interrupt enable */ +#define L4_UART_LBM (1 << 5) /* Loopback mode */ + + +/* + * Baud rate devisror (contained in control registers 1 and 2). + */ +#define L4_UART_GET_BRD() \ + ( (((l4_uint32_t) L4_UART_UTCR1 & 0x0f) << 8) + \ + (l4_uint8_t) L4_UART_UTCR2 ) + +#define L4_UART_SET_BRD(brd) \ + ( *(l4_uint32_t *) L4_UART_UTCR1 = brd & 0xff, \ + *(l4_uint32_t *) L4_UART_UTCR2 = (brd >> 8) & 0x0f ) \ + +#define L4_BRD_TO_BAUDRATE(brd) (3686400 / ((brd+1) << 4)) +#define L4_BAUDRATE_TO_BRD(rate) (3686400 / (rate << 4) - 1) + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TFS (1 << 0) /* Transmit FIFO service req. */ +#define L4_UART_RFS (1 << 1) /* Receive FIFO service req. */ +#define L4_UART_RID (1 << 2) /* Receiver idle */ +#define L4_UART_RBB (1 << 3) /* Receiver begin of break */ +#define L4_UART_REB (1 << 4) /* Receiver end of break */ +#define L4_UART_EIF (1 << 5) /* Error in FIFO */ + + +/* + * Bits defined in status register 0. + */ +#define L4_UART_TBY (1 << 0) /* Transmitter busy flag */ +#define L4_UART_RNE (1 << 1) /* Receiver FIFO not empty */ +#define L4_UART_TNF (1 << 2) /* Transmitter FIFO not full */ +#define L4_UART_PRE (1 << 3) /* Parity error */ +#define L4_UART_FRE (1 << 4) /* Framing error */ +#define L4_UART_ROR (1 << 5) /* Receive FIFO overrun */ + + + +#endif /* !L4__ARM__PLEB__UART_H */ diff --git a/kernel/include/arm/space.h b/kernel/include/arm/space.h new file mode 100644 index 0000000..7f33165 --- /dev/null +++ b/kernel/include/arm/space.h @@ -0,0 +1,46 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm/space.h + * Description: Address space definition for the ARM + * + * @LICENSE@ + * + * $Id: space.h,v 1.1 2001/12/07 19:05:12 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__SPACE_H__ +#define __ARM__SPACE_H__ + +class space_t +{ + // Normal page directory. + dword_t pgdir[1024]; + +public: + inline dword_t * pagedir_phys (void) + { return (dword_t *) this; } + + inline dword_t * pagedir (void) + { return (dword_t *) phys_to_virt (this); } + + inline pgent_t * pgent (int n) + { return (pgent_t *) phys_to_virt (&pgdir[n]); } +}; + + +INLINE space_t * get_current_space (void) +{ + return (space_t *) get_ttb (); +} + +INLINE space_t * get_kernel_space (void) +{ + extern ptr_t kernel_ptdir; + return (space_t *) virt_to_phys (kernel_ptdir); +} + + +#endif /* !__ARM_SPACE_H__ */ + diff --git a/kernel/include/arm/syscalls.h b/kernel/include/arm/syscalls.h new file mode 100644 index 0000000..e4e9fa6 --- /dev/null +++ b/kernel/include/arm/syscalls.h @@ -0,0 +1,136 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/syscalls.h + * Description: System call return wrappers for ARM. + * + * @LICENSE@ + * + * $Id: syscalls.h,v 1.17 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM_SYSCALLS_H__ +#define __ARM_SYSCALLS_H__ + + +#ifndef ASSEMBLY + +#define return_lthread_ex_regs(_uip, _usp, _pager, _tid, _flags) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_lthread_ex_regs */ \n" \ + " mov r0, %0 \n" \ + " mov r1, %1 \n" \ + " mov r2, %2 \n" \ + " mov r3, %3 \n" \ + " mov r4, %4 \n" \ + : \ + : "r" (_tid), "r"(_uip), "r"(_usp), "r"(_pager), "r"(_flags) \ + : "r0", "r1", "r2", "r3", "r4"); \ + return; \ +} + +#define return_create_thread() \ + return + +#define return_thread_switch() \ + return + +/* this is used in version X0 only */ +#define return_task_new(_newtask) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_task_new(_newtask) */ \n" \ + " mov r0, %0 \n" \ + : \ + : "r"(_newtask) \ + : "r0" \ + ); \ + return; \ +} + + + + +/* does not load argument into registers */ +#define return_ipc(_error) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_ipc(_error) */ \n" \ + " mov r0, %0 @ error "#_error"\n" \ + : \ + : "r"(_error) \ + : "r0" \ + ); \ + return; \ +} + +/* loads the arguments into registers */ +#define return_ipc_args(_from, _error, _myself) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_ipc_args(_from, _error) */ \n" \ + " mov r1, %0 @ from in r1 \n" \ + " mov r0, %1 @ error "#_error"\n" \ + : \ + : "r"(_from), "r"(current->msg_desc | _error) \ + : "r0", "r1" \ + ); \ + return; \ +} + +#define return_id_nearest(_nearestid, _type) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_id_nearest(_nearestid, _type) */ \n" \ + " mov r0, %0 \n" \ + " mov r1, %1 \n" \ + : \ + : "r" (_nearestid), "r" (_type) \ + : "r0", "r1" \ + ); \ + return; \ +} + +#define return_thread_schedule(_oldparam) \ +{ \ + __asm__ __volatile__ ( \ + "/* return_schedule(_oldparam) */ \n" \ + " mov r0, %0 \n" \ + : \ + : "r" (_oldparam) \ + : "r0" \ + ); \ + return; \ +} + +INLINE void do_pagefault_ipc(tcb_t * current, dword_t fault, dword_t ip) +{ + current->ipc_buffer[0] = fault; + current->ipc_buffer[1] = ip; + current->ipc_buffer[2] = 0; + l4_threadid_t pager = current->pager; + __asm__ ("/* do_pagefault_ipc(start) */ \n" + " mov r2, %0 \n" /* rcv fpage */ + " mov r1, #0 \n" /* register only send */ + " ldr r0, %1 \n" /* dest */ + " bl sys_ipc__FG13l4_threadid_tUiUi\n" + "\t/* do_pagefault_ipc(end) */ \n" + : + : "i"(IPC_PAGEFAULT_DOPE), "m"(pager) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "memory" + ); +} + +#endif /* ASSEMBLY */ + + + + +/* 0x20 -> enter kernel debugger */ +#define SYSCALL_LIMIT 0x20 + 4 + 3 + + +#endif /* __ARM_SYSCALLS_H__ */ + diff --git a/kernel/include/arm/tcb.h b/kernel/include/arm/tcb.h new file mode 100644 index 0000000..a58d594 --- /dev/null +++ b/kernel/include/arm/tcb.h @@ -0,0 +1,19 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm/tcb.h + * Description: ARM specific part of TCB structure. + * + * @LICENSE@ + * + * $Id: tcb.h,v 1.4 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __ARM__TCB_H__ +#define __ARM__TCB_H__ + +typedef struct { +} tcb_priv_t; + +#endif /* __ARM__TCB_H__ */ diff --git a/kernel/include/arm/thread.h b/kernel/include/arm/thread.h new file mode 100644 index 0000000..4c80309 --- /dev/null +++ b/kernel/include/arm/thread.h @@ -0,0 +1,201 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/thread.h + * Description: ARM thread switching code, and inline functions for + * manupilating a user stack frame. + * + * @LICENSE@ + * + * $Id: thread.h,v 1.25 2002/05/28 20:11:27 ud3 Exp $ + * + ********************************************************************/ +#ifndef __ARM__THREAD_H__ +#define __ARM__THREAD_H__ + +#include INC_ARCH(config.h) +#include INC_ARCH(space.h) +#include INC_ARCH(cpu.h) +#include + + + +INLINE tcb_t* get_current_tcb(void) +{ + tcb_t* tcb; + /* + * ASSUMPTION: sp is alway word aligned. Therefore, we don't need + * to zero out the lowest two bits. This works only for tcb sizes + * of up to 1K! + */ +#if (L4_NUMBITS_TCBS > 10) +# error TCB is too large for get_current_tcb()! +#endif + + __asm__ __volatile__( + "\n\t/* get_current_tcb(start) */ \n" + " and %0, sp, %1 \n\t" + "/* get_current_tcb(end) */ \n" + :"=r" (tcb) + :"i" (L4_TCB_MASK | 0x3)); + + return tcb; +} + + +INLINE ptr_t get_tcb_stack_top(tcb_t *tcb) +{ + return ptr_t (((dword_t)tcb) + L4_TOTAL_TCB_SIZE - 16); +} + +#define UIP(tcb) (get_tcb_stack_top(tcb)[-1]) +#define USP(tcb) (get_tcb_stack_top(tcb)[-4]) +#define UFL(tcb) (get_tcb_stack_top(tcb)[-5]) + +INLINE dword_t get_user_ip(tcb_t* tcb) { return UIP(tcb); } +INLINE dword_t get_user_sp(tcb_t* tcb) { return USP(tcb); } +INLINE dword_t get_user_flags(tcb_t* tcb) { return UFL(tcb); } +INLINE dword_t set_user_ip(tcb_t* tcb, dword_t val) { dword_t old = UIP(tcb); UIP(tcb) = val; return old; } +INLINE dword_t set_user_sp(tcb_t* tcb, dword_t val) { dword_t old = USP(tcb); USP(tcb) = val; return old; } +INLINE dword_t set_user_flags(tcb_t* tcb, dword_t val) { dword_t old = UFL(tcb); UFL(tcb) = val; return old; } + +INLINE void tcb_stack_push(tcb_t *tcb, dword_t value) +{ + *(--(tcb->stack)) = value; +} + +INLINE void create_user_stack_frame(tcb_t *tcb, dword_t usp, dword_t uip, void (*entry)(), void* param) +{ + tcb->stack = get_tcb_stack_top(tcb); + tcb_stack_push(tcb, uip); // user instruction pointer + tcb_stack_push(tcb, 0); // kernel lr - dummy + tcb_stack_push(tcb, 0); // user lr - dummy + tcb_stack_push(tcb, usp); // user stack +#if defined(CONFIG_USERMODE_NOIRQ) + tcb_stack_push(tcb, (IRQ_MASK|FIQ_MASK|USER_MODE)); // flags +#else + tcb_stack_push(tcb, (/*IRQ_MASK|FIQ_MASK|*/USER_MODE)); // flags +#endif + tcb_stack_push(tcb, (dword_t) param); // parameter + tcb_stack_push(tcb, (dword_t) entry); // entry point in kernel +} + +INLINE tcb_t* tid_to_tcb(l4_threadid_t tid) +{ + return (tcb_t*)((tid.id.thread << L4_NUMBITS_TCBS) + TCB_AREA); +} + +INLINE tcb_t *ptr_to_tcb(ptr_t ptr) +{ + return (tcb_t *) ((dword_t) ptr & L4_TCB_MASK); +} + +INLINE void allocate_tcb(tcb_t* tcb) +{ + __asm__ __volatile__ ( + "/* allocate_tcb */ \n" + " str r0, %0 \n" + "\t/* allocate_tcb end */ \n" + : + :"m"(tcb->scratch)); +} + +INLINE void switch_to_initial_thread(tcb_t* tcb) +{ + asm(" mov %%sp, %0\n" + " ldmia %%sp!, {%%pc}\n" + : + : "r"(tcb->stack)); + +} + +INLINE void switch_to_thread(tcb_t* tcb, tcb_t* current) +{ + if (!same_address_space(tcb, current)) + { + register dword_t foo = (dword_t) current; /* value unused */ + __asm__ __volatile__ + ("\n\t/* switch_to_thread_and_as(start) */ \n" + " stmdb sp!, {%3, %2, %1, lr} \n" + " adr lr, 1f @ save return address \n" + " str lr, [sp, #-4]! @ ...on the old stack \n" + " mcr p15, 0, %3, c2, c0 @ install new page table\n" + " @ clean cache loop \n" + " ldr %3, 0f \n" + "2: ldr %0, [%3, #0] \n" + " adds %3, %3, #16 \n" + " bne 2b \n" + " mcr p15, 0, %3, c7, c7, 0 @ flush I/D Cache \n" + " mcr p15, 0, %3, c7, c10, 4 @ drain write buffer \n" + " mcr p15, 0, %3, c8, c7, 0 @ flush I/D TLB \n" + " @ since the kernel is mapped in ALL address spaces \n" + " @ we should never get a code pagefault here \n" + " mov %3, sp @ save old sp \n" + " mov sp, %2 @ switch to new sp \n" + " @ hereby we might experience a data abort on the old TLB\n" + " @ which is served via the stack in the destination TCB \n" + " str %3, [%1] @ save old sp in old tcb\n" + " ldr pc, [sp], #4 \n" + "0: .word 0xFFFFC000 \n" + "1: ldmia sp!, {%3, %2, %1, lr} \n\t" + "/* switch_to_thread_and_as(end) */ \n" + : "+r" (foo) + : "r"(¤t->stack), "r"(tcb->stack), + "r" (tcb->space->pagedir_phys ()) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "memory" ); + } + else + { + __asm__ __volatile__ + ("\n\t/* switch_to_thread(start) */ \n" + " stmdb sp!, {lr} \n" + " adr lr, 1f \n" + " str lr, [sp, #-4]! \n" + " str sp, [%0] \n" + " mov sp, %1 \n" + " ldr pc, [sp], #4 \n" + "1: ldmia sp!, {lr} \n\t" + "/* switch_to_thread(end) */ \n" + : + : "r"(¤t->stack), "r"(tcb->stack) + : //"r0", "r1", + "r2", "r3", + "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "memory" + ); + } +} + +INLINE void switch_to_idle(tcb_t * current) +{ + __asm__ __volatile__ + ("\n\t/* switch_to_idle(start) */ \n" + " stmdb sp!, {lr} \n" + " adr lr, 1f \n" + " str lr, [sp, #-4]! \n" + " str sp, [%0] \n" + " mov sp, %1 \n" + " ldr pc, [sp], #4 \n" + "1: ldmia sp!, {lr} \n\t" + "/* switch_to_idle(end) */ \n" + : + : "r"(¤t->stack), "r"(get_idle_tcb()->stack) + : //"r0", "r1", + "r2", "r3", + "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "memory" + ); +} + +INLINE dword_t tcb_exist(tcb_t * tcb) +{ +#if 1 + __asm__ __volatile__ ("/* tcb_exist */"); +#endif + return (tcb->myself.raw); +} + +#endif /* __ARM__THREAD_H__ */ diff --git a/kernel/include/config.h b/kernel/include/config.h new file mode 100644 index 0000000..4d7c874 --- /dev/null +++ b/kernel/include/config.h @@ -0,0 +1,39 @@ +/* + * Automatically generated C config: don't edit + */ +#define AUTOCONF_INCLUDED +/* + * Architecture + */ +#define CONFIG_ARCH_X86 1 +#define CONFIG_ARCH_X86_I686 1 +#define CONFIG_IA32_FEATURE_PSE 1 +#define CONFIG_IA32_FEATURE_PGE 1 +#define CONFIG_IA32_FEATURE_SEP 1 +#define CONFIG_IA32_FEATURE_FXSR 1 +#define CONFIG_IA32_FEATURE_MSR 1 +#define CONFIG_IA32_FEATURE_CMOV 1 +/* + * Kernel Configuration + */ +#define CONFIG_X86_INKERNEL_PIC 1 +#define CONFIG_IO_FLEXPAGES 1 +/* + * Debug Configuration + */ +#define CONFIG_DEBUGGER_KDB 1 +#define CONFIG_DEBUGGER_IO_INCOM 1 +#define CONFIG_DEBUGGER_IO_OUTCOM 1 +#define CONFIG_DEBUGGER_COMPORT 0x3F8 +#define CONFIG_DEBUGGER_COMSPEED 115200 +#define CONFIG_DEBUGGER_IO_SCREEN_VGA 1 +#define CONFIG_DEBUG 1 +#define CONFIG_DEBUG_BREAKIN 1 +#define CONFIG_DEBUG_KDB_ONSTART 1 +/* + * Trace Settings + */ +#define CONFIG_DEBUG_TRACE_KPF 1 +#define CONFIG_DEBUG_TRACE_UPF 1 +#define CONFIG_DEBUG_TRACE_IPC 1 +#define CONFIG_DEBUG_TRACE_MDB 1 diff --git a/kernel/include/init.h b/kernel/include/init.h new file mode 100644 index 0000000..ab25928 --- /dev/null +++ b/kernel/include/init.h @@ -0,0 +1,57 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: init.h + * Description: Declarations of initialization functions. + * + * @LICENSE@ + * + * $Id: init.h,v 1.17 2002/05/13 13:04:29 stoess Exp $ + * + ********************************************************************/ +#ifndef __INIT_H__ +#define __INIT_H__ + + +/* From kmemory.c */ +void kmem_init(void) L4_SECT_INIT; + +/* From mapping.c */ +void mdb_init(void) L4_SECT_INIT; +void mdb_buflist_init(void) L4_SECT_INIT; + +/* From interrupts.c */ +void interrupts_init() L4_SECT_INIT; + +/* architecture specific initialization */ +void init_arch_1() L4_SECT_INIT; +void init_arch_2() L4_SECT_INIT; +void init_arch_3() L4_SECT_INIT; + + + +void setup_excp_vector() L4_SECT_INIT; + +tcb_t * create_idle_thread() L4_SECT_INIT; + + +/* starts sigma 0 */ +void create_sigma0(); + +/* starts root task */ +void create_root_task(); + +void create_nil_tcb(void); + +/* creates the thread that communicates with sigma0 */ +void create_kmemthread(); + + + + +/* the banner that gets printed through KDB on startup */ +extern const char * kernel_version; + + +#endif /* __INIT_H__ */ diff --git a/kernel/include/interrupt.h b/kernel/include/interrupt.h new file mode 100644 index 0000000..895462a --- /dev/null +++ b/kernel/include/interrupt.h @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: interrupt.h + * Description: Interrupt handling declarations. + * + * @LICENSE@ + * + * $Id: interrupt.h,v 1.6 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +/* interrupt owner */ +#define MAX_INTERRUPTS 32 + +/* defined in interrupt.c */ +extern tcb_t * interrupt_owner[MAX_INTERRUPTS]; + +/* handlers called from architecture specific part */ +void handle_timer_interrupt(); +void handle_interrupt(dword_t number); + +/* architecture specific interrupt masking */ +void mask_interrupt(unsigned int number); +void unmask_interrupt(unsigned int number); + +#endif /* __INTERRUPT_H__ */ diff --git a/kernel/include/ipc.h b/kernel/include/ipc.h new file mode 100644 index 0000000..6711c1e --- /dev/null +++ b/kernel/include/ipc.h @@ -0,0 +1,173 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: ipc.h + * Description: IPC message and IPC handling declarations. + * + * @LICENSE@ + * + * $Id: ipc.h,v 1.20 2002/06/07 17:01:45 skoglund Exp $ + * + ********************************************************************/ +#ifndef __IPC_H__ +#define __IPC_H__ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned uncacheable:1; + unsigned unbufferable:1; + unsigned zero:2; + unsigned page:20; +} fpage_struct_t; + +typedef union { + dword_t raw; + fpage_struct_t fpage; +} fpage_t; + +#define FPAGE_WHOLE_SPACE ((fpage_t) { fpage: { 0, 0, 32, 0, 0 } }) +#define FPAGE_OWN_SPACE (1<<31) +#define FPAGE_FLUSH (1<<1) + + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} msgdope_struct_t; + +typedef union { + dword_t raw; + msgdope_struct_t msgdope; +} msgdope_t; + + +typedef struct { + fpage_t rcv_fpage; + msgdope_t size_dope; + msgdope_t send_dope; + dword_t dwords[0]; +} memmsg_t; + +typedef struct { + dword_t send_size:31; + dword_t send_continue:1; + ptr_t send_address; + + dword_t rcv_size:31; + dword_t rcv_continue:1; + ptr_t rcv_address; +} stringdope_t; + + + +#define IPC_DESC_REGONLY 0x00 +#define IPC_DESC_REGMAP 0x02 + +#define IPC_PAGEFAULT_FPAGE (0x80) +#define IPC_PAGEFAULT_DOPE (IPC_PAGEFAULT_FPAGE | IPC_DESC_REGMAP) + +/* error codes */ +#define IPC_ERR_SEND 0x10 +#define IPC_ERR_RECV 0x00 +#define IPC_ERR_EXIST 0x10 +#define IPC_ERR__TIMEOUT 0x20 +#define IPC_ERR_CANCELED 0x40 +#define IPC_ERR_ABORTED 0xC0 +#define IPC_ERR_CUTMSG 0xe0 +#define IPC_ERR_SENDTIMEOUT (IPC_ERR__TIMEOUT + IPC_ERR_SEND) +#define IPC_ERR_RECVTIMEOUT (IPC_ERR__TIMEOUT + IPC_ERR_RECV) + +#define IS_IPC_ERROR(x) ((x) & 0xf0) + +/* what happened...*/ +#define IPC_MAP_MESSAGE 0x02 + +/* Number of dwords before not included in message buffer. */ +#define IPC_DWORD_GAP 3 + +/* slave bit for indirect strings */ +#define IPC_DOPE_CONTINUE 0x80000000 + + +/* + * IPC timeouts + */ +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} timeout_struct_t; + + +typedef union { + dword_t raw; + timeout_struct_t timeout; +} timeout_t; + +/* + * timeout macros + */ +#define TIMEOUT_NEVER ((timeout_t) { 0 }) +#define IS_INFINITE_SEND_TIMEOUT(x) (x.timeout.snd_exp == 0) +#define IS_INFINITE_RECV_TIMEOUT(x) (x.timeout.rcv_exp == 0) +#define TIMEOUT(exp,man) ((1 << (2 * (15 - exp))) * man) +#define IS_INFINITE_RECV_PFAULT(x) (~x.timeout.rcv_pfault) +#define IS_INFINITE_SEND_PFAULT(x) (~x.timeout.snd_pfault) + +INLINE timeout_t GET_RECV_PF_TIMEOUT(timeout_t to) +{ + timeout_t pf_to; + if (!IS_INFINITE_RECV_PFAULT(to)) + { + pf_to.timeout.snd_man = 1; + pf_to.timeout.rcv_man = 1; + pf_to.timeout.snd_exp = pf_to.timeout.rcv_exp = to.timeout.rcv_pfault; + } + else + pf_to.timeout.snd_exp = pf_to.timeout.rcv_exp = 0; + + return pf_to; +} + +INLINE timeout_t GET_SEND_PF_TIMEOUT(timeout_t to) +{ + timeout_t pf_to; + if (!IS_INFINITE_SEND_PFAULT(to)) + { + pf_to.timeout.snd_man = 1; + pf_to.timeout.rcv_man = 1; + pf_to.timeout.snd_exp = pf_to.timeout.rcv_exp = to.timeout.rcv_pfault; + } + else + pf_to.timeout.snd_exp = pf_to.timeout.rcv_exp = 0; + + return pf_to; +} + +class space_t; +int map_fpage(tcb_t *from, tcb_t *to, dword_t base, fpage_t snd_fp, fpage_t rcv_fp); +void fpage_unmap(space_t *space, fpage_t fpage, dword_t mapmask); + + +ptr_t get_copy_area(tcb_t * from, tcb_t * to, ptr_t addr); +void free_copy_area(tcb_t * tcb); + +/* ipc.c */ +notify_procedure(copy_pagefault, dword_t fault, tcb_t * partner); + +int ipc_handle_kernel_id(tcb_t* current, l4_threadid_t dest); +void extended_transfer(tcb_t * from, tcb_t * to, dword_t snd_desc); + +#endif /* __IPC_H__ */ diff --git a/kernel/include/kdebug.h b/kernel/include/kdebug.h new file mode 100644 index 0000000..3a07d92 --- /dev/null +++ b/kernel/include/kdebug.h @@ -0,0 +1,50 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: kdebug.h + * Description: Declarations of functions located within kernel + * debugger. + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.20 2001/12/04 20:37:30 uhlig Exp $ + * + ********************************************************************/ +#ifndef __KDEBUG_H__ +#define __KDEBUG_H__ + +/* usually implemented in arch/kdebug.c */ +void putc(char c) L4_SECT_KDEBUG; +char getc() L4_SECT_KDEBUG; + +/* kdebug.c */ +int printf(const char* format, ...) L4_SECT_KDEBUG; +void panic(const char *msg) L4_SECT_KDEBUG; +int kdebug_entry(exception_frame_t* frame) L4_SECT_KDEBUG; + +void kdebug_init() L4_SECT_KDEBUG; + + +extern int __kdebug_mdb_tracing; +extern int __kdebug_pf_tracing; + +/* arch/kdebug.c */ +void kdebug_dump_frame(exception_frame_t *frame) L4_SECT_KDEBUG; +void kdebug_dump_pgtable(ptr_t pgtable) L4_SECT_KDEBUG; +void kdebug_dump_map(dword_t pgtable) L4_SECT_KDEBUG; +void kdebug_mdb_stats(dword_t start, dword_t end) L4_SECT_KDEBUG; +void kdebug_dump_tcb(tcb_t* tcb) L4_SECT_KDEBUG; +void kdebug_pf_tracing(int state) L4_SECT_KDEBUG; +void kdebug_hwreset() L4_SECT_KDEBUG; +void kdebug_check_breakin() L4_SECT_KDEBUG; +void kdebug_dump_tracebuffer() L4_SECT_KDEBUG; +void kdebug_flush_tracebuffer() L4_SECT_KDEBUG; + + +#define TRACE() printf("%s: %d\n", __FUNCTION__, __LINE__) + + +#include INC_ARCH(kdebug.h) + +#endif /* __KDEBUG_H__ */ diff --git a/kernel/include/kernel.h b/kernel/include/kernel.h new file mode 100644 index 0000000..dc48c14 --- /dev/null +++ b/kernel/include/kernel.h @@ -0,0 +1,89 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: kernel.h + * Description: kernel info page definition + * + * @LICENSE@ + * + * $Id: kernel.h,v 1.7 2001/12/12 22:54:26 ud3 Exp $ + * + ********************************************************************/ + +#ifndef __KERNEL_H__ +#define __KERNEL_H__ + + +typedef struct kernel_info_page_t { + char magic[4]; /* "L4uK" */ + dword_t version; + char reserved_0x0C[8]; /* "L2" ... */ + + /* these are physical addresses !!! */ + void (*kdebug_init)(); + void (*kdebug_exception)(); + dword_t kdebug_low, kdebug_high; + dword_t sigma0_sp, sigma0_ip, sigma0_low, sigma0_high; + dword_t sigma1_sp, sigma1_ip, sigma1_low, sigma1_high; + dword_t root_sp, root_ip, root_low, root_high; + + dword_t l4_config; + dword_t reserved_0x54; + dword_t kdebug_config, kdebug_perms; + + /* memory areas */ + dword_t main_mem_low, main_mem_high; + /* these regions must not be used. They contains kernel code + (reserved mem0) or data (reserved mem1) grabbed by the kernel + before sigma0 was initialized */ + dword_t reserved_mem0_low, reserved_mem0_high; + dword_t reserved_mem1_low, reserved_mem1_high; + + /* these regions contain dedicated memory which cannot be used as + standard memory. For example, on PCs [640, 1M] is a popular + dedicated memory region. */ + dword_t dedicated_mem0_low, dedicated_mem0_high; + dword_t dedicated_mem1_low, dedicated_mem1_high; + dword_t dedicated_mem2_low, dedicated_mem2_high; + dword_t dedicated_mem3_low, dedicated_mem3_high; + dword_t dedicated_mem4_low, dedicated_mem4_high; + + /* the kernel clock */ +#if defined (CONFIG_SMP) + volatile +#endif + qword_t clock; + + /* ? */ + dword_t reserved_0xA8[2]; + + dword_t processor_frequency; + dword_t bus_frequency; + + dword_t reserved_0xB8[2]; +} kernel_info_page_t; +extern kernel_info_page_t kernel_info_page; + + +/* + * kernel versioning + */ +// currently defined architectures +#define KERNEL_VERSION_CPU_X86 0 +#define KERNEL_VERSION_CPU_ARM 1 +#define KERNEL_VERSION_CPU_MIPS 2 + +// Version Y ABI just for those processors that have SYSENTER/SYSEXIT +#if !defined(CONFIG_IA32_FEATURE_SEP) +# define KERNEL_VERSION_API 0xB0 /* Version X */ +#else +# define KERNEL_VERSION_API 0xB1 /* Version Y */ +#endif + +// Welcome - it's L4KA :) +#define KERNEL_VERSION_KID 0x4 /* L4KA */ +#define KERNEL_VERSION_SUB 0x1 /* RC1 */ + + +#endif /* __KERNEL_H__ */ diff --git a/kernel/include/kmemory.h b/kernel/include/kmemory.h new file mode 100644 index 0000000..f204d51 --- /dev/null +++ b/kernel/include/kmemory.h @@ -0,0 +1,31 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: kmemory.h + * Description: Kernel memory allocator function declarations. + * + * @LICENSE@ + * + * $Id: kmemory.h,v 1.11 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __KMEMORY_H__ +#define __KMEMORY_H__ + +#ifdef CONFIG_HAVE_ARCH_KMEM + +#include INC_ARCH(kmemory.h) + +#else /* !CONFIG_HAVE_ARCH_KMEM */ + +#define KMEM_CHUNKSIZE 0x400 + +ptr_t kmem_alloc(dword_t size); +void kmem_free(ptr_t address, dword_t size); + + +#endif /* !CONFIG_HAVE_ARCH_KMEM */ + + +#endif /* !__KMEMORY_H__ */ diff --git a/kernel/include/lib.h b/kernel/include/lib.h new file mode 100644 index 0000000..c5bc2f1 --- /dev/null +++ b/kernel/include/lib.h @@ -0,0 +1,20 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: lib.h + * Description: Various in-kernel helper functions. + * + * @LICENSE@ + * + * $Id: lib.h,v 1.4 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __LIB_H__ +#define __LIB_H__ + +void zero_memory(dword_t* dest, int len); +void memcpy(dword_t* dest, dword_t * src, int len); + + +#endif /* __LIB_H__ */ diff --git a/kernel/include/macros.h b/kernel/include/macros.h new file mode 100644 index 0000000..8058abb --- /dev/null +++ b/kernel/include/macros.h @@ -0,0 +1,52 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: macros.h + * Description: Collection of various "global" kernel macros. + * + * @LICENSE@ + * + * $Id: macros.h,v 1.8 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MACROS_H__ +#define __MACROS_H__ + +/* + * macros for CPP + * + * Precondition: __ARCH__ and __PLATFORM__ are defined + * + * Use: If __ARCH__=x86 and __PLATFORM__=i686 + * #include INC_ARCH(thread.h) includes include/x86/thread.h + * #include INC_PLATFORM(kdebug.h) includes include/x86/i686/thread.h + * + */ +#define INC_ARCH(x) <__ARCH__/x> +#define INC_PLATFORM(x) <__ARCH__/__PLATFORM__/x> + +#define L4_SECT_INIT __attribute__ ((section (".init"))) +#define L4_SECT_ROINIT __attribute__ ((section (".roinit"))) +#define L4_SECT_TEXT __attribute__ ((section (".text"))) +#define L4_SECT_KDEBUG __attribute__ ((section (".kdebug"))) +#if !defined(CONFIG_SMP) +# define L4_SECT_CPULOCAL +#else +# define L4_SECT_CPULOCAL __attribute__ ((section (".cpulocal"))) +#endif + +#define INLINE static inline + +#if (__GNUC__ >= 3) +#define EXPECT_TRUE(x) __builtin_expect((x), 1) +#define EXPECT_FALSE(x) __builtin_expect((x), 0) +#define EXPECT_VALUE(x,val) __builtin_expect((x), (val)) +#else /* __GNUC__ < 3 */ +#define EXPECT_TRUE(x) (x) +#define EXPECT_FALSE(x) (x) +#define EXPECT_VALUE(x,val) (x) +#endif /* __GNUC__ < 3 */ + + +#endif /* __MACROS_H__ */ diff --git a/kernel/include/mapping.h b/kernel/include/mapping.h new file mode 100644 index 0000000..3201a2d --- /dev/null +++ b/kernel/include/mapping.h @@ -0,0 +1,115 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mapping.h + * Description: Declarations and interfaces for generic mapping + * database. + * + * @LICENSE@ + * + * $Id: mapping.h,v 1.6 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MAPPING_H__ +#define __MAPPING_H__ + +#include INC_ARCH(mapping.h) + + +#define MDB_ALL_SPACES (1<<31) +#define MDB_FLUSH (1<<1) + + +/* + * The mdb_pgshifts[] is an architecture specific arrray defining the + * page sizes that should be supported by the mapping databse. + * Actually, it defines the shift numbers rather than the page sizes. + * The last entry in the array should define the whole address space. + * E.g if page sizes of 1MB, 64KB, 4KB, and 1KB are supported, the + * array would contain: + * + * dword_t mdb_pgshifts[5] = { 10, 12, 16, 20, 32 }; + * + */ +extern dword_t mdb_pgshifts[]; + + + +/* + * The mdb_buflistsp[] array defines the buffer sizes that will be + * needed by the mapping database, these sizes depend on the page + * sizes to be supported, and also on the size of the rnode_t and + * mnode_t structures. For efficiency reasons, the first entry should + * define the buffer size that will be allocated most frequently (i.e. + * the size of mapping nodes). The array should be terminated by + * defining a zero buffer size. A buffer size declaration for the ARM + * architecture would for instance be declared like: + * + * mdb_buflist_t mdb_buflists[5] = { {12}, {8}, {64}, {16}, {0} }; + * + */ +typedef struct { + dword_t size; + ptr_t list_of_lists; + dword_t max_free; +} mdb_buflist_t; + +extern mdb_buflist_t mdb_buflists[]; + + +/* Top level mapping node for sigma0. */ +extern mnode_t *sigma0_mapnode; + + +typedef struct { + mnode_t *map; + rnode_t *root; +} dualnode_t; + + + +/* + * Prototypes + */ + +/* From mapping.c */ +mnode_t *mdb_map(mnode_t *f_map, pgent_t *f_pg, dword_t f_pgsize, + dword_t f_addr, pgent_t *t_pg, dword_t t_pgsize, + space_t *t_space); +int mdb_flush(mnode_t *f_map, pgent_t *f_pg, dword_t f_pgsize, + dword_t t_addr, dword_t t_pgsize, dword_t mode); + + +/* From mapping_alloc.c */ +ptr_t mdb_alloc_buffer(dword_t size); +void mdb_free_buffer(ptr_t addr, dword_t size); + + + +/* + * Helper functions + */ + +static inline dword_t page_size(dword_t pgsize) +{ + return 1 << hw_pgshifts[pgsize]; +} + +static inline dword_t page_mask(dword_t pgsize) +{ + return (~0U) >> (32 - hw_pgshifts[pgsize]); +} + +static inline dword_t table_size(dword_t pgsize) +{ + return 1 << (hw_pgshifts[pgsize+1] - hw_pgshifts[pgsize]); +} + +static inline dword_t table_index(dword_t addr, dword_t pgsize) +{ + return (addr >> hw_pgshifts[pgsize]) & (table_size(pgsize) - 1); +} + + +#endif /* !__MAPPING_H__ */ diff --git a/kernel/include/mips/config.h b/kernel/include/mips/config.h new file mode 100644 index 0000000..55a3576 --- /dev/null +++ b/kernel/include/mips/config.h @@ -0,0 +1,48 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/config.h + * Description: Configuration for the MIPS platform. + * + * @LICENSE@ + * + * $Id: config.h,v 1.2 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_CONFIG_H__ +#define __MIPS_CONFIG_H__ + +/* thread configuration */ +#define TCB_AREA 0xC0000000 +#define TCB_AREA_SIZE 0x01000000 + +#define MEM_COPYAREA1 0xC2000000 +#define MEM_COPYAREA2 (MEM_COPYAREA1 + (PAGEDIR_SIZE * 2)) +#define MEM_COPYAREA_END (MEM_COPYAREA2 + (PAGEDIR_SIZE * 2)) + +#define L4_NUMBITS_TCBS 10 +#define L4_NUMBITS_THREADS 22 + +#define L4_TOTAL_TCB_SIZE (1 << L4_NUMBITS_TCBS) +#define L4_TCB_MASK ((~0) << L4_NUMBITS_TCBS) + +#define EXCEPTION_VECTOR_BASE (0xA0000000) +#define EXCEPTION_TLB_REFILL (EXCEPTION_VECTOR_BASE + 0x000) +#define EXCEPTION_XTLB_REFILL (EXCEPTION_VECTOR_BASE + 0x080) +#define EXCEPTION_CACHE_ERROR (EXCEPTION_VECTOR_BASE + 0x100) +#define EXCEPTION_OTHER (EXCEPTION_VECTOR_BASE + 0x180) +#define EXCEPTION_RESET (0xBFC00000) + + +#define KERNEL_VIRT 0x80000000 +#define KERNEL_PHYS 0x00000000 +#define KERNEL_SIZE 0x00010000 + +#define KERNEL_OFFSET 0x88000000 + +/* scheduler configuration */ +#define DEFAULT_TIMESLICE 2 +#define TIME_QUANTUM 1 + +#endif diff --git a/kernel/include/mips/cpu.h b/kernel/include/mips/cpu.h new file mode 100644 index 0000000..eb72c6b --- /dev/null +++ b/kernel/include/mips/cpu.h @@ -0,0 +1,116 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/cpu.h + * Description: MIPS CPU spcific definitions. + * + * @LICENSE@ + * + * $Id: cpu.h,v 1.3 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_CPU_H__ +#define __MIPS_CPU_H__ + +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define jp $25 +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* same as fp */ +#define ra $31 /* return address */ + +/* + * Coprocessor 0 + */ +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_CONFIG $16 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_XCONTEXT $20 +#define CP0_FRAMEMASK $21 +#define CP0_DIAGNOSTIC $22 +#define CP0_PERFORMANCE $25 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_TAGHI $29 +#define CP0_ERROREPC $30 + +#define ST0_KUP 0x18 + +#ifndef ASSEMBLY + + +typedef struct { + dword_t dummy; +} exception_frame_t; + + +INLINE void disable_interrupts() +{ +} + +INLINE void enable_interrupts() +{ +} + +INLINE void system_sleep() +{ +} + +INLINE void flush_tlb() +{ +} + +INLINE void flush_tlbent(ptr_t addr) +{ +} + + +#endif + +#endif diff --git a/kernel/include/mips/init.h b/kernel/include/mips/init.h new file mode 100755 index 0000000..55aa291 --- /dev/null +++ b/kernel/include/mips/init.h @@ -0,0 +1,18 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/init.h + * Description: MIPS specific initialization declarations. + * + * @LICENSE@ + * + * $Id: init.h,v 1.2 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_INIT_H__ +#define __MIPS_INIT_H__ + +void init_irqs() L4_SECT_INIT; + +#endif diff --git a/kernel/include/mips/kdebug.h b/kernel/include/mips/kdebug.h new file mode 100644 index 0000000..541b922 --- /dev/null +++ b/kernel/include/mips/kdebug.h @@ -0,0 +1,36 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/kdebug.h + * Description: MIPS specific kdebug stuff. + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.5 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_KDEBUG_H__ +#define __MIPS_KDEBUG_H__ + +INLINE void spin(int pos = 80) { + while(1); +} + +INLINE void spin1(int pos) { + putc('.'); +} + +INLINE void enter_kdebug(const char* message = NULL) +{ + if (message) + printf(message); + kdebug_entry(NULL); +} + +INLINE ptr_t get_current_pgtable() +{ + return 0; +} + +#endif /* __MIPS_KDEBUG_H__ */ diff --git a/kernel/include/mips/mapping.h b/kernel/include/mips/mapping.h new file mode 100644 index 0000000..6c1e152 --- /dev/null +++ b/kernel/include/mips/mapping.h @@ -0,0 +1,171 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mips/mapping.h + * Description: MIPS specifications for the mapping database. + * + * @LICENSE@ + * + * $Id: mapping.h,v 1.3 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifdef CONFIG_ENABLE_NEWMDB +#include INC_ARCH(mapping_new.h) +#else +#ifndef __ARM__MAPPING_H__ +#define __ARM__MAPPING_H__ + +#define SIGMA0_PGDIR_ID 0 + +#define NUM_PAGESIZES 1 + + +/* +** +** Mapping node definition and associated macros. +** +*/ +typedef struct { + unsigned pgdir :30; + unsigned next_type :2; + unsigned depth :6; + unsigned :4; + unsigned offset :22; + unsigned next :32; +} __attribute__ ((packed)) mnode_t; + +#define MNODE_SET_NEXT(n, addr) \ + ((n)->next = (dword_t) (addr)) + +#define MNODE_GET_NEXT(n) \ + ((mnode_t *) (n)->next) + +#define MNODE_SET_NEXT_TYPE_MAP(n) \ + ((n)->next_type = 0) + +#define MNODE_SET_NEXT_TYPE_ROOT(n) \ + ((n)->next_type = 1) + +#define MNODE_SET_PARTLY_INVALID(n) \ + ((n)->next_type = 2) + +#define MNODE_SET_INVALID(n) \ + ((n)->next_type = 3) + +#define MNODE_IS_NEXT_TYPE_MAP(n) \ + ((n)->next_type == 0) + +#define MNODE_IS_NEXT_TYPE_ROOT(n) \ + ((n)->next_type == 1) + +#define MNODE_IS_PARTLY_INVALID(n) \ + ((n)->next_type == 2) + +#define MNODE_SET_PGDIR(n, pgd) \ + ((n)->pgdir = (pgd) >> 2) + +#define MNODE_GET_PGDIR(n) \ + ((n)->pgdir << 2) + +#define MNODE_SET_OFFSET(n, off) \ + ((n)->offset = (off) >> 10) + +#define MNODE_GET_OFFSET(n) \ + ((n)->offset << 10) + +#define MNODE_OFFSET_EQ(n, off) \ + ((n)->offset << 10 == (off)) + +#define MNODE_SET_DEPTH(n, dpt) \ + ((n)->depth = (dpt)) + +#define MNODE_GET_DEPTH(n) \ + ((n)->depth) + + +/* +** +** Root node definition and associated macros. +** +*/ +typedef struct { + unsigned pgsize :1; + unsigned :3; + unsigned maptree :26; + unsigned next_type :2; +} rnode_t; + +#define RNODE_SET_NEXT_TYPE_MAP(n) \ + ((n)->next_type = 0) + +#define RNODE_SET_NEXT_TYPE_ROOT(n) \ + ((n)->next_type = 1) + +#define RNODE_SET_PARTLY_INVALID(n) \ + ((n)->next_type = 2) + +#define RNODE_SET_INVALID(n) \ + ((n)->next_type = 3) + +#define RNODE_IS_NEXT_TYPE_MAP(n) \ + ((n)->next_type == 0) + +#define RNODE_IS_NEXT_TYPE_ROOT(n) \ + ((n)->next_type == 1) + +#define RNODE_IS_PARTLY_INVALID(n) \ + ((n)->next_type == 2) + +#define RNODE_IS_INVALID(n) \ + ((n)->next_type == 3) + +#define RNODE_SET_PGSIZE(n, size) \ + ((n)->pgsize = size) + +#define RNODE_GET_PGSIZE(n) \ + ((n)->pgsize) + +#define RNODE_SET_MAPTREE(n, tree) \ +({ \ + ((n)->maptree = ((((dword_t) (tree)) >> 2) & 0x03ffffff)); \ + if ( (dword_t) RNODE_GET_MAPTREE(n) != (dword_t) tree && \ + (dword_t) tree != 0 ) { \ + printf("Maptree = 0x%x\n", tree); \ + panic("Maptree setting has lost some bits."); \ + } \ +}) + +#define RNODE_GET_MAPTREE(n) \ + ((n)->maptree ? ((mnode_t *) (((n)->maptree << 2) + 0xf0000000)) : \ + (mnode_t *) 0) + + + +typedef struct { + mnode_t *map; + rnode_t *root; + unsigned num_occupied:16; + unsigned num_invalid:16; +} dualnode_t; + + +/* +** +** Macros not operating on neither mapping nodes nor root nodes. +** +*/ +#define MDB_IS_KERNEL_PGDIR(p) \ + ((p) == kernel_pgdir) + +#define MDB_OFFSET_TO_ADDR(offset) \ + ((offset) << 10) + +#define MDB_ADDR_TO_OFFSET(addr) \ + ((addr) >> 10) + + + + +#endif /* !__ARM__MAPPING_H__ */ +#endif diff --git a/kernel/include/mips/memory.h b/kernel/include/mips/memory.h new file mode 100644 index 0000000..3834cfc --- /dev/null +++ b/kernel/include/mips/memory.h @@ -0,0 +1,179 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/memory.h + * Description: MIPS specific page table manipulation code. + * + * @LICENSE@ + * + * $Id: memory.h,v 1.6 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_MEMORY_H__ +#define __MIPS_MEMORY_H__ + +#include INC_ARCH(config.h) + +#define PAGEDIR_BITS 22 +#define PAGEDIR_SIZE (dword_t)(1 << PAGEDIR_BITS) +#define PAGEDIR_MASK (dword_t)(~(PAGEDIR_SIZE - 1)) + +#define PAGE_BITS 12 +#define PAGE_SIZE (1 << PAGE_BITS) +#define PAGE_MASK (~(PAGE_SIZE - 1)) + +#define PAGE_UNCACHED (2 << 5) +#define PAGE_CACHE_NONCOHERENT (3 << 5) +#define PAGE_CACHE_EXCLUSIVE (4 << 5) +#define PAGE_CACHE_SHARABLE (5 << 5) +#define PAGE_CACHE_UPDATE (6 << 5) + +#define PAGE_READONLY 0x00 +#define PAGE_WRITABLE 0x10 + +#define PAGE_GLOBAL 0x04 +#define PAGE_VALID 0x08 + +#define PT_ZEROPAGE (PAGE_VALID | PAGE_UNCACHED) +#define PT_TCB (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL | PAGE_UNCACHED) +#define PT_KERNELMEM (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL | PAGE_UNCACHED) +#define PT_SIGMA0 (PAGE_VALID | PAGE_WRITABLE | PAGE_CACHE_SHARABLE) + +#define PAGE_USER_BITS (PAGE_VALID) + +#ifndef ASSEMBLY + +/* declared in mips/init.c */ +extern ptr_t __zero_page; + + +#define virt_to_phys(x) \ +({ typeof(x) _x = (typeof(x))((dword_t) (x) - KERNEL_OFFSET); _x;}) + +#define phys_to_virt(x) \ +({ typeof(x) _x = (typeof(x))((dword_t) (x) + KERNEL_OFFSET); _x;}) + +INLINE void set_ptab_entry(ptr_t ptab, ptr_t virt, dword_t val) +{ + ptab[(((dword_t)virt) >> 12) & 0x3ff] = val; +} + +INLINE void set_pdir_entry(ptr_t pdir, ptr_t virt, dword_t val) +{ + pdir[((dword_t)virt) >> 22] = val; +} + +INLINE dword_t get_pagefault_address() +{ + return 0; +} + +INLINE ptr_t get_kernel_pagetable() +{ + extern dword_t __pdir_root[]; + return &__pdir_root[0]; +} + +INLINE ptr_t get_current_pagetable() +{ + return current_page_table; +} + +INLINE void set_current_pagetable(ptr_t pdir) +{ + current_page_table = pdir; +} + +void init_paging(); + +class pgent_t +{ + public: + union { + struct { + unsigned zero :2; + unsigned global :1; + unsigned valid :1; + unsigned rw :1; + unsigned cache :3; + unsigned base :24; + } pg; + + dword_t raw; + } x; + + // Predicates + + inline dword_t is_valid(dword_t pgsize) + { return x.raw & PAGE_VALID; } + + inline dword_t is_writable(dword_t pgsize) + { return x.raw & PAGE_WRITABLE; } + + inline dword_t is_subtree(dword_t pgsize) + { return 1; } + + // Retrieval operations + + inline dword_t address(dword_t pgsize) + { return x.raw & PAGE_MASK; } + + inline pgent_t * subtree(dword_t pgsize) + { return (pgent_t *) phys_to_virt(x.raw & PAGE_MASK); } + + // Change operations + + inline void clear(dword_t pgsize) + { x.raw = 0; } + + inline void make_subtree(dword_t pgsize) + { x.raw = virt_to_phys((dword_t) kmem_alloc((dword_t) PAGE_SIZE)) + | PAGE_VALID; + } + + inline void remove_subtree(dword_t pgsize) + { + kmem_free((ptr_t) phys_to_virt(x.raw & PAGE_MASK), PAGE_SIZE); + x.raw = 0; + } + inline void split(dword_t pgsize) + { +#if 0 + pgent_t *n = (pgent_t *) kmem_alloc((dword_t) PAGE_SIZE); + pgent_t t; + + x.raw &= ~PAGE_SUPER; + t.x.raw = x.raw; + + for ( int i = 0; i < 1024; i++ ) + { + n[i].x.raw = t.x.raw; + t.x.pg.base++; + } + + x.raw = (dword_t) virt_to_phys(n) | PAGE_USER_BITS | PAGE_WRITABLE; +#endif + } + inline void set_entry(dword_t addr, dword_t writable, dword_t pgsize) + { x.raw = (addr & PAGE_MASK) | PAGE_USER_BITS | + (writable ? PAGE_WRITABLE : 0); + } + + inline void set_writable(dword_t pgsize) + { x.raw |= PAGE_WRITABLE; } + + inline void set_readonly(dword_t pgsize) + { x.raw &= ~PAGE_WRITABLE; } + + // Movement + + inline pgent_t * next(dword_t num, dword_t pgsize) + { return this + num; } + +}; + + +#endif /* ASSEMBLY */ + +#endif /* __MIPS_MEMORY_H__ */ diff --git a/kernel/include/mips/notify.h b/kernel/include/mips/notify.h new file mode 100644 index 0000000..033acf6 --- /dev/null +++ b/kernel/include/mips/notify.h @@ -0,0 +1,45 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/notify.h + * Description: Code for invoking a notify function in the context + * of another thread. + * + * @LICENSE@ + * + * $Id: notify.h,v 1.4 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_NOTIFY_H__ +#define __MIPS_NOTFIY_H__ + +#define notify_thread(tcb, func) \ +{ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_1(tcb, func, param0) \ +{ \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, 0); /* return addr */ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_2(tcb, func, param0, param1) \ +{ \ + tcb_stack_push(tcb, param1); \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, 0); /* return addr */ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define comma_nightmare(params...) params + +#define notify_procedure(func, params...) \ +void notify_##func( comma_nightmare(params##,) dword_t __final) + +/* restore stackpointer */ +#define notify_return return + +#endif /* __MIPS_NOTIFY_H__ */ diff --git a/kernel/include/mips/pr31700/platform.h b/kernel/include/mips/pr31700/platform.h new file mode 100644 index 0000000..e046550 --- /dev/null +++ b/kernel/include/mips/pr31700/platform.h @@ -0,0 +1,145 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/pr31700/platform.h + * Description: MIPS PR31700 platform specific definitions. + * + * @LICENSE@ + * + * $Id: platform.h,v 1.4 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_PR31700_PLATFORM_H__ +#define __MIPS_PR31700_PLATFORM_H__ + +/* defines system interface unit registers */ +#define SIU_BASE 0x10C00000 + +// memory configuration +#define SIU_MEMCFG_0 0x000 +#define SIU_MEMCFG_1 0x004 +#define SIU_MEMCFG_2 0x008 +#define SIU_MEMCFG_3 0x00C +#define SIU_MEMCFG_4 0x010 +#define SIU_MEMCFG_5 0x014 +#define SIU_MEMCFG_6 0x018 +#define SIU_MEMCFG_7 0x01C +#define SIU_MEMCFG_8 0x020 + +// video control +#define SIU_VIDEO_CTRL_1 0x028 +#define SIU_VIDEO_CTRL_2 0x02C +#define SIU_VIDEO_CTRL_3 0x030 +#define SIU_VIDEO_CTRL_4 0x034 +#define SIU_VIDEO_CTRL_5 0x038 +#define SIU_VIDEO_CTRL_6 0x03C +#define SIU_VIDEO_CTRL_7 0x040 +#define SIU_VIDEO_CTRL_8 0x044 +#define SIU_VIDEO_CTRL_9 0x048 +#define SIU_VIDEO_CTRL_10 0x04C +#define SIU_VIDEO_CTRL_11 0x050 +#define SIU_VIDEO_CTRL_12 0x054 +#define SIU_VIDEO_CTRL_13 0x058 +#define SIU_VIDEO_CTRL_14 0x05C + +// SIB +#define SIB_SIZE 0x060 +#define SIB_SOUND_RCV_START 0x064 +#define SIB_SOUND_TRANS_START 0x068 +#define SIB_TEL_RCV_START 0x06C +#define SIB_TEL_TRANS_START 0x070 +#define SIB_CONTROL 0x074 +#define SIB_SOUND_HOLDING 0x078 +#define SIB_TEL_HOLDING 0x07C +#define SIB_SF0_CONTROL 0x080 +#define SIB_SF1_CONTROL 0x084 +#define SIB_SF0_STATUS 0x088 +#define SIB_SF1_STATUS 0x08C +#define SIB_DMA_CONTROL 0x090 + +// InfraRed +#define IR_CONTROL_1 0x0A0 +#define IR_CONTROL_2 0x0A4 +#define IR_HOLDING 0x0A8 + +// UARTA +#define UARTA_CONTROL_1 0x0B0 +#define UARTA_CONTROL_2 0x0B4 +#define UARTA_DMA_CONTROL_1 0x0B8 +#define UARTA_DMA_CONTROL_2 0x0BC +#define UARTA_DMA_COUNT 0x0C0 +#define UARTA_HOLDING 0x0C4 + +// UARTB +#define UARTB_CONTROL_1 0x0C8 +#define UARTB_CONTROL_2 0x0CC +#define UARTB_DMA_CONTROL_1 0x0D0 +#define UARTB_DMA_CONTROL_2 0x0D4 +#define UARTB_DMA_COUNT 0x0D8 +#define UARTB_HOLDING 0x0DC + +// Interrupt Controller +#define IRQ_1 0x100 +#define IRQ_2 0x104 +#define IRQ_3 0x108 +#define IRQ_4 0x10C +#define IRQ_5 0x110 +#define IRQ_6 0x114 +#define IRQ_ENABLE_1 0x118 +#define IRQ_ENABLE_2 0x11C +#define IRQ_ENABLE_3 0x120 +#define IRQ_ENABLE_4 0x124 +#define IRQ_ENABLE_5 0x128 +#define IRQ_ENABLE_6 0x12C + +// RTC +#define RTC_HIGH 0x140 +#define RTC_LOW 0x144 +#define RTC_ALARM_HIGH 0x148 +#define RTC_ALARM_LOW 0x14C +#define RTC_TIMER_CONTROL 0x150 +#define RTC_PERIODIC_TIMER 0x154 + +// SPI +#define SPI_CONTROL 0x160 +#define SPI_HOLDING 0x164 + +// IO +#define IO_CONTROL 0x180 +#define IO_MF_IO_OUT 0x184 +#define IO_MF_IO_DIRECTION 0x188 +#define IO_MF_IO_IN 0x18C +#define IO_MF_IO_SELECT 0x190 +#define IO_POWER_DOWN 0x194 +#define IO_MF_POWER_DOWN 0x198 + +// Control +#define CLOCK_CONTROL 0x1C0 +#define POWER_CONTROL 0x1C4 +#define SIU_TEST 0x1C8 + +// CHI +#define CHI_CONTROL 0x1D8 +#define CHI_POINTER_ENABLE 0x1DC +#define CHI_RCV_POINTER_A 0x1E0 +#define CHI_RCV_POINTER_B 0x1E4 +#define CHI_TRANS_POINTER_A 0x1E8 +#define CHI_TRANS_POINTER_B 0x1EC +#define CHI_SIZE 0x1F0 +#define CHI_RECV_START 0x1F4 +#define CHI_TRANS_START 0x1F8 +#define CHI_HOLDING 0x1FC + +INLINE void siu_out(dword_t reg, dword_t val) +{ + *(__volatile__ dword_t*)(0x80000000U + SIU_BASE + reg) = val; +} + +INLINE dword_t siu_in(dword_t reg) +{ + return *(__volatile__ dword_t*)(0x80000000U + SIU_BASE + reg); +} + + +#endif /* __MIPS_PR31700_PLATFORM_H__ */ diff --git a/kernel/include/mips/sgialib.h b/kernel/include/mips/sgialib.h new file mode 100644 index 0000000..7a818b6 --- /dev/null +++ b/kernel/include/mips/sgialib.h @@ -0,0 +1,122 @@ +/* $Id: sgialib.h,v 1.1 2000/02/07 17:41:23 uhlig Exp $ + * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef _MIPS_SGIALIB_H +#define _MIPS_SGIALIB_H + +#include + +extern struct linux_promblock *sgi_pblock; +extern struct linux_romvec *romvec; +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +extern int prom_flags; +#define PROM_FLAG_ARCS 1 + +/* Init the PROM library and it's internal data structures. Called + * at boot time from head.S before start_kernel is invoked. + */ +extern int prom_init(int argc, char **argv, char **envp); + +/* Simple char-by-char console I/O. */ +extern void prom_putchar(char c); +extern char prom_getchar(void); + +/* Generic printf() using ARCS console I/O. */ +extern void prom_printf(char *fmt, ...); + +/* Memory descriptor management. */ +#define PROM_MAX_PMEMBLOCKS 32 +struct prom_pmemblock { + unsigned long base; /* Within KSEG0. */ + unsigned int size; /* In bytes. */ + unsigned int type; /* free or prom memory */ +}; + +/* Get next memory descriptor after CURR, returns first descriptor + * in chain is CURR is NULL. + */ +extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); +#define PROM_NULL_MDESC ((struct linux_mdesc *) 0) + +/* Called by prom_init to setup the physical memory pmemblock + * array. + */ +extern void prom_meminit(void); +extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); + +/* Returns pointer to PROM physical memory block array. */ +extern struct prom_pmemblock *prom_getpblock_array(void); + +/* PROM device tree library routines. */ +#define PROM_NULL_COMPONENT ((pcomponent *) 0) + +/* Get sibling component of THIS. */ +extern pcomponent *prom_getsibling(pcomponent *prom_this); + +/* Get child component of THIS. */ +extern pcomponent *prom_getchild(pcomponent *prom_this); + +/* Get parent component of CHILD. */ +extern pcomponent *prom_getparent(pcomponent *child); + +/* Copy component opaque data of component THIS into BUFFER + * if component THIS has opaque data. Returns success or + * failure status. + */ +extern long prom_getcdata(void *buffer, pcomponent *prom_this); + +/* Other misc. component routines. */ +extern pcomponent *prom_childadd(pcomponent *prom_this, pcomponent *tmp, void *data); +extern long prom_delcomponent(pcomponent *prom_this); +extern pcomponent *prom_componentbypath(char *path); + +/* This is called at prom_init time to identify the + * ARC architecture we are running on + */ +extern void prom_identify_arch(void); + +/* Environemt variable routines. */ +extern char *prom_getenv(char *name); +extern long prom_setenv(char *name, char *value); + +/* ARCS command line acquisition and parsing. */ +extern char *prom_getcmdline(void); +extern void prom_init_cmdline(void); + +/* Acquiring info about the current time, etc. */ +extern struct linux_tinfo *prom_gettinfo(void); +extern unsigned long prom_getrtime(void); + +/* File operations. */ +extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt); +extern long prom_open(char *name, enum linux_omode md, unsigned long *fd); +extern long prom_close(unsigned long fd); +extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_getrstatus(unsigned long fd); +extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm); +extern long prom_mount(char *name, enum linux_mountops op); +extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf); +extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk); + +/* Running stand-along programs. */ +extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr); +extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp); +extern long prom_exec(char *name, long argc, char **argv, char **envp); + +/* Misc. routines. */ +extern void prom_halt(void) __attribute__((noreturn)); +extern void prom_powerdown(void) __attribute__((noreturn)); +extern void prom_restart(void) __attribute__((noreturn)); +extern void prom_reboot(void) __attribute__((noreturn)); +extern void prom_imode(void) __attribute__((noreturn)); +extern long prom_cfgsave(void); +extern struct linux_sysid *prom_getsysid(void); +extern void prom_cacheflush(void); + +#endif /* !(_MIPS_SGIALIB_H) */ diff --git a/kernel/include/mips/sgiarcs.h b/kernel/include/mips/sgiarcs.h new file mode 100644 index 0000000..44962a5 --- /dev/null +++ b/kernel/include/mips/sgiarcs.h @@ -0,0 +1,375 @@ +/* $Id: sgiarcs.h,v 1.2 2001/04/20 18:49:32 ud3 Exp $ + * + * SGI ARCS firmware interface defines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * copy-n-paste from linux + */ + +#ifndef _MIPS_SGIARCS_H +#define _MIPS_SGIARCS_H + +/* Various ARCS error codes. */ +#define PROM_ESUCCESS 0x00 +#define PROM_E2BIG 0x01 +#define PROM_EACCESS 0x02 +#define PROM_EAGAIN 0x03 +#define PROM_EBADF 0x04 +#define PROM_EBUSY 0x05 +#define PROM_EFAULT 0x06 +#define PROM_EINVAL 0x07 +#define PROM_EIO 0x08 +#define PROM_EISDIR 0x09 +#define PROM_EMFILE 0x0a +#define PROM_EMLINK 0x0b +#define PROM_ENAMETOOLONG 0x0c +#define PROM_ENODEV 0x0d +#define PROM_ENOENT 0x0e +#define PROM_ENOEXEC 0x0f +#define PROM_ENOMEM 0x10 +#define PROM_ENOSPC 0x11 +#define PROM_ENOTDIR 0x12 +#define PROM_ENOTTY 0x13 +#define PROM_ENXIO 0x14 +#define PROM_EROFS 0x15 +/* SGI ARCS specific errno's. */ +#define PROM_EADDRNOTAVAIL 0x1f +#define PROM_ETIMEDOUT 0x20 +#define PROM_ECONNABORTED 0x21 +#define PROM_ENOCONNECT 0x22 + +/* Device classes, types, and identifiers for prom + * device inventory queries. + */ +enum linux_devclass { + system, processor, cache, adapter, controller, peripheral, memory +}; + +enum linux_devtypes { + /* Generic stuff. */ + Arc, Cpu, Fpu, + + /* Primary insn and data caches. */ + picache, pdcache, + + /* Secondary insn, data, and combined caches. */ + sicache, sdcache, sccache, + + memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter, + multifunc_adapter, dsk_controller, tp_controller, cdrom_controller, + worm_controller, serial_controller, net_controller, disp_controller, + parallel_controller, ptr_controller, kbd_controller, audio_controller, + misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral, + modem_peripheral, monitor_peripheral, printer_peripheral, + ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral, + net_peripheral, misc_peripheral, anon +}; + +enum linux_identifier { + bogus, ronly, removable, consin, consout, input, output +}; + +/* A prom device tree component. */ +struct linux_component { + enum linux_devclass dclass; /* node class */ + enum linux_devtypes type; /* node type */ + enum linux_identifier iflags; /* node flags */ + unsigned short vers; /* node version */ + unsigned short rev; /* node revision */ + unsigned long key; /* completely magic */ + unsigned long amask; /* XXX affinity mask??? */ + unsigned long cdsize; /* size of configuration data */ + unsigned long ilen; /* length of string identifier */ + char *iname; /* string identifier */ +}; +typedef struct linux_component pcomponent; + +struct linux_sysid { + char vend[8], prod[8]; +}; + +/* ARCS prom memory descriptors. */ +enum arcs_memtypes { + arcs_eblock, /* exception block */ + arcs_rvpage, /* ARCS romvec page */ + arcs_fcontig, /* Contiguous and free */ + arcs_free, /* Generic free memory */ + arcs_bmem, /* Borken memory, don't use */ + arcs_prog, /* A loaded program resides here */ + arcs_atmp, /* ARCS temporary storage area, wish Sparc OpenBoot told this */ + arcs_aperm, /* ARCS permanent storage... */ +}; + +/* ARC has slightly different types than ARCS */ +enum arc_memtypes { + arc_eblock, /* exception block */ + arc_rvpage, /* romvec page */ + arc_free, /* Generic free memory */ + arc_bmem, /* Borken memory, don't use */ + arc_prog, /* A loaded program resides here */ + arc_atmp, /* temporary storage area */ + arc_aperm, /* permanent storage */ + arc_fcontig, /* Contiguous and free */ +}; + +union linux_memtypes { + enum arcs_memtypes arcs; + enum arc_memtypes arc; +}; + +struct linux_mdesc { + union linux_memtypes type; + unsigned long base; + unsigned long pages; +}; + +/* Time of day descriptor. */ +struct linux_tinfo { + unsigned short yr; + unsigned short mnth; + unsigned short day; + unsigned short hr; + unsigned short min; + unsigned short sec; + unsigned short msec; +}; + +/* ARCS virtual dirents. */ +struct linux_vdirent { + unsigned long namelen; + unsigned char attr; + char fname[32]; /* XXX imperical, should be a define */ +}; + +/* Other stuff for files. */ +enum linux_omode { + rdonly, wronly, rdwr, wronly_creat, rdwr_creat, + wronly_ssede, rdwr_ssede, dirent, dirent_creat +}; + +enum linux_seekmode { + absolute, relative +}; + +enum linux_mountops { + media_load, media_unload +}; + +/* This prom has a bolixed design. */ +struct linux_bigint { +#ifdef __MIPSEL__ + unsigned long lo; + long hi; +#else /* !(__MIPSEL__) */ + long hi; + unsigned long lo; +#endif +}; + +struct linux_finfo { + struct linux_bigint begin; + struct linux_bigint end; + struct linux_bigint cur; + enum linux_devtypes dtype; + unsigned long namelen; + unsigned char attr; + char name[32]; /* XXX imperical, should be define */ +}; + +struct linux_romvec { + /* Load an executable image. */ + long (*load)(char *file, unsigned long end, + unsigned long *start_pc, + unsigned long *end_addr); + + /* Invoke a standalong image. */ + long (*invoke)(unsigned long startpc, unsigned long sp, + long argc, char **argv, char **envp); + + /* Load and begin execution of a standalong image. */ + long (*exec)(char *file, long argc, char **argv, char **envp); + + void (*halt)(void) __attribute__((noreturn)); /* Halt the machine. */ + void (*pdown)(void) __attribute__((noreturn)); /* Power down the machine. */ + void (*restart)(void) __attribute__((noreturn)); /* XXX soft reset??? */ + void (*reboot)(void) __attribute__((noreturn)); /* Reboot the machine. */ + void (*imode)(void) __attribute__((noreturn)); /* Enter PROM interactive mode. */ + int _unused1; /* padding */ + + /* PROM device tree interface. */ + pcomponent *(*next_component)(pcomponent *prom_this); + pcomponent *(*child_component)(pcomponent *prom_this); + pcomponent *(*parent_component)(pcomponent *prom_this); + long (*component_data)(void *opaque_data, pcomponent *prom_this); + pcomponent *(*child_add)(pcomponent *prom_this, + pcomponent *tmp, + void *opaque_data); + long (*comp_del)(pcomponent *prom_this); + pcomponent *(*component_by_path)(char *file); + + /* Misc. stuff. */ + long (*cfg_save)(void); + struct linux_sysid *(*get_sysid)(void); + + /* Probing for memory. */ + struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr); + long _unused2; /* padding */ + + struct linux_tinfo *(*get_tinfo)(void); + unsigned long (*get_rtime)(void); + + /* File type operations. */ + long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry, + unsigned long num, unsigned long *count); + long (*open)(char *file, enum linux_omode mode, unsigned long *fd); + long (*close)(unsigned long fd); + long (*read)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*get_rstatus)(unsigned long fd); + long (*write)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*seek)(unsigned long fd, struct linux_bigint *offset, + enum linux_seekmode smode); + long (*mount)(char *file, enum linux_mountops op); + + /* Dealing with firmware environment variables. */ + char *(*get_evar)(char *name); + long (*set_evar)(char *name, char *value); + + long (*get_finfo)(unsigned long fd, struct linux_finfo *buf); + long (*set_finfo)(unsigned long fd, unsigned long flags, + unsigned long mask); + + /* Miscellaneous. */ + void (*cache_flush)(void); +}; + +/* The SGI ARCS parameter block is in a fixed location for standalone + * programs to access PROM facilities easily. + */ +struct linux_promblock { + long magic; /* magic cookie */ +#define PROMBLOCK_MAGIC 0x53435241 + + unsigned long len; /* length of parm block */ + unsigned short ver; /* ARCS firmware version */ + unsigned short rev; /* ARCS firmware revision */ + long *rs_block; /* Restart block. */ + long *dbg_block; /* Debug block. */ + long *gevect; /* XXX General vector??? */ + long *utlbvect; /* XXX UTLB vector??? */ + unsigned long rveclen; /* Size of romvec struct. */ + struct linux_romvec *romvec; /* Function interface. */ + unsigned long pveclen; /* Length of private vector. */ + long *pvector; /* Private vector. */ + long adap_cnt; /* Adapter count. */ + long adap_typ0; /* First adapter type. */ + long adap_vcnt0; /* Adapter 0 vector count. */ + long *adap_vector; /* Adapter 0 vector ptr. */ + long adap_typ1; /* Second adapter type. */ + long adap_vcnt1; /* Adapter 1 vector count. */ + long *adap_vector1; /* Adapter 1 vector ptr. */ + /* More adapter vectors go here... */ +}; + +#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL) +#define ROMVECTOR ((PROMBLOCK)->romvec) + +#if 0 + +/* Cache layout parameter block. */ +union linux_cache_key { + struct param { +#ifdef __MIPSEL__ + unsigned short size; + unsigned char lsize; + unsigned char bsize; +#else /* !(__MIPSEL__) */ + unsigned char bsize; + unsigned char lsize; + unsigned short size; +#endif + } info; + unsigned long allinfo; +}; + +/* Configuration data. */ +struct linux_cdata { + char *name; + int mlen; + enum linux_devtypes type; +}; + +/* Common SGI ARCS firmware file descriptors. */ +#define SGIPROM_STDIN 0 +#define SGIPROM_STDOUT 1 + +/* Common SGI ARCS firmware file types. */ +#define SGIPROM_ROFILE 0x01 /* read-only file */ +#define SGIPROM_HFILE 0x02 /* hidden file */ +#define SGIPROM_SFILE 0x04 /* System file */ +#define SGIPROM_AFILE 0x08 /* Archive file */ +#define SGIPROM_DFILE 0x10 /* Directory file */ +#define SGIPROM_DELFILE 0x20 /* Deleted file */ + +/* SGI ARCS boot record information. */ +struct sgi_partition { + unsigned char flag; +#define SGIPART_UNUSED 0x00 +#define SGIPART_ACTIVE 0x80 + + unsigned char shead, ssect, scyl; /* unused */ + unsigned char systype; /* OS type, Irix or NT */ + unsigned char ehead, esect, ecyl; /* unused */ + unsigned char rsect0, rsect1, rsect2, rsect3; + unsigned char tsect0, tsect1, tsect2, tsect3; +}; + +#define SGIBBLOCK_MAGIC 0xaa55 +#define SGIBBLOCK_MAXPART 0x0004 + +struct sgi_bootblock { + unsigned char _unused[446]; + struct sgi_partition partitions[SGIBBLOCK_MAXPART]; + unsigned short magic; +}; + +/* BIOS parameter block. */ +struct sgi_bparm_block { + unsigned short bytes_sect; /* bytes per sector */ + unsigned char sect_clust; /* sectors per cluster */ + unsigned short sect_resv; /* reserved sectors */ + unsigned char nfats; /* # of allocation tables */ + unsigned short nroot_dirents; /* # of root directory entries */ + unsigned short sect_volume; /* sectors in volume */ + unsigned char media_type; /* media descriptor */ + unsigned short sect_fat; /* sectors per allocation table */ + unsigned short sect_track; /* sectors per track */ + unsigned short nheads; /* # of heads */ + unsigned short nhsects; /* # of hidden sectors */ +}; + +struct sgi_bsector { + unsigned char jmpinfo[3]; + unsigned char manuf_name[8]; + struct sgi_bparm_block info; +}; + +/* Debugging block used with SGI symmon symbolic debugger. */ +#define SMB_DEBUG_MAGIC 0xfeeddead +struct linux_smonblock { + unsigned long magic; + void (*handler)(void); /* Breakpoint routine. */ + unsigned long dtable_base; /* Base addr of dbg table. */ + int (*printf)(const char *fmt, ...); + unsigned long btable_base; /* Breakpoint table. */ + unsigned long mpflushreqs; /* SMP cache flush request list. */ + unsigned long ntab; /* Name table. */ + unsigned long stab; /* Symbol table. */ + int smax; /* Max # of symbols. */ +}; + +#endif + +#endif /* !(_MIPS_SGIARCS_H) */ diff --git a/kernel/include/mips/smp.h b/kernel/include/mips/smp.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/include/mips/sync.h b/kernel/include/mips/sync.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/include/mips/syscalls.h b/kernel/include/mips/syscalls.h new file mode 100644 index 0000000..60129c9 --- /dev/null +++ b/kernel/include/mips/syscalls.h @@ -0,0 +1,106 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/syscalls.h + * Description: System call return wrappers for MIPS. + * + * @LICENSE@ + * + * $Id: syscalls.h,v 1.3 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_SYSCALLS_H__ +#define __MIPS_SYSCALLS_H__ + +#include + +void sys_lthread_ex_regs(l4_threadid_t tid, dword_t uip, dword_t usp, l4_threadid_t pager) __attribute__((noreturn));// __attribute__((regparm(3))); + +#if 1 +#define return_lthread_ex_regs(_uip, _usp, _pager, _tid, _flags) +#define return_create_thread() +#define return_thread_switch() +#define return_ipc(_error) +#define return_ipc_args(_from, _error, _myself) +#define return_id_nearest(_tid, _type) +#define return_task_new(_newtask) +#define return_thread_schedule(_oldparam) +#else +#define return_lthread_ex_regs(_uip, _usp, _pager, _tid, _flags)\ +{ \ + asm("/* load values into regs */\n" \ + "movl %0, %%esp\n" \ + "iret\n" \ + : \ + : "r"(&pager + 1), "a"(_flags), "c"(_usp), "d"(_uip), "S"(_pager));\ + while(1); \ +} + +#define return_create_thread() \ +{ \ + asm("movl %0, %%esp\n" \ + "iret\n" \ + : \ + : "r"(&usp + 1)); \ + while(1); \ +} + +#define return_thread_switch() \ +{ \ + asm("movl %0, %%esp\n" \ + "iret\n" \ + : \ + : "r"(&tid + 1)); \ + while(1); \ +} + +/* does not load argument into registers */ +#define return_ipc(_error) \ +{ \ + asm("movl %0, %%esp\n" \ + "ret\n" \ + : \ + : "r"(&dest - 1), "a"(_error)); \ + while(1); \ +} + +/* loads the arguments into registers */ +#define return_ipc_args(_from, _error, _myself) \ +{ \ + asm("movl %0, %%esp\n" \ + "movl 8(%%edx), %%ecx\n" \ + "movl 4(%%edx), %%ebx\n" \ + "movl 0(%%edx), %%edx\n" \ + "ret\n" \ + : \ + : "r"(&dest - 1), "S"(_from), \ + "a"(current->msg_desc | _error), "d"(_myself)); \ + while(1); \ +} +#endif + + +INLINE void do_pagefault_ipc(tcb_t * current, dword_t fault, dword_t ip) +{ + current->ipc_buffer[0] = fault & ~3; + current->ipc_buffer[1] = ip; + current->ipc_buffer[2] = 0; + current->ipc_buffer[3] = 0; +#if 0 + __asm__ __volatile__ ("pushl %%ebp\n" + "pushl %0\n" /* rcv fpage */ + "pushl $0\n" /* reg send */ + "pushl %1\n" /* dest */ + "call sys_ipc__FG13l4_threadid_tUiUi\n" + "addl $12, %%esp\n" + "popl %%ebp\n" + : + : "i"(IPC_PAGEFAULT_DOPE), "r"(current->pager) + : "eax", "ebx", "ecx", "edx", "esi", "edi", "memory" + ); +#endif +} + +#endif + diff --git a/kernel/include/mips/tcb.h b/kernel/include/mips/tcb.h new file mode 100644 index 0000000..b29ddd7 --- /dev/null +++ b/kernel/include/mips/tcb.h @@ -0,0 +1,19 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mips/tcb.h + * Description: MIPS specific part of TCB. + * + * @LICENSE@ + * + * $Id: tcb.h,v 1.4 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS__TCB_H__ +#define __MIPS__TCB_H__ + +typedef struct { +} tcb_priv_t; + +#endif /* __MIPS__TCB_H__ */ diff --git a/kernel/include/mips/thread.h b/kernel/include/mips/thread.h new file mode 100644 index 0000000..5b69151 --- /dev/null +++ b/kernel/include/mips/thread.h @@ -0,0 +1,184 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/thread.h + * Description: MIPS thread switch code and inline functions for + * manipulating user stack frame. + * + * @LICENSE@ + * + * $Id: thread.h,v 1.7 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __MIPS_THREAD_H__ +#define __MIPS_THREAD_H__ + +#include INC_ARCH(config.h) +#include INC_ARCH(cpu.h) + +/* defined in mips/memory.c */ +extern dword_t * current_page_table; +extern dword_t * current_stack; + +INLINE +tcb_t * get_current_tcb() +{ + tcb_t * tmp; + __asm__ __volatile__ ( + "move %0, $sp \n" + "srl %0, %0, %1 \n" + "sll %0, %0, %1 \n" + : "=r"(tmp) + : "i"(L4_NUMBITS_TCBS)); + return (tmp); +} + + +INLINE +ptr_t get_tcb_stack_top(tcb_t *tcb) +{ + return ptr_t (((dword_t)tcb) + L4_TOTAL_TCB_SIZE - 4); +} + +INLINE +void tcb_stack_push(tcb_t *tcb, dword_t value) +{ + *(--(tcb->stack)) = value; +} + +#define USER_STATUS (0x10) + +INLINE void create_user_stack_frame(tcb_t *tcb, dword_t usp, dword_t uip, void* entry, void* param) +{ + tcb->stack = get_tcb_stack_top(tcb); + tcb_stack_push(tcb, usp); + tcb_stack_push(tcb, USER_STATUS); + tcb_stack_push(tcb, uip); + tcb_stack_push(tcb, (dword_t)param); + tcb_stack_push(tcb, (dword_t)entry); +} + +INLINE tcb_t* tid_to_tcb(l4_threadid_t tid) +{ + return (tcb_t*)((tid.id.thread << L4_NUMBITS_TCBS) + TCB_AREA); +} + +INLINE tcb_t *ptr_to_tcb(ptr_t ptr) +{ + return (tcb_t *) ((dword_t) ptr & L4_TCB_MASK); +} + +INLINE void allocate_tcb(tcb_t *tcb) +{ + tcb->scratch = 0; +} + +INLINE void switch_to_initial_thread(tcb_t * tcb) +{ + __asm__ __volatile__ ( + "move $sp, %0 \n" + "lw $31, ($sp) \n" + "addiu $sp, $sp, 4 \n" + "jr $31 \n" + : + : "r"(tcb->stack) + ); +} + +INLINE void switch_to_thread(tcb_t * tcb, tcb_t * current) +{ + /* modify stack in tss */ + current_stack = get_tcb_stack_top(tcb); + __asm__ __volatile__ ( + "addiu $sp, -16 \n" + "sw $25, 0($sp) \n" + "sw $28, 4($sp) \n" + "sw $30, 8($sp) \n" + "sw $31, 12($sp) \n" + "addiu $sp, -4 \n" + "jal 1f \n" + " nop \n" + "b 3f \n" + " nop \n" + "1:sw $31, 0($sp) \n" + "sw $sp, 0(%0) \n" + "move $sp, %1 \n" + "/* switch pagetable */ \n" + "sw %2, 0(%3) \n" + "lw $31, 0($sp) \n" + "addiu $sp, 4 \n" + "jr $31 \n" + " nop \n" + "3: \n" + "lw $31, 12($sp) \n" + "lw $30, 8($sp) \n" + "lw $28, 4($sp) \n" + "lw $25, 0($sp) \n" + "addiu $sp, 16 \n" + : + : "r" (¤t->stack), "r"(tcb->stack), "r"(tcb->page_dir), + "r"(¤t_page_table) + : +#if 0 + : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", + "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", +#else + "memory"); +#endif +} + +INLINE void switch_to_idle(tcb_t * current) +{ + __asm__ __volatile__ ( + "addiu $sp, -16 \n" + "sw $25, 0($sp) \n" + "sw $28, 4($sp) \n" + "sw $30, 8($sp) \n" + "sw $31, 12($sp) \n" + "addiu $sp, -4 \n" + "jal 1f \n" + " nop \n" + "b 3f \n" + " nop \n" + "1:sw $31, 0($sp) \n" + "sw $sp, 0(%0) \n" + "move $sp, %1 \n" + "lw $31, 0($sp) \n" + "addiu $sp, 4 \n" + "jr $31 \n" + " nop \n" + "3: \n" + "lw $31, 12($sp) \n" + "lw $30, 8($sp) \n" + "lw $28, 4($sp) \n" + "lw $25, 0($sp) \n" + "addiu $sp, 16 \n" + : + : "r" (¤t->stack), "r"(get_idle_tcb()->stack) + : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", + "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "memory"); +} + + +INLINE dword_t tcb_exist(tcb_t * tcb) +{ + return (tcb->myself.raw); +} + + +#define UIP(tcb) (get_tcb_stack_top(tcb)[-2]) +#define USP(tcb) (get_tcb_stack_top(tcb)[-5]) +#define UFL(tcb) (get_tcb_stack_top(tcb)[-3]) + +INLINE dword_t get_user_ip(tcb_t* tcb) { return UIP(tcb); } +INLINE dword_t get_user_sp(tcb_t* tcb) { return USP(tcb); } +INLINE dword_t get_user_flags(tcb_t* tcb) { return UFL(tcb); } +INLINE dword_t set_user_ip(tcb_t* tcb, dword_t val) return old; { old = UIP(tcb); UIP(tcb) = val; } +INLINE dword_t set_user_sp(tcb_t* tcb, dword_t val) return old; { old = USP(tcb); USP(tcb) = val; } +INLINE dword_t set_user_flags(tcb_t* tcb, dword_t val) return old; { old = UFL(tcb); UFL(tcb) = val; } + + +#endif /* __MIPS_THREAD_H__ */ diff --git a/kernel/include/schedule.h b/kernel/include/schedule.h new file mode 100644 index 0000000..6ee9ae4 --- /dev/null +++ b/kernel/include/schedule.h @@ -0,0 +1,191 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: schedule.h + * Description: Inline functions and declarations dealing with + * sceduling. + * + * @LICENSE@ + * + * $Id: schedule.h,v 1.20 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __SCHEDULE_H__ +#define __SCHEDULE_H__ + +#include INC_ARCH(notify.h) +#include + +#define MAX_PRIO 255 + +extern notify_procedure(initialize_idle_thread); + +/* priority queue */ +extern tcb_t * prio_queue[]; +extern int current_max_prio; + +/* +** ready queue handling +*/ + +INLINE void thread_enqueue_ready(tcb_t * tcb) +{ + if (!(tcb->queue_state & TS_QUEUE_READY)) + { + int prio = tcb->priority; + if (prio_queue[prio]) + { + tcb_t *tmp = prio_queue[prio]; + tcb->ready_next = tmp; + tcb->ready_prev = tmp->ready_prev; + tcb->ready_prev->ready_next = tcb; + tmp->ready_prev = tcb; + } + else { + tcb->ready_next = tcb->ready_prev = tcb; + prio_queue[prio] = tcb; + } + tcb->queue_state |= TS_QUEUE_READY; + if (current_max_prio < prio) current_max_prio = prio; + } +} + +INLINE void thread_dequeue_ready(tcb_t * tcb) +{ + if (tcb->queue_state & TS_QUEUE_READY) + { + if (tcb->ready_next == tcb) { + prio_queue[tcb->priority] = NULL; +#ifdef CONFIG_DEBUG_SANITY + tcb->ready_next = tcb->ready_prev = NULL; +#endif + } + else { + if (prio_queue[tcb->priority] == tcb) + prio_queue[tcb->priority] = tcb->ready_next; + tcb->ready_prev->ready_next = tcb->ready_next; + tcb->ready_next->ready_prev = tcb->ready_prev; +#ifdef CONFIG_DEBUG_SANITY + tcb->ready_next = tcb->ready_prev = NULL; +#endif + } + tcb->queue_state &= ~TS_QUEUE_READY; + } +} + + +/* + * wakup queue + */ +INLINE void thread_enqueue_wakeup(tcb_t * tcb) +{ + if (!(tcb->queue_state & TS_QUEUE_WAKEUP)) + { + tcb_t * tmp = get_idle_tcb(); + tcb->wakeup_next = tmp->wakeup_next; + tmp->wakeup_next = tcb; + tcb->wakeup_prev = tmp; + tcb->wakeup_next->wakeup_prev = tcb; + tcb->queue_state |= TS_QUEUE_WAKEUP; + } +} + +INLINE void thread_dequeue_wakeup(tcb_t * tcb) +{ + if (tcb->queue_state & TS_QUEUE_WAKEUP) + { + tcb->wakeup_next->wakeup_prev = tcb->wakeup_prev; + tcb->wakeup_prev->wakeup_next = tcb->wakeup_next; +#ifdef CONFIG_DEBUG_SANITY + tcb->wakeup_next = tcb->wakeup_prev = NULL; +#endif + tcb->queue_state &= ~TS_QUEUE_WAKEUP; + } +} + + +/* + * send queue handling + */ +INLINE void thread_enqueue_send(tcb_t * dest, tcb_t * from) +{ + if (!dest->send_queue) + { + dest->send_queue = from; + from->send_next = from->send_prev = from; + } + else + { + tcb_t * first = dest->send_queue; + from->send_prev = first->send_prev; + from->send_next = first; + first->send_prev = from; + from->send_prev->send_next = from; + } +} + +INLINE tcb_t * thread_dequeue_send(tcb_t * dest, tcb_t * tcb) +{ + if (tcb->send_next == tcb) + { + /* we are the only one :-) */ + dest->send_queue = NULL; + +#ifdef CONFIG_DEBUG_SANITY + /* and sanity for debugging */ + tcb->send_next = tcb->send_prev = NULL; +#endif + } + else + { + if (dest->send_queue == tcb) + dest->send_queue = tcb->send_next; + + tcb->send_prev->send_next = tcb->send_next; + tcb->send_next->send_prev = tcb->send_prev; + +#ifdef CONFIG_DEBUG_SANITY + /* and sanity for debugging */ + tcb->send_next = tcb->send_prev = NULL; +#endif + } + + /* coding convenience */ + return tcb; +} + + +/* + * scheduler specific functions + */ + +typedef union { + struct { + unsigned prio : 8; + unsigned small_as : 8; + unsigned cpu : 4; + unsigned time_exp : 4; + unsigned time_man : 8; + } param; + dword_t raw; +} schedule_param_t; +#define INVALID_SCHED_PARAM ((schedule_param_t){raw:0xffffffff}) + +tcb_t * find_next_thread(); + +void dispatch_thread(tcb_t * tcb); + +tcb_t * parse_wakeup_queue(dword_t current_prio, qword_t current_time); + +/* + * time + */ + +INLINE qword_t get_current_time() +{ + return kernel_info_page.clock; +} + + +#endif /* __SCHEDULE_H__ */ diff --git a/kernel/include/sync.h b/kernel/include/sync.h new file mode 100644 index 0000000..3dfd209 --- /dev/null +++ b/kernel/include/sync.h @@ -0,0 +1,37 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: sync.h + * Description: Basic definitions for synchronization needed for SMP + * systemss (null-stubs if not used in an SMP + * environment). + * + * @LICENSE@ + * + * $Id: sync.h,v 1.3 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __SYNC_H__ +#define __SYNC_H__ + + +#ifndef CONFIG_SMP + +#define DEFINE_SPINLOCK(name) +#define spin_lock_init(x) do { } while(0) +#define spin_lock(x) do { } while(0) +#define spin_unlock(x) do { } while(0) + +#else /* CONFIG_SMP */ +/* + * for smp we need a platform specific file + * herewith we avoid rewriting empty spinlocks + * for each new platform again and again and again. + */ + +#include INC_ARCH(sync.h) + +#endif /* CONFIG_SMP */ + +#endif diff --git a/kernel/include/tcb.h b/kernel/include/tcb.h new file mode 100644 index 0000000..443d032 --- /dev/null +++ b/kernel/include/tcb.h @@ -0,0 +1,307 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: tcb.h + * Description: The Thread Control Block structure. + * + * @LICENSE@ + * + * $Id: tcb.h,v 1.16 2002/05/29 15:51:54 ud3 Exp $ + * + ********************************************************************/ +#ifndef __TCB_H__ +#define __TCB_H__ + + +#include INC_ARCH(tcb.h) + +#if defined(CONFIG_SMP) +# include INC_ARCH(sync.h) +#endif + +/* From */ +class space_t; + + +/* + + Thread Control Block (TCB) + + A TCB contains the state of a thread. However this is true for all but + the currently executing threads. + Every thread has its own kernel stack located behind the TCB. Most people + use the term TCB for the combination of both the TCB data structure and + the associated kernel stack. + +*/ + +typedef struct tcb_t { +/* TCB_START_MARKER - do NOT delete */ + dword_t ipc_buffer[3]; + timeout_t ipc_timeout; + dword_t msg_desc; + + /* don't touch above - hard coded in asm!!! */ + + /* + * Task state. + */ + space_t *space; + dword_t *pagedir_cache; + + /* + * Thread state. + */ + l4_threadid_t myself; + l4_threadid_t pager; + dword_t excpt; + ptr_t stack; + dword_t thread_state; + dword_t queue_state; + dword_t priority; + dword_t flags; + + sdword_t timeslice; + sdword_t current_timeslice; + qword_t absolute_timeout; + + /* + * Kernel links. + */ + tcb_t *present_prev; + tcb_t *present_next; + tcb_t *ready_prev; + tcb_t *ready_next; + + /* + * Wakeup queues + */ + tcb_t *wakeup_prev; + tcb_t *wakeup_next; + + /* + * resource management + */ + dword_t resources; + dword_t copy_area1; + dword_t copy_area2; + + /* + * ipc links + */ + tcb_t *send_queue; + tcb_t *send_prev; + tcb_t *send_next; + l4_threadid_t partner; + + /* + * interrupts + */ + dword_t intr_pending; + + /* + * + */ + ptr_t unwind_ipc_sp; + +#if defined(CONFIG_SMP) + /* + * SMP cpu ownership/control + */ + dword_t cpu; + spinlock_t tcb_spinlock; +#endif + + /* + * This field is not evaluated -> it can be written + * f.i. to force a write-pgfault in allocate_tcb + */ + dword_t scratch; + + /* + * TCB magic number (easy to check stack overrun). + */ + dword_t magic; + + /* + * Architecture-defined layout + */ + tcb_priv_t priv[0] __attribute__((aligned(16))); + +/* TCB_END_MARKER - do NOT delete */ +} tcb_t; + +typedef union { + tcb_t tcb __attribute__((aligned(L4_TOTAL_TCB_SIZE))); + char pad[L4_TOTAL_TCB_SIZE]; +} whole_tcb_t __attribute__((aligned(L4_TOTAL_TCB_SIZE))); + + +#define TCB_MAGIC 0x3F594857 + +/* The offset from the start of the tcb to the scratch field. */ +#define TCB_SCRATCH_OFFSET ({tcb_t *t; ((dword_t) &t->scratch - (dword_t) t);}) + + + + + + +/* the bit fields for thread states */ +#define TSB_READY 0x01 +#define TSB_POLLING 0x02 +#define TSB_LOCKED 0x04 + +/* + * Thread states use negative logic -> eases testing on x86 + */ + +#if !defined(CONFIG_SMP) + +/* Running. Present in ready-queue and ready to be scheduled. */ +#define TS_RUNNING (TSB_LOCKED | TSB_POLLING ) + +/* Sending, waiting for partner to receive my message. */ +#define TS_POLLING (TSB_LOCKED | TSB_READY) + +/* found someone to send me a message */ +#define TS_LOCKED_WAITING ( TSB_POLLING | TSB_READY) + +/* Running, sending or receiving a message. */ +#define TS_LOCKED_RUNNING ( TSB_POLLING ) + +/* dead */ +#define TS_ABORTED (TSB_LOCKED | TSB_POLLING | TSB_READY) + +/* waiting for someone to send me a message */ +#define TS_WAITING (~0U) + +#else /* CONFIG_SMP */ + +#define TSB_XCPU 0x08 + +#define TS_RUNNING (TSB_XCPU | TSB_LOCKED | TSB_POLLING ) +#define TS_POLLING (TSB_XCPU | TSB_LOCKED | TSB_READY) +#define TS_LOCKED_WAITING (TSB_XCPU | TSB_POLLING | TSB_READY) +#define TS_LOCKED_RUNNING (TSB_XCPU | TSB_POLLING ) +#define TS_ABORTED (TSB_XCPU | TSB_LOCKED | TSB_POLLING | TSB_READY) +#define TS_XCPU_LOCKED_WAITING ( TSB_POLLING | TSB_READY) +#define TS_XCPU_LOCKED_RUNNING ( TSB_POLLING ) +#define TS_WAITING (~0U) + +#endif /* CONFIG_SMP */ + +/* macros for checking thread states in IPC */ +#define IS_WAITING(x) (!(~((x)->thread_state))) +#define IS_POLLING(x) (!((x)->thread_state & ~TS_POLLING)) +#define IS_RUNNING(x) (!((x)->thread_state & ~TS_RUNNING)) + + + + + +/* Queue membership - these are the bits in the queue_state member of a TCB. + A set bit indicates that the TCB is in the respective queue, i.e. its + member pointers for this queue are valid */ +#define TS_QUEUE_READY 0x01 +#define TS_QUEUE_PRESENT 0x02 +#define TS_QUEUE_WAKEUP 0x04 +#define TS_QUEUE_SEND 0x08 + + + + +/* + * Resource bits for resources that threads can use. + */ + +void save_resources(tcb_t *current, tcb_t *dest); +void load_resources(tcb_t *current); + +void init_resources(tcb_t * tcb); +void free_resources(tcb_t * tcb); +void purge_resources(tcb_t * tcb); + +#define TR_IPC_MEM1 (1 << 0) +#define TR_IPC_MEM2 (1 << 1) +#define TR_IPC_MEM (TR_IPC_MEM1|TR_IPC_MEM2) +#define TR_FPU (1 << 2) +#define TR_LONG_IPC_PTAB (1 << 3) +#define TR_DEBUG_REGS (1 << 4) + +#if defined(CONFIG_ENABLE_PVI) +#define TR_PVI (1 << 5) +#endif + +#define COPYAREA_INVALID ((dword_t)~0) + + +/* Various thread flags. */ +#define TF_SENDING_IPC 0x01 /* Set during IPC send phase. */ + + +/* some globally used TCBs */ +extern whole_tcb_t __idle_tcb; +extern tcb_t * sigma0; + + + + +/* check, whether the threads belonging to two TCBs are in the same + address space by comparing the MMU translation table pointers */ +INLINE int same_address_space(tcb_t * tcb1, tcb_t * tcb2) +{ + return (tcb1->space == tcb2->space); +} + + + +/* + * idle tcb stuff + */ +INLINE tcb_t * get_idle_tcb() { + return &__idle_tcb.tcb; +}; + + + +/* + Present List Handling + + The present list contains all existing TCBs in a doubly linked list. + Initially, only the idle_tcb is in the present list. Newly created TCBs + are added. There is a present list per CPU. +*/ + +/* enqueue the TCB in the present list */ +INLINE void thread_enqueue_present(tcb_t * tcb) +{ + /* check if not already in the list */ + if (!(tcb->queue_state & TS_QUEUE_PRESENT)) + { + /* add the TCB next to the idle_tcb */ + tcb_t * idle = get_idle_tcb(); + + tcb->present_prev = idle; + tcb->present_next = idle->present_next; + idle->present_next = tcb; + tcb->present_next->present_prev = tcb; + + tcb->queue_state |= TS_QUEUE_PRESENT; + } +} + +INLINE void thread_dequeue_present(tcb_t * tcb) +{ + if (tcb->queue_state & TS_QUEUE_PRESENT) + { + tcb->present_prev->present_next = tcb->present_next; + tcb->present_next->present_prev = tcb->present_prev; + tcb->queue_state &= ~TS_QUEUE_PRESENT; + } +} + + + +#endif /* __TCB_H__ */ diff --git a/kernel/include/tcb_layout.h b/kernel/include/tcb_layout.h new file mode 100644 index 0000000..3a7dd84 --- /dev/null +++ b/kernel/include/tcb_layout.h @@ -0,0 +1,40 @@ +/* machine-generated file - do NOT edit */ +#ifndef __TCB_LAYOUT__H__ +#define __TCB_LAYOUT__H__ + +#define OFS_TCB_IPC_BUFFER 0x00 /* 0 */ +#define OFS_TCB_IPC_TIMEOUT 0x0c /* 12 */ +#define OFS_TCB_MSG_DESC 0x10 /* 16 */ +#define OFS_TCB_SPACE 0x14 /* 20 */ +#define OFS_TCB_PAGEDIR_CACHE 0x18 /* 24 */ +#define OFS_TCB_MYSELF 0x1c /* 28 */ +#define OFS_TCB_PAGER 0x20 /* 32 */ +#define OFS_TCB_EXCPT 0x24 /* 36 */ +#define OFS_TCB_STACK 0x28 /* 40 */ +#define OFS_TCB_THREAD_STATE 0x2c /* 44 */ +#define OFS_TCB_QUEUE_STATE 0x30 /* 48 */ +#define OFS_TCB_PRIORITY 0x34 /* 52 */ +#define OFS_TCB_FLAGS 0x38 /* 56 */ +#define OFS_TCB_TIMESLICE 0x3c /* 60 */ +#define OFS_TCB_CURRENT_TIMESLICE 0x40 /* 64 */ +#define OFS_TCB_ABSOLUTE_TIMEOUT 0x44 /* 68 */ +#define OFS_TCB_PRESENT_PREV 0x4c /* 76 */ +#define OFS_TCB_PRESENT_NEXT 0x50 /* 80 */ +#define OFS_TCB_READY_PREV 0x54 /* 84 */ +#define OFS_TCB_READY_NEXT 0x58 /* 88 */ +#define OFS_TCB_WAKEUP_PREV 0x5c /* 92 */ +#define OFS_TCB_WAKEUP_NEXT 0x60 /* 96 */ +#define OFS_TCB_RESOURCES 0x64 /* 100 */ +#define OFS_TCB_COPY_AREA1 0x68 /* 104 */ +#define OFS_TCB_COPY_AREA2 0x6c /* 108 */ +#define OFS_TCB_SEND_QUEUE 0x70 /* 112 */ +#define OFS_TCB_SEND_PREV 0x74 /* 116 */ +#define OFS_TCB_SEND_NEXT 0x78 /* 120 */ +#define OFS_TCB_PARTNER 0x7c /* 124 */ +#define OFS_TCB_INTR_PENDING 0x80 /* 128 */ +#define OFS_TCB_UNWIND_IPC_SP 0x84 /* 132 */ +#define OFS_TCB_SCRATCH 0x88 /* 136 */ +#define OFS_TCB_MAGIC 0x8c /* 140 */ +#define OFS_TCB_PRIV 0x90 /* 144 */ + +#endif /* __TCB_LAYOUT__H__ */ diff --git a/kernel/include/thread.h b/kernel/include/thread.h new file mode 100644 index 0000000..189287d --- /dev/null +++ b/kernel/include/thread.h @@ -0,0 +1,151 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: thread.h + * Description: Definitions of thread IDs and functions operating on + * threads. + * + * @LICENSE@ + * + * $Id: thread.h,v 1.58 2001/12/04 16:55:46 uhlig Exp $ + * + ********************************************************************/ +#ifndef __THREAD_H__ +#define __THREAD_H__ + + +#define L4_X0_VERSION_BITS 10 +#define L4_X0_THREADID_BITS 6 +#define L4_X0_TASKID_BITS 8 + +typedef union { + struct { + unsigned version : L4_X0_VERSION_BITS; + unsigned thread : (L4_X0_THREADID_BITS + L4_X0_TASKID_BITS); + unsigned chief : L4_X0_TASKID_BITS; + } id; + + struct { + unsigned version : L4_X0_VERSION_BITS; + unsigned thread : L4_X0_THREADID_BITS; + unsigned task : L4_X0_TASKID_BITS; + unsigned chief : L4_X0_TASKID_BITS; + } x0id; + + dword_t raw; +} l4_threadid_t; + +/* + * Some well known thread id's. + */ +#define L4_KERNEL_ID ((l4_threadid_t) { x0id : {0,1,0,0} }) +#define L4_SIGMA0_ID ((l4_threadid_t) { x0id : {1,0,2,4} }) +#define L4_ROOT_TASK_ID ((l4_threadid_t) { x0id : {1,0,4,4} }) +#define L4_GRABKMEM_ID L4_KERNEL_ID + +/* + * be carefull - this has some context + * interrupt-ids are always checked *AFTER* IS_KERNEL_ID + * but makes sense for performance reasons + */ +#define IS_KERNEL_ID(x) (x.x0id.task == 0) +#define IS_INTERRUPT_ID(x) (x.raw) +#define INTERRUPT_ID(x) (x.raw - 1) + + +#define L4_NIL_ID ((l4_threadid_t) { raw : 0x00000000 }) +#define L4_INVALID_ID ((l4_threadid_t) { raw : 0xffffffff }) + +#define l4_is_nil_id(id) ((id).raw == L4_NIL_ID.raw) +#define l4_is_invalid_id(id) ((id).raw == L4_INVALID_ID.raw) + +static inline int operator == (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw == t2.raw; +} + +static inline int operator != (const l4_threadid_t & t1, + const l4_threadid_t & t2) +{ + return t1.raw != t2.raw; +} + + +INLINE dword_t threadnum(tcb_t *tcb) +{ + return ((dword_t) tcb >> L4_NUMBITS_TCBS) & + ((1 << L4_X0_THREADID_BITS) - 1); +} + +INLINE dword_t tasknum(tcb_t *tcb) +{ + return ((dword_t) tcb >> (L4_NUMBITS_TCBS + L4_X0_THREADID_BITS)) & + ((1 << L4_X0_TASKID_BITS) - 1); +} + + +void unwind_ipc(tcb_t *tcb); + +/* several ways of returning to the user */ +extern void abort_ipc(); +extern void switch_to_user(); + +class space_t; +space_t * create_space (void); +void delete_space (space_t * space); + + +#if defined(CONFIG_ENABLE_SWITCH_TRACE) + +typedef struct { + dword_t f_uip; + dword_t f_usp; + dword_t t_uip; + dword_t t_usp; + tcb_t *t_tcb; +} switch_trace_t; + +enum switch_trace_type_t { + SWTRACE_NONE, + SWTRACE_ALL, + SWTRACE_TASK, + SWTRACE_THREAD +}; + +extern switch_trace_type_t kdebug_switch_trace_type; +extern switch_trace_t kdebug_switch_trace[]; +extern dword_t kdebug_switch_trace_idx; +extern tcb_t *kdebug_switch_trace_id; + +#define TRACE_THREAD_SWITCH(from, to) \ +do { \ + if ((kdebug_switch_trace_type == SWTRACE_NONE) \ + || (kdebug_switch_trace_type == SWTRACE_TASK && \ + tasknum (from) != tasknum (kdebug_switch_trace_id) && \ + tasknum (to) != tasknum (kdebug_switch_trace_id)) \ + || (kdebug_switch_trace_type == SWTRACE_THREAD && \ + from != kdebug_switch_trace_id && \ + to != kdebug_switch_trace_id)) \ + break; \ + \ + switch_trace_t *st = kdebug_switch_trace + kdebug_switch_trace_idx; \ + st->f_uip = get_user_ip (from); \ + st->f_usp = get_user_sp (from); \ + st->t_uip = get_user_ip (to); \ + st->t_usp = get_user_sp (to); \ + st->t_tcb = to; \ + \ + if (++kdebug_switch_trace_idx == CONFIG_SWITCH_TRACE_SIZE) \ + kdebug_switch_trace_idx = 0; \ +} while (0) + +#else /* !CONFIG_ENABLE_SWITCH_TRACE */ +#define TRACE_THREAD_SWITCH(from, to) +#endif + + +#endif /* __THREAD_H__ */ + + diff --git a/kernel/include/tracebuffer.h b/kernel/include/tracebuffer.h new file mode 100644 index 0000000..14e8338 --- /dev/null +++ b/kernel/include/tracebuffer.h @@ -0,0 +1,26 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: tracebuffer.h + * Description: Macros recording tracebuffer events. + * + * @LICENSE@ + * + * $Id: tracebuffer.h,v 1.2 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __TRACEBUFFER_H__ +#define __TRACEBUFFER_H__ + +#if defined(CONFIG_TRACEBUFFER) +#include INC_ARCH(tracebuffer.h) +#else +#define TBUF_RECORD_EVENT(_a) +#define TBUF_RECORD_EVENT_AND_PAR(_a, _p0) +#define TBUF_RECORD_EVENT_AND_TWO_PAR(_a, _p0, _p1) +#define TBUF_INCREMENT_TRACE_COUNTER() +#define TBUF_CLEAR_BUFFER() +#endif + +#endif /* __TRACEBUFFER_H__ */ diff --git a/kernel/include/tracepoint_list.h b/kernel/include/tracepoint_list.h new file mode 100644 index 0000000..c4d2166 --- /dev/null +++ b/kernel/include/tracepoint_list.h @@ -0,0 +1,62 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: tracepoint_list.h + * Description: List of available kernel tracepoints. + * + * @LICENSE@ + * + * $Id: tracepoint_list.h,v 1.13 2002/05/13 13:04:29 stoess Exp $ + * + ********************************************************************/ +#if defined(DEFINE_TP) + +DEFINE_TP(SYS_IPC, "sys_ipc(src=%x, dest=%x)") +DEFINE_TP(SYS_SCHEDULE, "sys_schedule") +DEFINE_TP(SYS_THREAD_SWITCH, "sys_thread_switch(dest=%x)") +DEFINE_TP(SYS_LTHREAD_EX_REGS, "sys_lthread_ex_regs") +DEFINE_TP(SYS_TASK_NEW, "sys_task_new(tid=%x, pager=%x)") +DEFINE_TP(SYS_ID_NEAREST, "sys_id_nearest(tid=%x, uip=%x)") +DEFINE_TP(SYS_FPAGE_UNMAP, "sys_fpage_unmap(fpage=%x, mask=%x)") + +DEFINE_TP(SET_PRIO, "set_prio") +DEFINE_TP(GET_KERNEL_VERSION, "get_kernel_version") +DEFINE_TP(EXTENDED_TRANSFER, "extended_transfer") +DEFINE_TP(LONG_SEND_IPC, "long_send_ipc") +DEFINE_TP(LONG_LONG_IPC, "long_long_ipc") +DEFINE_TP(KERNEL_USER_PF, "kernel_user_pf(fault=%x, ip=%x)") +DEFINE_TP(STRING_COPY_IPC, "string_copy_ipc") +DEFINE_TP(STRING_COPY_PF, "string_copy_pf") +DEFINE_TP(UNWIND_IPC, "unwind_ipc") +DEFINE_TP(SAVE_RESOURCES, "save_resources") +DEFINE_TP(LOAD_RESOURCES, "load_resources") +DEFINE_TP(PURGE_RESOURCES, "purge_resources") +DEFINE_TP(SWITCH_TO_IDLE, "switch_to_idle") +DEFINE_TP(HANDLE_TIMER_INTERRUPT, "handle_timer_interrupt") + +#if defined(CONFIG_ARCH_X86) +DEFINE_TP(IDT_FAULT, "idt_fault") +DEFINE_TP(FPU_VIRTUALIZATION, "fpu_virtualization") +DEFINE_TP(SEGREG_RELOAD, "segreg_reload") +DEFINE_TP(KDB_OPERATION, "kdb_operation") +DEFINE_TP(INTERRUPT, "interrupt(#%d)") +DEFINE_TP(INSTRUCTION_EMULATION,"instruction_emulation") +#endif + +DEFINE_TP(SYNC_TCB_AREA, "sync_tcb_ares") +DEFINE_TP(MAP_NEW_TCB, "map_new_tcb") +DEFINE_TP(MAP_ZERO_PAGE, "map_zero_page") + +#if defined(CONFIG_ENABLE_SMALL_AS) +DEFINE_TP(SET_SMALL_SPACE, "set_small_space") +DEFINE_TP(SET_SMALL_SPACE_FAILED,"set_small_space_failed") +DEFINE_TP(ENLARGE_SPACE, "enlarge_space") +DEFINE_TP(RESTART_IPC, "restart_ipc") +DEFINE_TP(SMALL_SPACE_RECEIVER, "small_space_receiver") +DEFINE_TP(SMALL_SPACE_SENDER, "small_space_sender") +DEFINE_TP(COPY_SMALL_PDIRENT, "copy_small_pdirent") +#endif + + +#endif /* DEFINE_TP */ diff --git a/kernel/include/tracepoints.h b/kernel/include/tracepoints.h new file mode 100644 index 0000000..92c82b9 --- /dev/null +++ b/kernel/include/tracepoints.h @@ -0,0 +1,141 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: tracepoints.h + * Description: Kernel Tracepoint definitions. + * + * @LICENSE@ + * + * $Id: tracepoints.h,v 1.5 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __TRACEPOINTS_H__ +#define __TRACEPOINTS_H__ + +#include + + +/* + * Create an enum list of all tracepoints. + */ + +#define DEFINE_TP(x, str) TP_##x, +enum tracepoint_t { + TP_INVALID = 0, +# include + TP_MAX +}; +#undef DEFINE_TP + + +#if defined(CONFIG_ENABLE_TRACEPOINTS) + + +/* + * First argument to TRACEPOINT() should be the tracepoint name. + * Second argument (if present) is code to be executed before kdebug + * is (possibly) entered. + */ + +#define TRACEPOINT(x, code...) \ +do { \ + TBUF_RECORD_EVENT (TP_##x); \ + tracepoint_cnt[TP_##x]++; \ + if (is_tracepoint_set (TP_##x)) \ + { \ + {code;} \ + if (does_tracepoint_enter_kdb (TP_##x)) \ + enter_kdebug (#x); \ + } \ +} while (0) + +/* + * The following versions of TRACEPOINT() take additional parameters, + * which can be recorded into the tracebuffer. + */ + +#define TRACEPOINT_1PAR(x, par1, code...) \ +do { \ + TBUF_RECORD_EVENT_AND_PAR (TP_##x, par1); \ + tracepoint_cnt[TP_##x]++; \ + if (is_tracepoint_set (TP_##x)) \ + { \ + {code;} \ + if (does_tracepoint_enter_kdb (TP_##x)) \ + enter_kdebug (#x); \ + } \ +} while (0) + +#define TRACEPOINT_2PAR(x, par1, par2, code...) \ +do { \ + TBUF_RECORD_EVENT_AND_TWO_PAR (TP_##x, par1, par2); \ + tracepoint_cnt[TP_##x]++; \ + if (is_tracepoint_set (TP_##x)) \ + { \ + {code;} \ + if (does_tracepoint_enter_kdb (TP_##x)) \ + enter_kdebug (#x); \ + } \ +} while (0) + + +extern char *tracepoint_name[]; +extern byte_t tracepoint_is_set[]; +extern byte_t tracepoint_enters_kdb[]; +extern dword_t tracepoint_cnt[]; + + + +/* + * Helper functions. + */ + +INLINE void clr_tracepoint (int num) +{ + tracepoint_is_set[num >> 3] &= ~(1 << (num & 0x7)); + tracepoint_enters_kdb[num >> 3] &= ~(1 << (num & 0x7)); +} + +INLINE void set_tracepoint (int num, int enter_kdb) +{ + tracepoint_is_set[num >> 3] |= 1 << (num & 0x7); + if ( enter_kdb ) + tracepoint_enters_kdb[num >> 3] |= 1 << (num & 0x7); + else + tracepoint_enters_kdb[num >> 3] &= ~(1 << (num & 0x7)); +} + +INLINE int is_tracepoint_set (int num) +{ + return tracepoint_is_set[num >> 3] & (1 << (num & 0x7)); +} + +INLINE int does_tracepoint_enter_kdb (int num) +{ + return tracepoint_enters_kdb[num >> 3] & (1 << (num & 0x7)); +} + + + + +#else /* !CONFIG_ENABLE_TRACEPOINTS */ + +#define TRACEPOINT(x, code...) \ +do { \ + TBUF_RECORD_EVENT (TP_##x); \ +} while (0) + +#define TRACEPOINT_1PAR(x, par1, code...) \ +do { \ + TBUF_RECORD_EVENT_AND_PAR (TP_##x, par1); \ +} while (0) + +#define TRACEPOINT_2PAR(x, par1, par2, code...) \ +do { \ + TBUF_RECORD_EVENT_AND_TWO_PAR (TP_##x, par1, par2); \ +} while (0) + +#endif + +#endif /* !__TRACEPOINTS_H__ */ diff --git a/kernel/include/types.h b/kernel/include/types.h new file mode 100644 index 0000000..eb83597 --- /dev/null +++ b/kernel/include/types.h @@ -0,0 +1,57 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: types.h + * Description: Global type definitions. + * + * @LICENSE@ + * + * $Id: types.h,v 1.9 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __TYPES_H__ +#define __TYPES_H__ + +/* + * standard type definitions + */ +typedef unsigned long long qword_t; +typedef unsigned int dword_t; +typedef unsigned short word_t; +typedef unsigned char byte_t; + +typedef signed long long sqword_t; +typedef signed int sdword_t; +typedef signed short sword_t; +typedef signed char sbyte_t; + +typedef dword_t* ptr_t; + +typedef unsigned long long uint64; +typedef unsigned long uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; +typedef long long int64; +typedef long int32; +typedef short int16; +typedef char int8; + + + +typedef struct tcb_t tcb_t; + + +#ifndef NULL +#define NULL (0) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#endif /* __TYPES_H__ */ diff --git a/kernel/include/universe.h b/kernel/include/universe.h new file mode 100644 index 0000000..eada91d --- /dev/null +++ b/kernel/include/universe.h @@ -0,0 +1,63 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: universe.h + * Description: File including all include files. Using this scheme + * we only need to include a single file. If we touch + * a single include file, however, we need to recompile + * the whole kernel, but since the kernel is small (in + * contrast to, e.g., Linux) we can live with that. + * + * @LICENSE@ + * + * $Id: universe.h,v 1.17 2001/11/22 14:56:35 skoglund Exp $ + * + ********************************************************************/ +#ifndef __UNIVERSE_H__ +#define __UNIVERSE_H__ + +/* the file created by the xconfig tool */ +#include + +#include +#include + +// kip and kernel identification +#include + +/* some of the include files rely on + * architecture specific configuration */ +#include INC_ARCH(config.h) + +#include +#include + +/* some of the macros of the notify mechanism are used to + create function prototypes */ +#include INC_ARCH(notify.h) + +#include +#include +#include +#include +#include +#include + +#include INC_ARCH(cpu.h) +#include INC_ARCH(memory.h) +#include INC_ARCH(thread.h) + + +#if defined(CONFIG_SMP) +# include INC_ARCH(smp.h) +#endif + +#include + +#if defined(CONFIG_DEBUG) +# define ASSERT(x) do { if (!(x)) {printf("ASSERT(%s) failed in %s, file: %s:%d\n", #x, __FUNCTION__, __FILE__, __LINE__); enter_kdebug("ASSERT FAILED"); while(1);} } while (0) +#else +# define ASSERT(x) do { } while (0) +#endif +#endif /* __UNIVERSE_H__ */ diff --git a/kernel/include/x86/apic.h b/kernel/include/x86/apic.h new file mode 100644 index 0000000..435f355 --- /dev/null +++ b/kernel/include/x86/apic.h @@ -0,0 +1,172 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86/apic.h + * Description: Definitions and inlines for the IA-32 Local APIC and + * IO-APIC. + * + * @LICENSE@ + * + * $Id: apic.h,v 1.9 2001/11/22 14:56:36 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86_APIC_H__ +#define __X86_APIC_H__ + + +#define X86_IO_APIC_BASE (0xFEC00000) +#define X86_LOCAL_APIC_BASE (0xFEE00000) +#define X86_APIC_ID 0x020 +#define X86_APIC_VERSION 0x030 +#define X86_APIC_TASK_PRIO 0x080 +#define X86_APIC_ARBITR_PRIO 0x090 +#define X86_APIC_PROC_PRIO 0x0A0 +#define X86_APIC_EOI 0x0B0 +#define X86_APIC_LOCAL_DEST 0x0D0 +#define X86_APIC_DEST_FORMAT 0x0E0 +#define X86_APIC_SVR 0x0F0 +#define X86_APIC_ISR_BASE 0x100 +#define X86_APIC_TMR_BASE 0x180 +#define X86_APIC_IRR_BASE 0x200 +#define X86_APIC_ERR_STATUS 0x280 +#define X86_APIC_INTR_CMD1 0x300 +#define X86_APIC_INTR_CMD2 0x310 +#define X86_APIC_LVT_TIMER 0x320 +#define X86_APIC_PERF_COUNTER 0x340 +#define X86_APIC_LVT_LINT0 0x350 +#define X86_APIC_LVT_LINT1 0x360 +#define X86_APIC_LVT_ERROR 0x370 +#define X86_APIC_TIMER_COUNT 0x380 +#define X86_APIC_TIMER_CURRENT 0x390 +#define X86_APIC_TIMER_DIVIDE 0x3E0 + +/* IOAPIC register ids */ +#define X86_IOAPIC_ID 0x00 +#define X86_IOAPIC_VERSION 0x01 +#define X86_IOAPIC_ARB 0x02 +#define X86_IOAPIC_REDIR0 0x10 + +/* APIC delivery modes */ +#define APIC_DEL_FIXED (0x0) +#define APIC_DEL_LOWESTPRIO (0x1 << 8) +#define APIC_DEL_SMI (0x2 << 8) +#define APIC_DEL_NMI (0x4 << 8) +#define APIC_DEL_INIT (0x5 << 8) +#define APIC_DEL_EXTINT (0x7 << 8) + +#define APIC_TRIGGER_LEVEL (1 << 15) +#define APIC_TRIGGER_EDGE 0 + +#define APIC_ASSERT (1 << 14) +#define APIC_DEASSERT 0 + +#define APIC_IRQ_MASK (1 << 16) + +#define APIC_DEST_PHYS 0x0 +#define APIC_DEST_VIRT 0x1 + +#define IOAPIC_POLARITY_LOW 0x1 +#define IOAPIC_POLARITY_HIGH 0x0 + +#define IOAPIC_TRIGGER_LEVEL 0x1 +#define IOAPIC_TRIGGER_EDGE 0x0 + +#define IOAPIC_IRQ_MASK (1 << 16) +#define IOAPIC_IRQ_MASKED 0x1 +#define IOAPIC_IRQ_UNMASKED 0x0 + +#define MAX_IOAPIC_INTR 32 + + +typedef union { + struct { + unsigned version : 8; + unsigned reserved1 : 8; + unsigned max_lvt : 8; + unsigned reserved0 : 8; + } ver; + dword_t raw; +} apic_version_t; + + +typedef struct { + dword_t vector : 8, + delivery_mode : 3, + dest_mode : 1, + delivery_status : 1, + polarity : 1, + irr : 1, + trigger_mode : 1, + mask : 1, + __reserved1 : 15; + union { + struct { + dword_t __reserved_1 : 24, + physical_dest : 4, + __reserved_2 : 4; + } physical; + + struct { + dword_t __reserved_1 : 24, + logical_dest : 8; + } logical; + } dest; +} apic_redir_t __attribute__((packed)); + + +/* + * local APIC + */ +INLINE dword_t get_local_apic(dword_t reg) +{ + dword_t tmp; + tmp = *(__volatile__ dword_t*)(KERNEL_LOCAL_APIC + reg); + return tmp; +} + +INLINE void set_local_apic(dword_t reg, dword_t val) +{ + *(__volatile__ dword_t*)(KERNEL_LOCAL_APIC + reg) = val; +} + +INLINE void apic_ack_irq() +{ + get_local_apic(X86_APIC_SVR); + set_local_apic(X86_APIC_EOI, 0); +} + + + +/* + * IO-APIC + */ +INLINE dword_t get_io_apic(dword_t reg) +{ + *(__volatile__ dword_t*)(KERNEL_IO_APIC) = reg; + return *(__volatile__ dword_t*)(KERNEL_IO_APIC + 0x10); +} + +INLINE void set_io_apic(dword_t reg, dword_t val) +{ + *(__volatile__ dword_t*)(KERNEL_IO_APIC) = reg; + *(__volatile__ dword_t*)(KERNEL_IO_APIC + 0x10) = val; +} + + +INLINE void io_apic_mask_irq(int num) +{ + int reg = X86_IOAPIC_REDIR0 + (num * 2); + set_io_apic(reg, get_io_apic(reg) | IOAPIC_IRQ_MASK); +} + +INLINE void io_apic_unmask_irq(int num) +{ + int reg = X86_IOAPIC_REDIR0 + (num * 2); + set_io_apic(reg, get_io_apic(reg) & (~IOAPIC_IRQ_MASK)); +} + + +void setup_local_apic() L4_SECT_INIT; + +#endif /* __X86_APIC_H__ */ diff --git a/kernel/include/x86/config.h b/kernel/include/x86/config.h new file mode 100644 index 0000000..e0ce9ff --- /dev/null +++ b/kernel/include/x86/config.h @@ -0,0 +1,187 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/config.h + * Description: Various kernel configuration for x86. + * + * @LICENSE@ + * + * $Id: config.h,v 1.33 2002/05/13 13:04:30 stoess Exp $ + * + ********************************************************************/ +#ifndef __X86_CONFIG_H__ +#define __X86_CONFIG_H__ + +#include "cpu.h" + +/* thread configuration */ +#define USER_AREA_MAX 0xC0000000 +#define TCB_AREA 0xE0000000 +#define TCB_AREA_SIZE 0x01000000 + +#define MEM_COPYAREA1 0xE2000000 +#define MEM_COPYAREA2 (MEM_COPYAREA1 + (PAGEDIR_SIZE * 2)) +#define MEM_COPYAREA_END (MEM_COPYAREA2 + (PAGEDIR_SIZE * 2)) + + +#define SPACE_ID_IDX ((((MEM_COPYAREA_END >> PAGEDIR_BITS)+7)/8)*8) + +#if defined(CONFIG_IO_FLEXPAGES) +#define IO_SPACE_IDX (SPACE_ID_IDX+3) +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) + +#undef USER_AREA_MAX +#if defined(CONFIG_SMALL_AREA_2GB) +# define USER_AREA_MAX 0x60000000 +#elif defined(CONFIG_SMALL_AREA_1GB) +# define USER_AREA_MAX 0xA0000000 +#else +# define USER_AREA_MAX 0xC0000000 +#endif + +#define SMALL_SPACE_START USER_AREA_MAX + +/* Next entries are aligned to fit in one cache line. */ +#define GDT_ENTRY1_IDX (SPACE_ID_IDX+1) +#define GDT_ENTRY2_IDX (SPACE_ID_IDX+2) + + +#endif + +#if defined (CONFIG_LARGE_TCB) +#define L4_NUMBITS_TCBS 12 +#else +#define L4_NUMBITS_TCBS 10 +#endif +#define L4_NUMBITS_THREADS 22 + +#define L4_TOTAL_TCB_SIZE (1 << L4_NUMBITS_TCBS) +#define L4_TCB_MASK ((~0) << L4_NUMBITS_TCBS) + +/* see also linker/x86.lds */ +#define KERNEL_PHYS 0x00100000 +#define KERNEL_OFFSET 0xF0000000 +#define KERNEL_VIRT (KERNEL_PHYS + KERNEL_OFFSET) +#define KERNEL_SIZE 0x00012000 +#define KERNEL_INIT_PAGES 2 +#define KERNEL_CPU_LOCAL_PAGES 2 + +#define KERNEL_VIDEO (0xF00b8000) +#define KERNEL_VIDEO_HERC (0xF00b0000) +#define KERNEL_IO_APIC (0xF00E0000) +#define KERNEL_LOCAL_APIC (0xF00F0000) + +/* startup code must be 4k aligned and < 1MB */ +#define SMP_STARTUP_PAGE (0x00004000) + + + +/* spurious int vector MUST be @ 0x...f */ +#define APIC_SPURIOUS_INT_VECTOR 31 + +/* apic interrupt vectors */ +#define APIC_LINT0_INT_VECTOR 55 +#define APIC_LINT1_INT_VECTOR 56 +#define APIC_TIMER_INT_VECTOR 57 +#define APIC_ERROR_INT_VECTOR 58 + +/* performance counter overflow */ +#define APIC_PERFCTR_INT_VECTOR 59 + +/* smp interrupt vectors */ +#if defined(CONFIG_ENABLE_PROFILING) +# define APIC_SMP_CONTROL_IPI 60 +# define APIC_SMP_COMMAND_IPI 61 +#else +# define APIC_SMP_CONTROL_IPI 59 +# define APIC_SMP_COMMAND_IPI 60 +#endif + + +/* scheduler configuration */ +/* 10 ms = 1 timeslice */ +#define DEFAULT_TIMESLICE (10000) + +/* 1.953ms per timer tick + * VU: the hardware clock can only be configured to tick in 2^n Hz + * 1000 / 512 Hz = 1.953125 ms/tick */ +#define TIME_QUANTUM (1953) + + +#define IDTSZ_ADD1 0 +#define IDTSZ_ADD2 0 +#define IDTSZ_ADD3 0 + +#if defined(CONFIG_X86_APIC) +# undef IDTSZ_ADD1 +# define IDTSZ_ADD1 4 +#endif +#if defined(CONFIG_ENABLE_PROFILING) +# undef IDTSZ_ADD2 +# define IDTSZ_ADD2 1 +#endif +#if defined(CONFIG_SMP) +# undef IDTSZ_ADD3 +# define IDTSZ_ADD3 2 +#endif + +#define IDT_SIZE (55 + IDTSZ_ADD1 + IDTSZ_ADD2 + IDTSZ_ADD3) + +#undef IDT_SZ_ADD1 +#undef IDT_SZ_ADD2 +#undef IDT_SZ_ADD3 + + +/* number of descriptors in the GDT + 1 null + 2 kernel + 2 user + tss + kdb + tracebuffer */ +#ifdef CONFIG_TRACEBUFFER +#define GDT_SIZE 8 +#else +#define GDT_SIZE 7 +#endif +#define TSS_SIZE (sizeof(x86_tss_t)) + +#if defined(CONFIG_SMP) +# if CONFIG_SMP_MAX_CPU > 32 +/* currently we only support up to 32 cpu's. */ +# error maximum cpu is 32 +# endif +#endif + + +#if !defined(ASSEMBLY) + +static const dword_t CPU_FEATURE_MASK = ( X86_FEAT_TSC | X86_FEAT_DE + +#if defined(CONFIG_IA32_FEATURE_PSE) +| X86_FEAT_PSE +#endif +#if defined(CONFIG_IA32_FEATURE_PGE) +| X86_FEAT_PGE +#endif +#if defined(CONFIG_IA32_FEATURE_SEP) +| X86_FEAT_SEP +#endif +#if defined(CONFIG_IA32_FEATURE_FXSR) +| X86_FEAT_FXSR +#endif +#if defined(CONFIG_IA32_FEATURE_MSR) +| X86_FEAT_MSR +#endif +#if defined(CONFIG_IA32_FEATURE_CMOV) +| X86_FEAT_CMOV +#endif +#if defined(CONFIG_X86_APIC) + | X86_FEAT_APIC +#endif +#if defined(CONFIG_X86_P4_BST) || defined(CONFIG_X86_P4_PEBS) + | X86_FEAT_DS +#endif + ); + +#endif + +#endif /* __X86_CONFIG_H__ */ diff --git a/kernel/include/x86/cpu.h b/kernel/include/x86/cpu.h new file mode 100644 index 0000000..6ce8e8a --- /dev/null +++ b/kernel/include/x86/cpu.h @@ -0,0 +1,771 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: x86/cpu.h + * Description: x86 specific definitions and inlines. + * + * @LICENSE@ + * * $Id: cpu.h,v 1.58 2002/05/31 11:49:56 stoess Exp $ + * + ********************************************************************/ +#ifndef __X86_CPU_H__ +#define __X86_CPU_H__ + +/* CPU Features (CPUID) */ +#define X86_FEAT_FPU (1 << 0) +#define X86_FEAT_VME (1 << 1) +#define X86_FEAT_DE (1 << 2) +#define X86_FEAT_PSE (1 << 3) +#define X86_FEAT_TSC (1 << 4) +#define X86_FEAT_MSR (1 << 5) +#define X86_FEAT_PAE (1 << 6) +#define X86_FEAT_MCE (1 << 7) +#define X86_FEAT_CXS (1 << 8) +#define X86_FEAT_APIC (1 << 9) +#define X86_FEAT_SEP (1 << 11) +#define X86_FEAT_MTRR (1 << 12) +#define X86_FEAT_PGE (1 << 13) +#define X86_FEAT_MCA (1 << 14) +#define X86_FEAT_CMOV (1 << 15) +#define X86_FEAT_FGPAT (1 << 16) +#define X86_FEAT_PSE36 (1 << 17) +#define X86_FEAT_PSN (1 << 18) +#define X86_FEAT_CLFLSH (1 << 19) +#define X86_FEAT_DS (1 << 21) +#define X86_FEAT_ACPI (1 << 22) +#define X86_FEAT_MMX (1 << 23) +#define X86_FEAT_FXSR (1 << 24) +#define X86_FEAT_SSE (1 << 25) +#define X86_FEAT_SSE2 (1 << 26) +#define X86_FEAT_SS (1 << 27) +#define X86_FEAT_HT (1 << 28) +#define X86_FEAT_TM (1 << 29) +#define X86_FEAT_IA64 (1 << 30) + + +/* Segment register values */ +#define X86_KCS 0x08 +#define X86_KDS 0x10 +#define X86_UCS 0x1b +#define X86_UDS 0x23 +#define X86_TSS 0x28 +#define X86_KDB 0x30 +#define X86_TBS 0x38 + +/* some bits for the EFLAGS register */ +#define X86_EFL_TF (1 << 8) /* trap flag */ +#define X86_EFL_IF (1 << 9) /* interrupt enable flag */ +#define X86_EFL_RF (1 << 16) /* resume flag */ +#define X86_EFL_VIF (1 << 19) /* virtual interrupt flag */ +#define X86_EFL_VIP (1 << 20) /* virtual interrupt pending flag */ +#define X86_EFL_IOPL(x) ((x & 3) << 12) /* the IO privilege level field */ + +#if defined(CONFIG_IO_FLEXPAGES) +#define X86_DEFAULT_IOPL 0 +#else +#define X86_DEFAULT_IOPL 3 +#endif + +#if defined(CONFIG_ENABLE_PVI) +#define X86_USER_FLAGS (X86_EFL_IOPL(X86_DEFAULT_IOPL) + X86_EFL_IF + X86_EFL_VIF+ 2) +#else +#if defined(CONFIG_USERMODE_NOIRQ) +#define X86_USER_FLAGS (X86_EFL_IOPL(X86_DEFAULT_IOPL) + 2) +#else +#define X86_USER_FLAGS (X86_EFL_IOPL(X86_DEFAULT_IOPL) + X86_EFL_IF + 2) +#endif + +#endif /* CONFIG_ENABLE_PVI */ + +/* floating point unit state size + * with sse, sse2 ext. we use fxsave and the state is 512 bytes + * otherwise we use fsave and the size is 108 bytes + */ +#if defined(CONFIG_IA32_FEATURE_FXSR) +# define X86_FLOATING_POINT_SIZE 512 +# define X86_FLOATING_POINT_ALLOC_SIZE 0x400 +#else +# define X86_FLOATING_POINT_SIZE 108 +#endif + + +/* some bits for the control registers */ +#define X86_CR0_PE (1 << 0) /* enable protected mode */ +#define X86_CR0_EM (1 << 2) /* disable fpu */ +#define X86_CR0_TS (1 << 3) /* task switched */ +#define X86_CR0_WP (1 << 16) /* force write protection on user + read only pages for kernel */ +#define X86_CR0_NW (1 << 29) /* */ +#define X86_CR0_CD (1 << 30) /* */ +#define X86_CR0_PG (1 << 31) /* enable paging */ +#define X86_CR4_PVI (1 << 1) /* enable protected mode + virtual interrupts */ +#define X86_CR4_PSE (1 << 4) /* enable super-pages (4M) */ +#define X86_CR4_PGE (1 << 7) /* enable global pages */ +#define X86_CR4_PCE (1 << 8) /* allow user to use rdpmc */ +#define X86_CR4_OSFXSR (1 << 9) /* enable fxsave/fxrstor + sse */ +#define X86_CR4_OSXMMEXCPT (1 << 10) /* support for unmsk. SIMD exc. */ + +/* + * Model specific register locations. + */ + +#define IA32_SYSENTER_CS_MSR 0x174 +#define IA32_SYSENTER_EIP_MSR 0x176 +#define IA32_SYSENTER_ESP_MSR 0x175 + +#define IA32_DEBUGCTL 0x1d9 + +#if defined(CONFIG_ARCH_X86_I586) +# define IA32_TSC 0x010 +# define IA32_CESR 0x011 +# define IA32_CTR0 0x012 +# define IA32_CTR1 0x013 +#endif /* CONFIG_ARCH_X86_I586 */ + +#if defined(CONFIG_ARCH_X86_I686) +# define IA32_PERFCTR0 0x0c1 +# define IA32_PERFCTR1 0x0c2 +# define IA32_EVENTSEL0 0x186 +# define IA32_EVENTSEL1 0x187 +# define IA32_LASTBRANCHFROMIP 0x1db +# define IA32_LASTBRANCHTOIP 0x1dc +# define IA32_LASTINTFROMIP 0x1dd +# define IA32_LASTINTTOIP 0x1de +#endif /* CONFIG_ARCH_X86_I868 */ + +#if defined(CONFIG_ARCH_X86_P4) +# define IA32_MISC_ENABLE 0x1a0 +# define IA32_COUNTER_BASE 0x300 +# define IA32_CCCR_BASE 0x360 +# define IA32_TC_PRECISE_EVENT 0x3f0 +# define IA32_PEBS_ENABLE 0x3f1 +# define IA32_PEBS_MATRIX_VERT 0x3f2 +# define IA32_DS_AREA 0x600 +# define IA32_LER_FROM_LIP 0x1d7 +# define IA32_LER_TO_LIP 0x1d8 +# define IA32_LASTBRANCH_TOS 0x1da +# define IA32_LASTBRANCH_0 0x1db +# define IA32_LASTBRANCH_1 0x1dc +# define IA32_LASTBRANCH_2 0x1dd +# define IA32_LASTBRANCH_3 0x1de + +/* Processor features in the MISC_ENABLE MSR. */ +# define IA32_ENABLE_FAST_STRINGS (1 << 0) +# define IA32_ENABLE_X87_FPU (1 << 2) +# define IA32_ENABLE_THERMAL_MONITOR (1 << 3) +# define IA32_ENABLE_SPLIT_LOCK_DISABLE (1 << 4) +# define IA32_ENABLE_PERFMON (1 << 7) +# define IA32_ENABLE_BRANCH_TRACE (1 << 11) +# define IA32_ENABLE_PEBS (1 << 12) + +/* Preceise Event-Based Sampling (PEBS) support. */ +# define IA32_PEBS_REPLAY_TAG_MASK ((1 << 12)-1) +# define IA32_PEBS_UOP_TAG (1 << 24) +# define IA32_PEBS_ENABLE_PEBS (1 << 25) +#endif /* CONFIG_ARCH_X86_P4 */ + + + +/* PIC */ +#define X86_PIC1_CMD (0x20) +#define X86_PIC1_DATA (0x21) +#define X86_PIC2_CMD (0xA0) +#define X86_PIC2_DATA (0xA1) + +/* If PIC handling is done exclusively by the kernel, we can save + a lot of time by shadowing the mask register. */ + +#ifdef CONFIG_X86_INKERNEL_PIC +#define PIC1_MASK(irq) \ + do { pic1_mask |= 1 << (irq); \ + outb(X86_PIC1_DATA, pic1_mask); } while (0) +#define PIC1_UNMASK(irq) \ + do { pic1_mask &= ~(1 << (irq)); \ + outb(X86_PIC1_DATA, pic1_mask); } while (0) +#define PIC2_MASK(irq) \ + do { pic2_mask |= 1 << (irq); \ + outb(X86_PIC2_DATA, pic2_mask); } while (0) +#define PIC2_UNMASK(irq) \ + do { pic2_mask &= ~(1 << (irq)); \ + outb(X86_PIC2_DATA, pic2_mask); } while (0) +#define PIC1_SET_MASK(mask) \ + do { pic1_mask = (mask); outb(X86_PIC1_DATA, pic1_mask); } while (0) +#define PIC2_SET_MASK(mask) \ + do { pic2_mask = (mask); outb(X86_PIC2_DATA, pic2_mask); } while (0) +#else +#define PIC1_MASK(irq) \ + outb(X86_PIC1_DATA, inb(X86_PIC1_DATA) | (1 << (irq))) +#define PIC2_MASK(irq) \ + outb(X86_PIC2_DATA, inb(X86_PIC2_DATA) | (1 << (irq))) +#define PIC1_UNMASK(irq) \ + outb(X86_PIC1_DATA, inb(X86_PIC1_DATA) & ~(1 << (irq))) +#define PIC2_UNMASK(irq) \ + outb(X86_PIC2_DATA, inb(X86_PIC2_DATA) & ~(1 << (irq))) +#define PIC1_SET_MASK(mask) \ + outb(X86_PIC1_DATA, (mask)) +#define PIC2_SET_MASK(mask) \ + outb(X86_PIC2_DATA, (mask)) +#endif + +#define X86_RTC_CMD (0x70) +#define X86_RTC_DATA (0x71) + +#define KERNEL_VERSION_VER KERNEL_VERSION_CPU_X86 + +#ifndef ASSEMBLY + +#if defined(CONFIG_IO_FLEXPAGES) +#define X86_IOPERMBITMAP_SIZE 0x10000 +#else +#define X86_IOPERMBITMAP_SIZE 0 +#endif +typedef struct { + dword_t link; + dword_t esp0, ss0; + dword_t esp1, ss1; + dword_t esp2, ss2; + dword_t cr3; + dword_t eip, eflags; + dword_t eax, ecx, edx, ebx, esp, ebp, esi, edi; + dword_t es, cs, ss, ds, fs, gs; + dword_t ldt; + word_t trace; + word_t iopbm_offset; +#if defined(CONFIG_IO_FLEXPAGES) + byte_t io_bitmap[X86_IOPERMBITMAP_SIZE/8+1] __attribute__((aligned(4096))); +#else + byte_t io_bitmap[(X86_IOPERMBITMAP_SIZE+7)/8]; +#endif + byte_t stopper; +} x86_tss_t; + +typedef struct { + word_t size; + ptr_t ptr __attribute__((packed)); + word_t zero; +} sys_desc_t; + +/* the IDT entry data structure + ... and a method to set one in a human-readible fashion */ +class idt_desc_t { + public: + union { + dword_t raw[2]; + + struct { + dword_t offset_low : 16; + dword_t sel : 16; + dword_t res0 : 8; + dword_t type : 3; + dword_t d : 1; + dword_t res1 : 1; + dword_t dpl : 2; + dword_t p : 1; + dword_t offset_high : 16; + } d; + } x; +#define IDT_DESC_TYPE_INT 6 +#define IDT_DESC_TYPE_TRAP 7 + /* set an entry + - address is the offset of the handler in X86_KCS + - type selects Interrupt Gate or Trap Gate respectively + - dpl sets the numerical maximum CPL of allowed calling code + */ + inline void set(void (*address)(), int type, int dpl) + { + x.d.offset_low = ((dword_t) address ) & 0xFFFF; + x.d.offset_high = ((dword_t) address >> 16) & 0xFFFF; + x.d.dpl = dpl; + x.d.type = type; + + /* set constant values */ + x.d.sel = X86_KCS; + x.d.p = 1; /* present */ + x.d.d = 1; /* size is 32 */ + + /* clear reserved fields */ + x.d.res0 = x.d.res1 = 0; + }; +}; + +class seg_desc_t { + public: + union { + dword_t raw[2]; + struct { + dword_t limit_low : 16; + dword_t base_low : 24 __attribute__((packed)); + dword_t type : 4; + dword_t s : 1; + dword_t dpl : 2; + dword_t p : 1; + dword_t limit_high : 4; + dword_t avl : 2; + dword_t d : 1; + dword_t g : 1; + dword_t base_high : 8; + } d __attribute__((packed)); + } x; + +#define GDT_DESC_TYPE_CODE 0xb +#define GDT_DESC_TYPE_DATA 0x3 +#define GDT_DESC_TYPE_TSS 0x9 + inline void set_seg(void* base, dword_t limit, int dpl, int type) + { + x.d.limit_low = (limit >> 12) & 0xFFFF; + x.d.limit_high = (limit >> 28) & 0xF; + x.d.base_low = (dword_t) base & 0xFFFFFF; + x.d.base_high = ((dword_t) base >> 24) & 0xFF; + x.d.type = type; + x.d.dpl = dpl; + + /* default fields */ + x.d.p = 1; /* present */ + x.d.g = 1; /* 4k granularity */ + x.d.d = 1; /* 32-bit segment */ + x.d.s = 1; /* non-system segment */ + + /* unused fields */ + x.d.avl = 0; + } + inline void set_sys(void* base, dword_t limit, int dpl, int type) + { + x.d.limit_low = limit & 0xFFFF; + x.d.limit_high = (limit >> 16) & 0xFF; + x.d.base_low = (dword_t) base & 0xFFFFFF; + x.d.base_high = ((dword_t) base >> 24) & 0xFF; + x.d.type = type; + x.d.dpl = dpl; + + /* default fields */ + x.d.p = 1; /* present */ + x.d.g = 0; /* byte granularity */ + x.d.d = 0; /* 32-bit segment */ + x.d.s = 0; /* non-system segment */ + + /* unused fields */ + x.d.avl = 0; + } +}; + + +typedef struct { + dword_t fault_code; + dword_t es; + dword_t ds; + /* pusha */ + dword_t edi; + dword_t esi; + dword_t ebp; + dword_t esp; + dword_t ebx; + dword_t edx; + dword_t ecx; + dword_t eax; + /* default exception frame */ + dword_t error_code; + dword_t fault_address; + dword_t cs; + dword_t eflags; + dword_t *user_stack; + dword_t ss; +} exception_frame_t; + + + +INLINE void outb(const dword_t port, const byte_t val) +{ + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("outb %1, %0\n" + : + : "dN"(port), "al"(val)); + else + __asm__ __volatile__("outb %1, %%dx\n" + : + : "d"(port), "al"(val)); +} + +INLINE byte_t inb(const dword_t port) +{ + byte_t tmp; + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("inb %1, %0\n" + : "=al"(tmp) + : "dN"(port)); + else + __asm__ __volatile__("inb %%dx, %0\n" + : "=al"(tmp) + : "d"(port)); + return tmp; +} + +INLINE void outw(const dword_t port, const word_t val) +{ + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("outw %1, %0\n" + : + : "dN"(port), "ax"(val)); + else + __asm__ __volatile__("outw %1, %%dx\n" + : + : "d"(port), "ax"(val)); +} + +INLINE word_t inw(const dword_t port) +{ + word_t tmp; + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("inw %1, %0\n" + : "=ax"(tmp) + : "dN"(port)); + else + __asm__ __volatile__("inw %%dx, %0\n" + : "=ax"(tmp) + : "d"(port)); + return tmp; +}; + +INLINE void outl(const dword_t port, const dword_t val) +{ + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("outl %1, %0\n" + : + : "dN"(port), "a"(val)); + else + __asm__ __volatile__("outl %1, %%dx\n" + : + : "d"(port), "a"(val)); +} + +INLINE dword_t inl(const dword_t port) +{ + dword_t tmp; + /* GCC can optimize here if constant */ + if (__builtin_constant_p(port) && (port < 0x100)) + __asm__ __volatile__("inl %1, %0\n" + : "=a"(tmp) + : "dN"(port)); + else + __asm__ __volatile__("inl %%dx, %0\n" + : "=a"(tmp) + : "d"(port)); + return tmp; +}; + +INLINE void out_rtc(const dword_t rtc_port, const byte_t val) +{ + outb(X86_RTC_CMD, rtc_port); + outb(X86_RTC_DATA, val); +} + +INLINE byte_t in_rtc(const dword_t rtc_port) +{ + outb(X86_RTC_CMD, rtc_port); + // wait a little - necessary for older clocks + __asm__ __volatile__("jmp 1f;1:jmp 1f;1:jmp 1f;1:jmp 1f;1:\n"); + return inb(X86_RTC_DATA); +} + +INLINE void enable_interrupts() +{ + __asm__ __volatile__ ("sti\n":); +} + +INLINE void disable_interrupts() +{ + __asm__ __volatile__ ("cli\n":); +} + +#if !defined(CONFIG_SMP) +INLINE void system_sleep() +{ +/* + * If we're running in PVI mode, we set the idler's IOPL + * to 3. + * If we run in an interrupt, we can check, if we're sigma0 or idle + * simply by checking the IOPL in the exception frame. We have to do this, as + * the VIF flags does not help, if we're sigma0 or idle. + * This is faster than checking the tcb... + */ + __asm__ __volatile__( +#if defined(CONFIG_ENABLE_PVI) + "pushf \n" + "orl $(3 << 12), (%esp)\n" + "popf \n" +#endif + "sti \n" + "hlt \n" + "cli \n" + :); +} +#else +/* idling is polling for external events on SMP systems */ +void system_sleep(); +#endif + +INLINE void flush_tlb() +{ + dword_t dummy; + __asm__ __volatile__("movl %%cr3, %0\n" + "movl %0, %%cr3\n" + : "=r" (dummy)); +} + + +INLINE void flush_tlbent(ptr_t addr) +{ + __asm__ __volatile__ ("invlpg (%0) \n" + : + :"r" (addr)); +} + +INLINE dword_t get_cpu_features() +{ + dword_t features, dummy; + __asm__ ("cpuid\n" + : "=d"(features), "=a"(dummy) + : "a"(1) + : "ebx", "ecx"); + return features; +} + +INLINE void enable_super_pages() +{ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr4, %0\n" + "orl %1, %0\n" + "mov %0, %%cr4\n" + : "=r" (dummy) + : "i" (X86_CR4_PSE)); +} + +INLINE void enable_global_pages() +{ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr4, %0\n" + "orl %1, %0\n" + "mov %0, %%cr4\n" + : "=r" (dummy) + : "i" (X86_CR4_PGE)); +} + +INLINE void enable_paged_mode() +{ + asm("mov %0, %%cr0\n" + "nop;nop;nop\n" + : + : "r"(X86_CR0_PG | X86_CR0_WP | X86_CR0_PE) + ); +} + +INLINE void enable_fpu() +{ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr0, %0\n" + "andl %1, %0\n" + "mov %0, %%cr0\n" + : "=r" (dummy) + : "i" (~X86_CR0_TS)); +} + +INLINE void enable_osfxsr() +{ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr4, %0 \n" + "orl %1, %0 \n" + "mov %0, %%cr4 \n" + : "=r"(dummy) + : "i"(X86_CR4_OSFXSR)); +} + +INLINE void disable_fpu() +{ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr0, %0\n" + "orl %1, %0\n" + "mov %0, %%cr0\n" + : "=r" (dummy) + : "i" (X86_CR0_TS)); + +} + +INLINE void save_fpu_state(byte_t *fpu_state) +{ + __asm__ __volatile__ ( +#if !defined(CONFIG_IA32_FEATURE_FXSR) + "fnsave %0" +#else + "fxsave %0" +#endif + : + : "m" (*fpu_state)); +} + +INLINE void load_fpu_state(byte_t *fpu_state) +{ + __asm__ __volatile__ ( +#if !defined(CONFIG_IA32_FEATURE_FXSR) + "frstor %0" +#else + "fxrstor %0" +#endif + : + : "m" (*fpu_state)); +} + +INLINE void init_fpu() +{ + __asm__ __volatile__ ("finit"); +} + + +INLINE void load_debug_regs(ptr_t dbg) +{ + __asm__ __volatile__ ( + " mov 0(%0), %%eax \n" + " mov %%eax, %%dr0 \n" + " mov 4(%0), %%eax \n" + " mov %%eax, %%dr1 \n" + " mov 8(%0), %%eax \n" + " mov %%eax, %%dr2 \n" + " mov 12(%0), %%eax \n" + " mov %%eax, %%dr3 \n" + " mov 24(%0), %%eax \n" + " mov %%eax, %%dr6 \n" + " mov 28(%0), %%eax \n" + " mov %%eax, %%dr7 \n" + : + :"r"(dbg) + :"eax"); +} + +INLINE void save_debug_regs(ptr_t dbg) +{ + __asm__ __volatile__ ( + " mov %%dr0, %%eax \n" + " mov %%eax, 0(%0) \n" + " mov %%dr1, %%eax \n" + " mov %%eax, 4(%0) \n" + " mov %%dr2, %%eax \n" + " mov %%eax, 8(%0) \n" + " mov %%dr3, %%eax \n" + " mov %%eax, 12(%0) \n" + " mov %%dr6, %%eax \n" + " mov %%eax, 24(%0) \n" + " mov %%dr7, %%eax \n" + " mov %%eax, 28(%0) \n" + : + :"r"(dbg) + :"eax"); +} + +INLINE void reload_user_segregs (void) +{ + asm volatile ( + " movl %0, %%es \n" +#if !defined(CONFIG_TRACEBUFFER) + " movl %0, %%fs \n" +#endif + " movl %0, %%gs \n" + : + : "r" (X86_UDS)); +} + +INLINE qword_t rdpmc(const int ctrsel) +{ + qword_t __return; + + __asm__ __volatile__ ( + "rdpmc" + : "=A"(__return) + : "c"(ctrsel)); + + return __return; +} + +INLINE qword_t rdtsc(void) +{ + qword_t __return; + + __asm__ __volatile__ ( + "rdtsc" + : "=A"(__return)); + + return __return; +} + +INLINE qword_t rdmsr(const dword_t reg) +{ + qword_t __return; + + __asm__ __volatile__ ( + "rdmsr" + : "=A"(__return) + : "c"(reg) + ); + + return __return; +} + +INLINE void wrmsr(const dword_t reg, const qword_t val) +{ + __asm__ __volatile__ ( + "wrmsr" + : + : "A"(val), "c"(reg)); +} + +INLINE void wbinvd() +{ + __asm__ ("wbinvd\n" : : : "memory"); +} + +INLINE int lsb (dword_t w) __attribute__ ((const)); +INLINE int lsb (dword_t w) +{ + int bitnum; + __asm__ ("bsf %1, %0" : "=r" (bitnum) : "rm" (w)); + return bitnum; +} + +#if defined(CONFIG_ENABLE_PVI) +INLINE void enable_pvi(void){ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr4, %0\n" + "orl %1, %0\n" + "mov %0, %%cr4\n" + : "=r" (dummy) + : "i" (X86_CR4_PVI)); + +} + +INLINE void disable_pvi(void){ + dword_t dummy; + __asm__ __volatile__ ("mov %%cr4, %0\n" + "andl %1, %0\n" + "mov %0, %%cr4\n" + : "=r" (dummy) + : "i" (~X86_CR4_PVI)); + +} + +INLINE dword_t get_cr4(void){ + dword_t ret; + __asm__ __volatile__ ("mov %%cr4, %0\n" + : "=r" (ret)); + return ret; +} + + +#endif /* ENABLE_PVI */ + +#endif /* ASSEMBLY */ + +#endif /* __X86_CPU_H__ */ diff --git a/kernel/include/x86/i586/kdebug.h b/kernel/include/x86/i586/kdebug.h new file mode 100644 index 0000000..7a8ef86 --- /dev/null +++ b/kernel/include/x86/i586/kdebug.h @@ -0,0 +1,7 @@ +#ifndef __PLATFORM_KDEBUG_H__ +#define __PLATFORM_KDEBUG_H__ + + + + +#endif /* __PLATFORM_KDEBUG_H__ */ diff --git a/kernel/include/x86/i686/kdebug.h b/kernel/include/x86/i686/kdebug.h new file mode 100644 index 0000000..7a8ef86 --- /dev/null +++ b/kernel/include/x86/i686/kdebug.h @@ -0,0 +1,7 @@ +#ifndef __PLATFORM_KDEBUG_H__ +#define __PLATFORM_KDEBUG_H__ + + + + +#endif /* __PLATFORM_KDEBUG_H__ */ diff --git a/kernel/include/x86/init.h b/kernel/include/x86/init.h new file mode 100644 index 0000000..44d412d --- /dev/null +++ b/kernel/include/x86/init.h @@ -0,0 +1,91 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/init.h + * Description: Initialization declarations for x86. + * + * @LICENSE@ + * + * $Id: init.h,v 1.13 2002/05/13 13:04:30 stoess Exp $ + * + ********************************************************************/ +#ifndef __X86_INIT_H__ +#define __X86_INIT_H__ + +extern "C" void int_0(); +extern "C" void int_1(); +extern "C" void int_2(); +extern "C" void int_3(); +extern "C" void int_4(); +extern "C" void int_5(); +extern "C" void int_6(); +extern "C" void int_7(); +extern "C" void int_8(); +extern "C" void int_9(); +extern "C" void int_10(); +extern "C" void int_11(); +extern "C" void int_12(); +extern "C" void int_13(); +extern "C" void int_14(); +extern "C" void int_16(); +extern "C" void int_17(); +extern "C" void int_18(); +extern "C" void int_19(); + +extern "C" void hwintr_0(); +extern "C" void hwintr_1(); +extern "C" void hwintr_2(); +extern "C" void hwintr_3(); +extern "C" void hwintr_4(); +extern "C" void hwintr_5(); +extern "C" void hwintr_6(); +extern "C" void hwintr_7(); +extern "C" void hwintr_8(); +extern "C" void hwintr_9(); +extern "C" void hwintr_10(); +extern "C" void hwintr_11(); +extern "C" void hwintr_12(); +extern "C" void hwintr_13(); +extern "C" void hwintr_14(); +extern "C" void hwintr_15(); + +extern "C" void int_48(); +extern "C" void int_49(); +extern "C" void int_50(); +extern "C" void int_51(); +extern "C" void int_52(); +extern "C" void int_53(); +extern "C" void int_54(); + +extern "C" void timer_irq(); + +#if defined (CONFIG_X86_APIC) +extern "C" void apic_lint0(); +extern "C" void apic_lint1(); +extern "C" void apic_error(); +extern "C" void apic_spurious_int(); +#endif + +#if defined (CONFIG_ENABLE_PROFILING) +extern "C" void apic_perfctr(); +extern "C" void perfctr_bounce_back(); +#endif + +#if defined (CONFIG_SMP) +extern "C" void apic_smp_control_ipi(); +extern "C" void apic_smp_command_ipi(); +#endif /* CONFIG_SMP */ + +void init_irqs() L4_SECT_INIT; + +#if defined(CONFIG_IO_FLEXPAGES) +/* From io_mapping.c */ +void io_mdb_init(void) L4_SECT_INIT; +#endif + +#endif + + + + diff --git a/kernel/include/x86/io_mapping.h b/kernel/include/x86/io_mapping.h new file mode 100644 index 0000000..717e0d0 --- /dev/null +++ b/kernel/include/x86/io_mapping.h @@ -0,0 +1,55 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: x86/io_mapping.h + * Description: Declarations for mapping database for IO fpages + * + * @LICENSE@ + * + * $Id: io_mapping.h,v 1.1 2002/05/13 14:04:52 ud3 Exp $ + * + ********************************************************************/ +#ifndef __X86_IO_MAPPING_H__ +#define __X86_IO_MAPPING_H__ + +#include + +#if defined(CONFIG_IO_FLEXPAGES) + +#define IOFP_LO_BOUND 0xF0000000 +#define IOFP_HI_BOUND 0xFFFFF043 + +typedef struct { + unsigned grant:1; + unsigned none:1; + unsigned size:6; + unsigned zero:4; + unsigned port:16; + unsigned f:4; +} io_fpage_struct_t; + +typedef union { + dword_t raw; + io_fpage_struct_t fpage; +} io_fpage_t; + + +inline io_fpage_t io_fpage(word_t port, word_t ld_size, byte_t grant) +{ + return ((io_fpage_t){fpage:{grant, 0 , ld_size, 0, port, 0xf}}); +} + +int map_io_fpage(tcb_t *from, tcb_t *to, fpage_t io_fp); + +void unmap_io_fpage(tcb_t *from, fpage_t io_fp, dword_t mapmask); + +void io_mdb_task_new(tcb_t *current, tcb_t *task); + +void io_mdb_delete_iospace(tcb_t *tcb); + +void io_mdb_init_sigma0(void); + +#endif /* defined(CONFIG_IO_FLEXPAGES) */ + +#endif /* __X86_IO_MAPPING_H__ */ diff --git a/kernel/include/x86/kdebug.h b/kernel/include/x86/kdebug.h new file mode 100644 index 0000000..3df0f19 --- /dev/null +++ b/kernel/include/x86/kdebug.h @@ -0,0 +1,56 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/kdebug.h + * Description: x86 specific kdebug stuff. + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.18 2001/11/22 14:56:37 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86_KDEBUG_H__ +#define __X86_KDEBUG_H__ + +#if defined(CONFIG_X86_P4_BTS) || defined(CONFIG_X86_P4_PEBS) +void init_tracestore(void) L4_SECT_INIT; +#endif + + +INLINE void spin(int pos = 80) { + while(1) +#if !defined(CONFIG_SMP) + ((word_t*)(KERNEL_VIDEO))[pos] += 1; +#else + ((word_t*)(KERNEL_VIDEO))[pos + (get_cpu_id() * 80)] += 1; +#endif +} + +INLINE void spin1(int pos) { +#if defined(CONFIG_DEBUG_SPIN) +# if !defined(CONFIG_SMP) + ((char*)(KERNEL_VIDEO))[pos * 2] += 1; + ((char*)(KERNEL_VIDEO))[pos * 2 + 1] = 7; +# else + ((char*)(KERNEL_VIDEO))[(get_cpu_id() * 80 + pos) * 2] += 1; + ((char*)(KERNEL_VIDEO))[(get_cpu_id() * 80 + pos) * 2 + 1] = 7; +# endif +#endif +} + +#define enter_kdebug(arg...) \ +__asm__ __volatile__ ( \ + "int $3;" \ + "jmp 1f;" \ + ".ascii \"KD# " arg "\";" \ + "1:") + +INLINE ptr_t get_current_pgtable() +{ + ptr_t t; + __asm__ __volatile__ ("mov %%cr3, %0" : "=r" (t)); + return t; +} + +#endif /* __X86_KDEBUG_H__ */ diff --git a/kernel/include/x86/mapping.h b/kernel/include/x86/mapping.h new file mode 100644 index 0000000..58d065a --- /dev/null +++ b/kernel/include/x86/mapping.h @@ -0,0 +1,275 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86/mapping.h + * Description: Mapping database specification for x86. + * + * @LICENSE@ + * + * $Id: mapping.h,v 1.4 2001/12/05 20:49:51 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86__MAPPING_H__ +#define __X86__MAPPING_H__ + +#define SIGMA0_PGDIR_ID 0 +#define NUM_PAGESIZES 2 + +#if !defined(ASSEMBLY) + +#ifdef CONFIG_SMP +#define __LOCK "lock;" +#else +#define __LOCK +#endif + +#if 0 +#define MDB_BIT_LOCK(word, bit) \ + __asm__ __volatile__ ( \ + "1: \n" \ + __LOCK \ + " btsl %1, %0 \n" \ + " jc 2f \n" \ + ".section .spinlock \n" \ + "2: \n" \ + " jmp 1b \n" \ + ".previous \n" \ + : \ + :"m"(word), "I"(bit)) + +#define MDB_BIT_TRYLOCK(word, bit) \ +({ \ + int ret = 0; \ + \ + __asm__ __volatile__ ( \ + __LOCK \ + " btsl %2, %1 \n" \ + " setnc %b0 \n" \ + : \ + :"r"(ret), "m"(word), "I"(bit)); \ + \ + ret; \ +}) + +#define MDB_BIT_UNLOCK(word, bit) \ + __asm__ __volatile__ ( \ + __LOCK "btrl %1, %0" \ + : \ + :"m"(word), "I"(bit)) + +#else + +#define MDB_BIT_LOCK(word, bit) +#define MDB_BIT_TRYLOCK(word, bit) (1) +#define MDB_BIT_UNLOCK(word, bit) + +#endif + + +//#define MDB_SANITY_CHECK + + +class space_t; +class pgent_t; +class rnode_t; + + +#define MDB_NEXT_ROOT 0x01 +#define MDB_PREV_ROOT 0x01 + +#define MDB_SPACE_MASK 0xfffff000 +#define MDB_DEPTH_MASK 0x000000ff +#define MDB_UPLOCK_BIT 8 +#define MDB_DOWNLOCK_BIT 9 +#define MDB_UPLOCK (1 << MDB_UPLOCK_BIT) +#define MDB_DOWNLOCK (1 << MDB_DOWNLOCK_BIT) + + +class mnode_t +{ + public: + volatile unsigned long w1; // Prev pointer, pgent_t pointer + volatile unsigned long w2; // Space, tree depth, type bits + volatile unsigned long w3; // Next pointer + + inline void down_lock(void) + { MDB_BIT_LOCK(w2, MDB_DOWNLOCK_BIT); } + + inline int down_trylock(void) + { return MDB_BIT_TRYLOCK(w2, MDB_DOWNLOCK_BIT); } + + inline void down_unlock(void) + { MDB_BIT_UNLOCK(w2, MDB_DOWNLOCK_BIT); } + + inline void up_lock(void) + { MDB_BIT_LOCK(w2, MDB_UPLOCK_BIT); } + + inline int up_trylock(void) + { return MDB_BIT_TRYLOCK(w2, MDB_UPLOCK_BIT); } + + inline void up_unlock(void) + { MDB_BIT_UNLOCK(w2, MDB_UPLOCK_BIT); } + + inline void clear_locks(void) + { w2 &= ~(MDB_UPLOCK | MDB_DOWNLOCK); } + + + // Previous pointer and backing pointer + + inline pgent_t *get_pgent(mnode_t *prev) + { +#ifdef MDB_SANITY_CHECK + if ( w1 & MDB_PREV_ROOT ) + panic("mnode::get_pgent - Not prev map\n"); +#endif + return (pgent_t *) (w1 ^ (dword_t) prev); + } + + inline pgent_t *get_pgent(rnode_t *prev) + { +#ifdef MDB_SANITY_CHECK + if ( !(w1 & MDB_PREV_ROOT) ) + panic("mnode::get_pgent - Not prev root\n"); +#endif + return (pgent_t *) ((w1 ^ (dword_t) prev) & ~MDB_PREV_ROOT); + } + + inline mnode_t *get_prevm(pgent_t *pg) + { +#ifdef MDB_SANITY_CHECK + if ( w1 & MDB_PREV_ROOT ) + panic("mnode::get_prevm - Not prev map\n"); +#endif + return (mnode_t *) ((w1 ^ (dword_t) pg) & ~MDB_PREV_ROOT); + } + + inline rnode_t *get_prevr(pgent_t *pg) + { +#ifdef MDB_SANITY_CHECK + if ( !(w1 & MDB_PREV_ROOT) ) + panic("mnode::get_prevr - Not prev root\n"); +#endif + return (rnode_t *) ((w1 ^ (dword_t) pg) & ~MDB_PREV_ROOT); + } + + inline void set_backlink(mnode_t *prev, pgent_t *pg) + { + w1 = (dword_t) prev ^ (dword_t) pg; + } + + inline void set_backlink(rnode_t *prev, pgent_t *pg) + { + w1 = ((dword_t) prev ^ (dword_t) pg) | MDB_PREV_ROOT; + } + + inline int is_prev_root(void) + { + return w1 & MDB_PREV_ROOT; + } + + + // Next pointer + + inline mnode_t *get_nextm(void) + { + return (mnode_t *) (w3 & ~MDB_NEXT_ROOT); + } + + inline rnode_t *get_nextr(void) + { + return (rnode_t *) (w3 & ~MDB_NEXT_ROOT); + } + + inline void set_next(mnode_t *map) + { + w3 = (dword_t) map; + } + + inline void set_next(rnode_t *root) + { + w3 = (dword_t) root | MDB_NEXT_ROOT; + } + + inline int is_next_root(void) + { + return w3 & MDB_NEXT_ROOT; + } + + + // Address space identifier + + inline space_t * get_space(void) + { + return (space_t *) (w2 & MDB_SPACE_MASK); + } + + inline void set_space(space_t * space) + { + w2 = (w2 & ~MDB_SPACE_MASK) | ((dword_t) space & MDB_SPACE_MASK); + } + + + // Tree depth + + inline dword_t get_depth(void) + { + return w2 & MDB_DEPTH_MASK; + } + + inline void set_depth(dword_t depth) + { + w2 = (w2 & ~MDB_DEPTH_MASK) | (depth & MDB_DEPTH_MASK); + } + +} __attribute__ ((packed)); + + +#define MDB_RNEXT_ROOT 0x01 +#define MDB_RDOWNLOCK_BIT 1 +#define MDB_RDOWNLOCK (1 << MDB_RDOWNLOCK_BIT) +#define MDB_RPTR_MASK 0xfffffffc + + +class rnode_t +{ + public: + unsigned long w1; + + inline void down_lock(void) + { MDB_BIT_LOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline int down_trylock(void) + { return MDB_BIT_TRYLOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline void down_unlock(void) + { MDB_BIT_UNLOCK(w1, MDB_RDOWNLOCK_BIT); } + + inline void clear_locks(void) + { w1 &= ~MDB_RDOWNLOCK; } + + inline mnode_t *get_map(void) + { + return (mnode_t *) (w1 & MDB_RPTR_MASK); + } + + inline void set_ptr(mnode_t *map) + { + w1 = (dword_t) map | MDB_RDOWNLOCK; + } + + inline void set_ptr(rnode_t *root) + { + w1 = (dword_t) root | MDB_RNEXT_ROOT | MDB_RDOWNLOCK; + } + + inline int is_next_root(void) + { + return w1 & MDB_RNEXT_ROOT; + } +}; + + +#endif /* !ASSEMBLY */ + +#endif /* !__X86__MAPPING_H__ */ diff --git a/kernel/include/x86/memory.h b/kernel/include/x86/memory.h new file mode 100644 index 0000000..18de7e0 --- /dev/null +++ b/kernel/include/x86/memory.h @@ -0,0 +1,398 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, 2002, Karlsruhe University + * + * File path: x86/memory.h + * Description: x86 page table manipulation code. + * + * @LICENSE@ + * + * $Id: memory.h,v 1.20 2002/07/18 13:09:07 haeber Exp $ + * + ********************************************************************/ +#ifndef __X86__MEMORY_H__ +#define __X86__MEMORY_H__ + +#include INC_ARCH(config.h) +#include INC_ARCH(mapping.h) + +#if defined(ASSEMBLY) +# define __DWORD_CAST +#else +# define __DWORD_CAST (dword_t) +#endif + +#define PAGEDIR_BITS 22 +#define PAGEDIR_SIZE __DWORD_CAST (1 << PAGEDIR_BITS) +#define PAGEDIR_MASK __DWORD_CAST (~(PAGEDIR_SIZE - 1)) + +#define PAGE_BITS 12 +#define PAGE_SIZE __DWORD_CAST (1 << PAGE_BITS) +#define PAGE_MASK __DWORD_CAST (~(PAGE_SIZE - 1)) + +#define PAGE_VALID (1<<0) +#define PAGE_WRITABLE (1<<1) +#define PAGE_USER (1<<2) +#define PAGE_WRITE_THROUGH (1<<3) +#define PAGE_CACHE_DISABLE (1<<4) +#define PAGE_ACCESSED (1<<5) +#define PAGE_DIRTY (1<<6) +#define PAGE_SUPER (1<<7) +#if defined(CONFIG_IA32_FEATURE_PGE) && !defined(CONFIG_SMP) +# define PAGE_GLOBAL (1<<8) +#else +# define PAGE_GLOBAL (0) +#endif +#define PAGE_FLAGS_MASK (0x017f) + +#define PAGE_USER_BITS (PAGE_VALID | PAGE_USER) +#define PAGE_USER_TBITS (PAGE_VALID | PAGE_USER | PAGE_WRITABLE) +#define PAGE_SIGMA0_BITS (PAGE_VALID | PAGE_USER | PAGE_WRITABLE) + +#define PAGE_KERNEL_INIT_SECT (PAGE_VALID | PAGE_WRITABLE) +#define PAGE_KERNEL_BITS (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL) +#define PAGE_KERNEL_TBITS (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL | PAGE_ACCESSED) +#define PAGE_TCB_BITS (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL) +#define PAGE_ZERO_BITS (PAGE_VALID) +#define PAGE_APIC_BITS (PAGE_VALID | PAGE_WRITABLE | PAGE_GLOBAL | PAGE_CACHE_DISABLE) + +#define IS_PAGE_VALID(x) (x & PAGE_VALID) + + +#if !defined(ASSEMBLY) + +/* + * Generic page table configuration + */ + +#define HW_NUM_PGSIZES 2 + +#if defined(CONFIG_IA32_FEATURE_PSE) +# define HW_VALID_PGSIZES ((1<<22) + (1<<12)) +#else +# define HW_VALID_PGSIZES (1<<12) +#endif + +extern dword_t hw_pgshifts[]; + + + +/* declared in x86/init.c */ +extern ptr_t __zero_page; + + +#if 0 +INLINE ptr_t virt_to_phys(ptr_t p) +{ + return (ptr_t)((dword_t)p - KERNEL_OFFSET); +} +#else +#define virt_to_phys(x) \ +({ typeof(x) _x = (typeof(x))((dword_t) (x) - KERNEL_OFFSET); _x;}) +#endif + +#if 0 +INLINE ptr_t phys_to_virt(ptr_t p) +{ + return (ptr_t)((dword_t)p + KERNEL_OFFSET); +} +#else +#define phys_to_virt(x) \ +({ typeof(x) _x = (typeof(x))((dword_t) (x) + KERNEL_OFFSET); _x;}) +#endif + + +INLINE dword_t pgdir_idx(dword_t addr) +{ + return addr >> PAGEDIR_BITS; +} + +INLINE dword_t pgtab_idx(dword_t addr) +{ + return (addr >> PAGE_BITS) & ~(PAGE_MASK >> 2); +} + +INLINE ptr_t get_kernel_pagetable() +{ + extern dword_t * kernel_ptdir_root; + return kernel_ptdir_root; +} + +#if defined(CONFIG_SMP) +INLINE ptr_t get_cpu_pagetable(int cpu) +{ + extern ptr_t cpu_ptdir_root[CONFIG_SMP_MAX_CPU]; + return cpu_ptdir_root[cpu]; +} +#endif + + +INLINE dword_t get_pagefault_address(void) +{ + register dword_t tmp; + + asm ("movl %%cr2, %0\n" + :"=r" (tmp)); + + return tmp; +} + +INLINE ptr_t get_current_pagetable(void) +{ + ptr_t tmp; + + asm volatile ("movl %%cr3, %0 \n" + :"=a" (tmp)); + + return tmp; +} + +INLINE void set_current_pagetable(ptr_t pdir) +{ + asm volatile ("mov %0, %%cr3\n" + : + : "r"(pdir)); +} + +#include INC_ARCH(space.h) + +#if defined(CONFIG_ENABLE_SMALL_AS) + +#if defined(CONFIG_SMP) +#error SMP does not work with small address spaces. +#endif + +void small_space_to_large (space_t *); +int make_small_space (space_t *, byte_t); + +INLINE dword_t get_ipc_copy_limit(dword_t addr, tcb_t *receiver) +{ + if ( addr < SMALL_SPACE_START ) + /* Sender is in small space. Use receivers pagetab. */ + return SMALL_SPACE_START; + else if ( addr < TCB_AREA ) + { + /* Receiver is in small space. */ + smallid_t small = receiver->space->smallid (); + return small.offset () + small.bytesize (); + } + else + /* Neither sender or receiver in small space. Use copy area. */ + return MEM_COPYAREA_END; +} + +INLINE void check_limit(dword_t addr, dword_t limit, tcb_t *tcb) +{ + if ( addr >= limit ) + if ( limit <= SMALL_SPACE_START ) + __asm__ __volatile__ ( + "int $3;" + "jmp 1f;" + ".ascii \"KD# limit crosses 3GB boundary\";" + "1:"); + else + small_space_to_large (tcb->space); +} + +#endif /* CONFIG_ENABLE_SMALL_AS */ + +class pgent_t +{ + public: + union { + struct { + unsigned present :1; + unsigned rw :1; + unsigned privilege :1; + unsigned write_through :1; + + unsigned cache_disabled :1; + unsigned accessed :1; + unsigned dirty :1; + unsigned size :1; + + unsigned global :1; + unsigned avail :3; + + unsigned base :20; + } pg; + + dword_t raw; + } x; + +#if defined(CONFIG_SMP) + +# define SPACE_BASE(_x) ((dword_t)(_x) & ~(PAGE_SIZE*(CONFIG_SMP_MAX_CPU-1))) + +# define SYNC_PGENT() \ +do { \ + if ( pgsize == NUM_PAGESIZES-1 ) \ + for ( int i = 0; i < CONFIG_SMP_MAX_CPU; i++ ) \ + *(dword_t*) ( SPACE_BASE(this) + (i*PAGE_SIZE)) = x.raw; \ +} while (0) + +# define GET_MAPNODE() \ + ((pgsize == 0) ? \ + (*(dword_t *) ((dword_t) this + PAGE_SIZE)) : \ + (*(dword_t *) ((dword_t) SPACE_BASE(this) + \ + PAGE_SIZE*CONFIG_SMP_MAX_CPU))) + +# define SET_MAPNODE(x) \ + if ( pgsize == 0 ) \ + (*(dword_t *) ((dword_t) this + PAGE_SIZE)) = (x); \ + else \ + (*(dword_t *) ((dword_t) SPACE_BASE(this) + \ + PAGE_SIZE*CONFIG_SMP_MAX_CPU)) = (x) + +#else +# define SYNC_PGENT() +# define GET_MAPNODE() (*(dword_t*) ((dword_t) this + PAGE_SIZE)) +# define SET_MAPNODE(x) (*(dword_t*) ((dword_t) this + PAGE_SIZE)) = (x) +#endif + + // Predicates + + inline int is_valid(space_t * s, int pgsize = 0) + { return x.raw & PAGE_VALID; } + + inline int is_writable(space_t * s, int pgsize = 0) + { return x.raw & PAGE_WRITABLE; } + + inline int is_subtree(space_t * s, int pgsize) + { return (pgsize == 1) && !(x.raw & PAGE_SUPER); } + + // Retrieval operations + + inline dword_t address(space_t * s, int pgsize) + { return x.raw & PAGE_MASK; } + + inline pgent_t * subtree(space_t * s, int pgsize) + { return (pgent_t *) phys_to_virt(x.raw & PAGE_MASK); } + + inline mnode_t * mapnode(space_t * s, int pgsize, dword_t vaddr) + { return (mnode_t *) (GET_MAPNODE() ^ vaddr); } + + inline dword_t vaddr(space_t * s, int pgsize, mnode_t *map) + { return (GET_MAPNODE() ^ (dword_t) map); } + + // Change operations + + inline void clear(space_t * s, int pgsize) + { x.raw = 0; SYNC_PGENT(); SET_MAPNODE(0); } + + inline void make_subtree(space_t * s, int pgsize) + { + x.raw = virt_to_phys((dword_t) kmem_alloc((dword_t) PAGE_SIZE*2)) + | PAGE_USER_TBITS; + SYNC_PGENT(); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (s->is_small ()) + { + dword_t idx = s->smallid ().pgdir_idx (); + idx += ((dword_t) this & ~PAGE_MASK) >> 2; + ((dword_t *) phys_to_virt (get_current_pagetable ()))[idx] = + ((dword_t *) get_kernel_pagetable ())[idx] = x.raw; + } +#endif + } + + inline void remove_subtree(space_t * s, int pgsize) + { + kmem_free((ptr_t) phys_to_virt(x.raw & PAGE_MASK), PAGE_SIZE*2); + x.raw = 0; + SYNC_PGENT(); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (s->is_small ()) + __asm__ __volatile__ ( + "int $3;" + "jmp 1f;" + ".ascii \"KD# removing subtree from small as\";" + "1:"); +#endif + } + + inline void set_entry(space_t * s, dword_t addr, dword_t writable, + int pgsize) + { + x.raw = (addr & PAGE_MASK) | PAGE_USER_BITS | + (writable ? PAGE_WRITABLE : 0) | + (pgsize == 1 ? PAGE_SUPER : 0); +#if defined(CONFIG_GLOBAL_SMALL_SPACES) + if (s->is_small ()) + x.raw |= PAGE_GLOBAL; +#endif + SYNC_PGENT(); + } + + inline void set_writable(space_t * s, int pgsize) + { x.raw |= PAGE_WRITABLE; SYNC_PGENT(); } + + inline void set_readonly(space_t * s, int pgsize) + { x.raw &= ~PAGE_WRITABLE; SYNC_PGENT(); } + + inline void set_uncacheable(space_t * s, int pgsize) + { x.raw |= PAGE_CACHE_DISABLE; SYNC_PGENT(); } + + inline void set_unbufferable(space_t * s, int pgsize) + { } + + inline void set_mapnode(space_t * s, int pgsize, mnode_t *map, + dword_t vaddr) + { SET_MAPNODE((dword_t) map ^ vaddr); } + + // Movement + + inline pgent_t * next(space_t * s, dword_t num, int pgsize = 0) + { return this + num; } + + + // Architecture specific + + inline void copy (space_t * s, int pgsize, pgent_t *from, + space_t * f_s, int f_pgsize) + { x.raw = from->x.raw; SYNC_PGENT(); } + + inline void set_address (space_t * s, int pgsize, dword_t addr) + { x.raw = (x.raw & ~PAGE_MASK) | (addr & PAGE_MASK) | + (pgsize == 1 ? PAGE_SUPER : 0); SYNC_PGENT(); } + + inline void set_flags (space_t * s, int pgsize, dword_t flags) + { x.raw = (x.raw & ~PAGE_FLAGS_MASK) | flags; SYNC_PGENT(); } + +#if defined(CONFIG_SMP) + inline void copy_nosync (space_t * s, int pgsize, pgent_t * from, + space_t * f_s, int f_pgsize) + { x.raw = from->x.raw; } + + inline void sync (space_t * s, int pgsize) + { SYNC_PGENT(); } +#endif + +}; + +#define HAVE_ARCH_IPC_COPY +INLINE void ipc_copy(dword_t * to, dword_t * from, dword_t len) +{ + int i = len / 4; + unsigned dummy; + + __asm__ __volatile__ ( + "rep movsl\n\t" + : "=S" (from), "=D" (to), "=c" (dummy) + : "S" (from), "D" (to), "c" (i) + ); + + if ( len & 2 ) + { + *((word_t *) to) = *((word_t *) from); + to = (dword_t *) ((word_t *) to + 1); + from = (dword_t *) ((word_t *) from + 1); + } + + if ( len & 1 ) + *(byte_t *) to = *(byte_t *) from; +} + +#endif /* !ASSEMBLY */ + +#endif /* __X86__MEMORY_H__ */ diff --git a/kernel/include/x86/mps-14.h b/kernel/include/x86/mps-14.h new file mode 100644 index 0000000..f326c0c --- /dev/null +++ b/kernel/include/x86/mps-14.h @@ -0,0 +1,161 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86/mps-14.h + * Description: Structures from the Multiprocessor Specification + * version 1.4 (Intel document 24201601.pdf). + * + * @LICENSE@ + * + * $Id: mps-14.h,v 1.3 2001/11/22 15:08:08 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86__MPS_14_H__ +#define __X86__MPS_14_H__ + +#include +#include + + +typedef struct intel_mp_floating +{ + dword_t signature; /* "_MP_" */ +#define MPS_MPF_SIGNATURE (('_'<<24)|('P'<<16)|('M'<<8)|'_') + dword_t physptr; /* Configuration table address */ + byte_t length; /* in paragraphs */ + byte_t specification; + byte_t checksum; /* makes sum 0 */ + byte_t feature[5]; +} intel_mp_floating_t; + +typedef struct mp_config_table +{ + dword_t signature; +#define MPS_MPC_SIGNATURE ('P'|('C'<<8)|('M'<<16)|('P'<<24)) + word_t length; /* Size of table */ + byte_t spec; /* 0x01 */ + byte_t checksum; + char oem[8]; + char productid[12]; + dword_t oemptr; /* 0 if not present */ + word_t oemsize; /* 0 if not present */ + word_t entries; + dword_t lapic; /* APIC address */ + dword_t reserved; +} mp_config_table_t; + +/* entry types */ +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 + +typedef struct mpc_config_processor +{ + byte_t type; + byte_t apicid; /* Local APIC number */ + byte_t apicver; /* Local APIC version */ + byte_t cpuflag; /* bit 0: available + bit 1: boot processor */ + dword_t cpufeature; + dword_t featureflag; /* CPUID feature value */ + dword_t reserved[2]; +} mpc_config_processor_t; + +typedef struct mpc_config_bus +{ + byte_t type; + byte_t busid; + byte_t bustype[6] __attribute((packed)); +} mpc_config_bus_t; + +typedef struct mpc_config_ioapic +{ + byte_t type; + byte_t apicid; + byte_t apicver; + byte_t flags; /* bit 0: usable */ + dword_t apicaddr; +} mpc_config_ioapic_t; + +typedef struct mpc_config_intsrc +{ + byte_t type; + byte_t irqtype; + word_t irqflag; + byte_t srcbus; + byte_t srcbusirq; + byte_t dstapic; + byte_t dstirq; +} mpc_config_intsrc_t; + +enum mp_irq_source_types { + mp_INT = 0, + mp_NMI = 1, + mp_SMI = 2, + mp_ExtINT = 3 +}; + +typedef struct mpc_config_lintsrc +{ + byte_t type; + byte_t irqtype; + word_t irqflag; + byte_t srcbus; + byte_t srcbusirq; + byte_t dstapic; /* 0xFF = broadcast */ + byte_t dstlint; +} mpc_config_lintsrc_t; + +enum mp_bustype { + MP_BUS_ISA = 1, + MP_BUS_EISA, + MP_BUS_PCI, + MP_BUS_MCA +}; + + + + + + + + + + + +/* PCI IRQ Routing table */ + + +struct irq_info { + byte_t bus; /* Bus, device and function */ + byte_t devfn; + struct { + byte_t link; /* IRQ line ID, chipset dependent, + 0=not routed */ + word_t bitmap; /* Available IRQs */ + } __attribute__((packed)) irq[4]; + byte_t slot; /* Slot number, 0=onboard */ + byte_t rfu; +} __attribute__((packed)); + +struct irq_routing_table { + dword_t signature; /* PIRQ_SIGNATURE should be here */ + word_t version; /* PIRQ_VERSION */ + word_t size; /* Table size in bytes */ + byte_t rtr_bus; + byte_t rtr_devfn; /* Where the interrupt router lies */ + word_t exclusive_irqs; /* IRQs devoted exclusively to PCI usage */ + word_t rtr_vendor; + word_t rtr_device; /* Vendor and device ID of interrupt router */ + dword_t miniport_data; /* Crap */ + byte_t rfu[11]; + byte_t checksum; /* Modulo 256 checksum must give zero */ + struct irq_info slots[0]; +} __attribute__((packed)); + +#define MPS_PIRT_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) + +#endif /* !__X86__MPS_14_H__ */ diff --git a/kernel/include/x86/notify.h b/kernel/include/x86/notify.h new file mode 100644 index 0000000..ac2cb03 --- /dev/null +++ b/kernel/include/x86/notify.h @@ -0,0 +1,53 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/notify.h + * Description: Wrappers for invoking a function within the context + * of another thread. + * + * @LICENSE@ + * + * $Id: notify.h,v 1.4 2001/11/22 14:56:37 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86_NOTIFY_H__ +#define __X86_NOTFIY_H__ + +#define notify_thread(tcb, func) \ +{ \ + tcb_stack_push(tcb, 0); /* dummy */ \ + tcb_stack_push(tcb, 0); /* return addr */ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_1(tcb, func, param0) \ +{ \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, 0); /* dummy */ \ + tcb_stack_push(tcb, 0); /* return addr */ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_thread_2(tcb, func, param0, param1) \ +{ \ + tcb_stack_push(tcb, param1); \ + tcb_stack_push(tcb, param0); \ + tcb_stack_push(tcb, 0); /* dummy */ \ + tcb_stack_push(tcb, 0); /* return addr */ \ + tcb_stack_push(tcb, (dword_t)notify_##func); \ +} + +#define notify_procedure(func, params...) \ +void notify_##func(dword_t __dummy ,##params, dword_t __final) + +/* restore stackpointer */ +#define notify_return \ + asm("movl %0, %%esp\n" \ + "ret\n" \ + : \ + : "r"(&__final)); + + +#endif /* __X86_NOTIFY_H__ */ + diff --git a/kernel/include/x86/smp.h b/kernel/include/x86/smp.h new file mode 100644 index 0000000..afcc28f --- /dev/null +++ b/kernel/include/x86/smp.h @@ -0,0 +1,228 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/smp.h + * Description: x86 SMP definitions and inlines. + * + * @LICENSE@ + * + * $Id: smp.h,v 1.15 2001/12/04 20:16:26 uhlig Exp $ + * + ********************************************************************/ +#ifndef __X86_SMP_H__ +#define __X86_SMP_H__ + +// if we have smp we __ALWAYS__ need APIC handling +// so include right here. +#include + +INLINE dword_t get_apic_cpu_id() +{ + return ((get_local_apic(X86_APIC_ID) >> 24) & 0xf); +} + +INLINE dword_t get_cpu_id() +{ + return get_idle_tcb()->cpu; +} + +extern dword_t boot_cpu; +INLINE dword_t get_boot_cpu() +{ + return boot_cpu; +} + +INLINE int is_boot_cpu() +{ + return (get_apic_cpu_id() == get_boot_cpu()); +} + +INLINE void send_command_ipi(dword_t cpu) +{ + set_local_apic(X86_APIC_INTR_CMD2, cpu << (56 - 32)); + set_local_apic(X86_APIC_INTR_CMD1, APIC_SMP_COMMAND_IPI); +} + +INLINE void broadcast_command_ipi() +{ + /* send to all cpu's excl. myself */ + set_local_apic(X86_APIC_INTR_CMD2, 0xff << (56 - 32)); + set_local_apic(X86_APIC_INTR_CMD1, (APIC_SMP_COMMAND_IPI + get_cpu_id()) | + 0xc0000); +} + +void set_cpu_online(dword_t cpu) L4_SECT_INIT; +int is_cpu_online(dword_t cpu) L4_SECT_INIT; + +/* kdebug control between cpu's */ +void smp_enter_kdebug(); +void smp_leave_kdebug(); + +void smp_startup_processors() L4_SECT_INIT; + +/********************************************************************** + * + * command definitions for inter-cpu communication + * + **********************************************************************/ + +#define SMP_CMD_FLUSH_TLB 1 + +#define SMP_CMD_IPC_SHORT 10 +#define SMP_CMD_IPC_START 11 +#define SMP_CMD_IPC_END 12 +#define SMP_CMD_IPC_RECEIVE 13 + +#define SMP_CMD_THREAD_EX_REGS 20 +#define SMP_CMD_THREAD_GET 21 +#define SMP_CMD_THREAD_PUT 22 +#define SMP_CMD_DELETE_ALL_THREADS 23 +#define SMP_CMD_UNWIND 24 + +/* + * mailbox status messages + */ +#define MAILBOX_NULL 0 +#define MAILBOX_OK 1 +#define MAILBOX_ERROR 2 +#define MAILBOX_DONE 3 + +#define MAILBOX_UNWIND_REMOTE 10 + +#define MAX_MAILBOX_PARAM 5 + +#define MAILBOX_TIMEOUT 0x100000 + +DECLARE_SPINLOCK(ipi_lock); + +class cpu_mailbox_t +{ +private: + dword_t m_command; + volatile dword_t m_status; + +public: + tcb_t * tcb; + dword_t param[MAX_MAILBOX_PARAM]; + l4_threadid_t tid; + volatile dword_t pending_requests; + + /* handling of incoming requests */ + inline void set_request(dword_t from_cpu) + { + asm volatile("lock;orl %0, %1\n" + : + : "r"(1 << from_cpu), "m"(pending_requests)); + } + + inline void clear_request(dword_t from_cpu) + { + asm volatile("lock;andl %0, %1\n" + : + : "r"(~(1 << from_cpu)), "m"(pending_requests)); + }; + + inline void handle_pending_requests() { + extern void smp_handle_requests(); + if (pending_requests) + smp_handle_requests(); + }; + + /* command handling */ + dword_t send_command(dword_t cpu, dword_t command, + dword_t value = MAILBOX_NULL); + + inline void broadcast_command(dword_t command, + dword_t value = MAILBOX_NULL) + { + m_status = value; + m_command = command; + broadcast_command_ipi(); + } + + inline dword_t wait_for_status(dword_t value) + { + extern int printf(const char *, ...); + + int count = MAILBOX_TIMEOUT; + m_status = value; + while (m_status == value) { + if (!count--) + { + printf("cpu %d: mailbox::wait_for_status timeout\n", get_cpu_id()); + count = MAILBOX_TIMEOUT; + asm("int3\n"); + } + + /* allow incoming requests from other cpus */ + if (pending_requests) + { + printf("cpu %d: cpu_mailbox::wait_for_status incoming request\n", get_cpu_id()); + handle_pending_requests(); + } + + __asm__ __volatile__ (".byte 0xf3; .byte 0x90\n"); + } + return m_status; + } + + inline void switch_to_idle(tcb_t * current, const dword_t val) + { + dword_t dummy; + + if (current->resources) + free_resources(current); + + __asm__ __volatile__( + "/* switch_to_idle */ \n" + "pushl %%ebp \n" + "pushl $1f \n" + "movl %%esp, %2 \n" + "movl %3, %%esp \n" + "movl %5, %4 \n" + "ret \n" + "1: \n" + "popl %%ebp \n" + "/* switch_to_idle */ \n" + : "=a" (dummy), "=d"(dummy) + : "m"(current->stack), "m"(get_idle_tcb()->stack), + "m"(m_status), "gi"(val) + : "ebx", "ecx", "esi", "edi", "memory"); + } + + inline dword_t get_command() { return m_command; } + + inline void set_status(dword_t status) { m_status = status; } + + inline dword_t get_status() { return m_status; } +}; + +/* XCPU operations */ + +void smp_move_thread(tcb_t * tcb, dword_t cpu); +dword_t smp_start_short_ipc(tcb_t * to_tcb, tcb_t * current); +void smp_end_short_ipc(tcb_t * to_tcb); +dword_t smp_start_ipc(tcb_t * to_tcb, tcb_t * current); +dword_t smp_end_ipc(tcb_t * to_tcb, tcb_t * current); + +dword_t smp_start_receive_ipc(tcb_t * from_tcb, tcb_t * current); + +int smp_delete_all_threads(space_t * space); +int smp_ex_regs(tcb_t * tcb, dword_t * uip, dword_t * usp, + l4_threadid_t * pager, dword_t * flags); + +void smp_flush_tlb(); + +/********************************************************************** + * + * thread handling + * + **********************************************************************/ + +INLINE void thread_adapt_pagetable(tcb_t * tcb, dword_t cpu) +{ + tcb->pagedir_cache = tcb->space->pagedir_phys(cpu); +} + +#endif /* __X86_SMP_H__ */ diff --git a/kernel/include/x86/space.h b/kernel/include/x86/space.h new file mode 100644 index 0000000..13deb65 --- /dev/null +++ b/kernel/include/x86/space.h @@ -0,0 +1,182 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86/space.h + * Description: Address space definition for the x86 + * + * @LICENSE@ + * + * $Id: space.h,v 1.5 2001/12/04 20:15:46 uhlig Exp $ + * + ********************************************************************/ +#ifndef __X86__SPACE_H__ +#define __X86__SPACE_H__ + +#if defined(CONFIG_ENABLE_SMALL_AS) + +/* + * Small space IDs on x86 are contained within a single byte. The + * least significant bit which is set inidicates the size of the space + * and the remaining most significant bits indicate the position. + * Examples: + * + * 0001 1011 - Bit 0 set, space size = 4MB * 2^0 = 4MB + * Position 0001101b = 13, 13th 4MB space + * 0100 0100 - Bit 2 set, space size = 4MB * 2^2 = 16MB + * Position 01000b = 8, 8th 16MB space + */ + +#define MAX_SMALL_SPACES 128 +#define SMALL_SPACE_INVALID 0xff + +#if defined(CONFIG_SMALL_AREA_2GB) +# define SMALL_SPACE_MIN 16 +# define SMALL_SPACE_SHIFT (PAGEDIR_BITS+2) +#elif defined(CONFIG_SMALL_AREA_1GB) +# define SMALL_SPACE_MIN 8 +# define SMALL_SPACE_SHIFT (PAGEDIR_BITS+1) +#else +# define SMALL_SPACE_MIN 4 +# define SMALL_SPACE_SHIFT PAGEDIR_BITS +#endif + + +class smallid_t +{ + dword_t x; + +public: + + inline dword_t value (void) + { return x; } + + inline void set_value (dword_t value) + { x = value & 0xff; } + + inline int is_valid (void) + { return (x != SMALL_SPACE_INVALID) && (x != 0); } + + inline dword_t size (void) + { return (1 << lsb (x)); } + + inline dword_t bytesize (void) + { return (size () << SMALL_SPACE_SHIFT); } + + inline dword_t num (void) + { return x >> (lsb (x) + 1); } + + inline dword_t idx (void) + { return (x >> (lsb (x) + 1)) << lsb (x); } + + inline dword_t pgdir_idx (void) + { return (idx () * (SMALL_SPACE_MIN >> 2)) + + (SMALL_SPACE_START >> PAGEDIR_BITS); } + + inline dword_t offset (void) + { return (pgdir_idx () << PAGEDIR_BITS); } +}; + +#endif /* CONFIG_ENABLE_SMALL_AS */ + + + + +/* + * On x86, some words in the upper parts of the page directory are + * defined to contain a small space id and the GDT entries which are + * valid for this space. No auxiliary data structures are needed. + */ + +class space_t +{ + union { +#if !defined(CONFIG_SMP) + // Normal page directory. + dword_t pgdir[1024]; +#else + // multiple page directories + dword_t pgdir[CONFIG_SMP_MAX_CPU][1024]; +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) + // Page directory containg various variables. + struct { + dword_t pgdir[SPACE_ID_IDX]; + smallid_t smallid; + seg_desc_t gdt_entry; + dword_t pgdir_kern[1024-SPACE_ID_IDX-3]; + } space; +#endif /* CONFIG_ENABLE_SMALL_AS */ + } u; + +public: +#if !defined(CONFIG_SMP) + inline dword_t * pagedir_phys (void) + { return (dword_t *) this; } + + inline dword_t * pagedir (void) + { return (dword_t *) phys_to_virt (this); } + + inline pgent_t * pgent (int n) + { return (pgent_t *) phys_to_virt (&u.pgdir[n]); } +#else /* CONFIG_SMP */ + inline dword_t * pagedir_phys (int cpu = 0) + { return (dword_t *) &u.pgdir[cpu][0]; } + + inline dword_t * pagedir (int cpu = 0) + { return (dword_t *) phys_to_virt (&u.pgdir[cpu][0]); } + + inline pgent_t * pgent (int n, int cpu = 0) + { return (pgent_t *) phys_to_virt (&u.pgdir[cpu][n]); } +#endif /* CONFIG_SMP */ + +#if defined(CONFIG_ENABLE_SMALL_AS) +#define SMALLID (*(phys_to_virt (&u.space.smallid))) +#define GDT_DESC (*(phys_to_virt (&u.space.gdt_entry))) + + inline smallid_t smallid (void) + { return SMALLID; } + + inline void set_smallid (dword_t value) + { + SMALLID.set_value (value); + if (SMALLID.is_valid ()) + GDT_DESC.set_seg ((void *) SMALLID.offset (), + SMALLID.bytesize () - 1, 3, 3); + } + + inline void set_smallid (smallid_t small) + { set_smallid (small.value ()); } + + inline int is_small (void) + { return SMALLID.is_valid (); } + +#undef SMALLID +#undef GDT_DESC +#endif /* CONFIG_ENABLE_SMALL_AS */ +}; + + +INLINE space_t * get_current_space (void) +{ + space_t * s; + __asm__ __volatile__ ("movl %%cr3, %0 \n" + "andl %1, %0 \n" + :"=r" (s) + :"i"(PAGE_MASK)); +#if defined(CONFIG_SMP) + s = (space_t*)((dword_t)s & ~(PAGE_SIZE * CONFIG_SMP_MAX_CPU - 1)); +#endif + return s; +} + +INLINE space_t * get_kernel_space (void) +{ + extern ptr_t kernel_ptdir_root; + return (space_t*)virt_to_phys (kernel_ptdir_root); +} + + +#endif /* !__X86__SPACE_H__ */ + diff --git a/kernel/include/x86/sync.h b/kernel/include/x86/sync.h new file mode 100644 index 0000000..12a1f64 --- /dev/null +++ b/kernel/include/x86/sync.h @@ -0,0 +1,53 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/sync.h + * Description: SMP synchronizarion inlines for x86. + * + * @LICENSE@ + * + * $Id: sync.h,v 1.3 2001/12/04 20:14:32 uhlig Exp $ + * + ********************************************************************/ +#ifndef __X86_SYNC_H__ +#define __X86_SYNC_H__ + +#ifndef CONFIG_SMP +# error should not be included! +#endif + +typedef struct { volatile dword_t lock; } spinlock_t; + +#define DECLARE_SPINLOCK(name) extern spinlock_t name; +#define DEFINE_SPINLOCK(name) spinlock_t name = (spinlock_t) { 0 } + +INLINE void spin_lock_init(spinlock_t * lock) { lock->lock = 0; } + +INLINE void spin_lock(spinlock_t * lock) +{ + __asm__ __volatile__ ( + "1: \n" + "xchg %0, %1 \n" + "cmpl $0, %0 \n" + "jnz 2f \n" + ".section .spinlock \n" + "2: \n" + "cmpl $0, %1 \n" + "jne 2b \n" + "jmp 1b \n" + ".previous \n" + : + : "r"(1), "m"(*lock)); +} + +INLINE void spin_unlock(spinlock_t * lock) +{ + __asm__ __volatile__ ( + "movl %0, %1\n" + : + : "r"(0), "m"(*lock)); +} + + +#endif diff --git a/kernel/include/x86/syscalls.h b/kernel/include/x86/syscalls.h new file mode 100644 index 0000000..df45379 --- /dev/null +++ b/kernel/include/x86/syscalls.h @@ -0,0 +1,201 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: x86/syscalls.h + * Description: System call return paths for x86. + * + * @LICENSE@ + * + * $Id: syscalls.h,v 1.38 2002/05/14 12:51:53 ud3 Exp $ + * + ********************************************************************/ +#ifndef __X86_SYSCALLS_H__ +#define __X86_SYSCALLS_H__ + +#include + +#if defined(CONFIG_ENABLE_SMALL_AS) +# define SET_UDS(_reg) \ + "mov %1, %%"#_reg" \n" \ + "mov %%"#_reg", %%ds \n" +#else +# define SET_UDS(_reg) +#endif + +#define return_lthread_ex_regs(_uip, _usp, _pager, _tid, _flags) \ +{ \ + asm("/* return lthread_ex_regs */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(ebx) \ + " iret \n" \ + : \ + : "r"(&pager + 1), "i"(X86_UDS), \ + "a"(_flags), "c"(_usp), "d"(_uip), "S"(_pager) \ + : "ebx"); \ + while(1); \ +} + +#define return_create_thread() \ +{ \ + asm("/* return create_thread */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(eax) \ + " iret \n" \ + : \ + : "r"(&usp + 1), "i"(X86_UDS) \ + : "eax"); \ + while(1); \ +} + +#define return_thread_switch() \ +{ \ + asm("/* return thread_switch */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(eax) \ + " iret \n" \ + : \ + : "r"(&tid + 1), "i"(X86_UDS) \ + : "eax"); \ + while(1); \ +} + +/* does not load argument into registers */ +#define return_ipc(_error) \ +{ \ + asm("/* return_ipc */ \n" \ + " movl %0, %%esp \n" \ + " ret \n" \ + : \ + : "r"(&dest - 1), "a"(_error)); \ + while(1); \ +} + +/* loads the arguments into registers */ +#define return_ipc_args(_from, _error, _myself) \ +{ \ + const l4_threadid_t* p = &dest - 1; \ + asm("leal %0, %%esp \n" \ + "ret \n" \ + : /* no output */ \ + : "m"(*p), "S"(_from), \ + "a"(_myself->msg_desc | _error), \ + "d"(_myself->ipc_buffer[0]), \ + "b"(_myself->ipc_buffer[1]), \ + "D"(_myself->ipc_buffer[2])); \ + while(1); \ +} + +#define return_task_new(_newtask) \ +{ \ + asm("/* return_task_new */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(eax) \ + " iret \n" \ + : \ + : "r"(&usp + 1), "i"(X86_UDS), "S"(_newtask) \ + : "eax"); \ + while(1); \ +} + +#if !defined(CONFIG_SMP) +#define return_id_nearest(_nearestid, _type) \ +{ \ + asm("/* return id_nearest */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(ebx) \ + " iret \n" \ + : \ + : "r"(&tid + 1), "i"(X86_UDS), "a"(_type), "S"(_nearestid) \ + : "ebx"); \ + while(1); \ +} +#else +#define return_id_nearest(_nearestid, _type) \ +{ \ + asm("/* return id_nearest */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(ebx) \ + " iret \n" \ + : \ + : "r"(&tid + 1), "i"(X86_UDS), "a"(_type), "S"(_nearestid), \ + "c"(get_cpu_id()) \ + : "ebx"); \ + while(1); \ +} +#endif + +#define return_thread_schedule(_oldparam) \ +{ \ + asm("/* return thread_schedule */ \n" \ + " movl %0, %%esp \n" \ + SET_UDS(ebx) \ + " iret \n" \ + : \ + : "r"(&tid + 1), "i"(X86_UDS), "a"(_oldparam) \ + : "ebx"); \ + while(1); \ +} + + +INLINE dword_t do_pagefault_ipc(tcb_t * current, dword_t fault, dword_t ip) +{ + current->ipc_buffer[0] = fault; + current->ipc_buffer[1] = ip; + current->ipc_buffer[2] = 0; + + ptr_t tmp = current->unwind_ipc_sp; + dword_t result; + + __asm__ __volatile__ ( + "pushl %%ebp \n\t" + "pushl $1f \n\t" + "mov %%esp,%3 \n\t" + "pushl %1 \n\t" /* rcv desc */ + "pushl $0 \n\t" /* reg desc */ + "pushl %2 \n\t" /* dest */ +#if (__GNUC__ >= 3) + "call _Z7sys_ipc13l4_threadid_tjj \n\t" +#else + "call sys_ipc__FG13l4_threadid_tUiUi \n\t" +#endif + "addl $16, %%esp \n" + "1: \n\t" + "popl %%ebp \n\t" + : "=a"(result) + : "i"(IPC_PAGEFAULT_DOPE), "m"(current->pager), + "m" (current->unwind_ipc_sp) + : "ebx", "ecx", "edx", "esi", "edi", "memory" + ); + current->unwind_ipc_sp = tmp; + return result; +} + + +INLINE msgdope_t do_ipc(l4_threadid_t dest, dword_t snd, dword_t rcv) +{ + msgdope_t result; + dword_t dummy; + __asm__ __volatile__ ("/* do_ipc */ \n" + " pushl %%ebp \n" + " pushl %0 /* rcv desc */ \n" + " pushl %1 /* snd desc */ \n" + " pushl %2 /* dest */ \n" +#if (__GNUC__ >= 3) + " call _Z7sys_ipc13l4_threadid_tjj \n" +#else + " call sys_ipc__FG13l4_threadid_tUiUi \n" +#endif + " addl $12, %%esp \n" + " popl %%ebp \n" + : "=a" (result), "=r" (dummy), "=r" (dummy) + : "0"(rcv), + "1"(snd), + "2"(dest) + : "ecx", "esi", "edi", "memory" + ); + return result; +} + +#endif + diff --git a/kernel/include/x86/tcb.h b/kernel/include/x86/tcb.h new file mode 100644 index 0000000..40cfcea --- /dev/null +++ b/kernel/include/x86/tcb.h @@ -0,0 +1,35 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86/tcb.h + * Description: x86 specific part of TCB structure. + * + * @LICENSE@ + * + * $Id: tcb.h,v 1.12 2001/11/22 14:56:37 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86__TCB_H__ +#define __X86__TCB_H__ + +typedef struct { + byte_t data[X86_FLOATING_POINT_SIZE]; +} x86_fpu_state_t; + +typedef struct { + dword_t dr[8]; +} x86_debug_regs_t; + +typedef struct { +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) + x86_fpu_state_t *fpu_ptr; +#else + x86_fpu_state_t fpu; + int fpu_used; +#endif + x86_debug_regs_t dbg; +} tcb_priv_t; + + +#endif /* __X86__TCB_H__ */ diff --git a/kernel/include/x86/thread.h b/kernel/include/x86/thread.h new file mode 100644 index 0000000..3465dfb --- /dev/null +++ b/kernel/include/x86/thread.h @@ -0,0 +1,364 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: x86/thread.h + * Description: Thread switch code and definitions and inlines for + * manipulating user stack frame. + * + * @LICENSE@ + * + * $Id: thread.h,v 1.52 2002/05/07 19:12:33 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86_THREAD_H__ +#define __X86_THREAD_H__ + +#include +#include + +#include INC_ARCH(config.h) +#include INC_ARCH(memory.h) +#include INC_ARCH(cpu.h) + + +INLINE ptr_t get_tcb_stack_top(tcb_t *tcb) +{ + return ptr_t (((dword_t)tcb) + L4_TOTAL_TCB_SIZE - 4); +} + + +/* + * Stack positions during sys_ipc. + */ +#define IPCSTK_USP (-2) +#define IPCSTK_UFLAGS (-3) +#define IPCSTK_UIP (-5) +#define IPCSTK_RCVDESC (-6) +#define IPCSTK_SNDDESC (-7) +#define IPCSTK_DESTID (-8) +#define IPCSTK_RETADDR (-9) /* Return address for `call sys_ipc' */ + + +#define USP(tcb) (get_tcb_stack_top(tcb)[-2]) +#define UFL(tcb) (get_tcb_stack_top(tcb)[-3]) +#define UIP(tcb) (get_tcb_stack_top(tcb)[-5]) + +INLINE dword_t get_user_ip(tcb_t* tcb) { return UIP(tcb); } +INLINE dword_t get_user_sp(tcb_t* tcb) { return USP(tcb); } +INLINE dword_t get_user_flags(tcb_t* tcb) { return UFL(tcb); } + +INLINE dword_t set_user_ip(tcb_t* tcb, dword_t val) +{ dword_t old = UIP(tcb); UIP(tcb) = val; return old; } +INLINE dword_t set_user_sp(tcb_t* tcb, dword_t val) +{ dword_t old = USP(tcb); USP(tcb) = val; return old; } +INLINE dword_t set_user_flags(tcb_t* tcb, dword_t val) +{ dword_t old = UFL(tcb); UFL(tcb) = val; return old; } + + + +INLINE void tcb_stack_push(tcb_t* const tcb, const dword_t value) +{ + *(--(tcb->stack)) = value; +} + +INLINE void create_user_stack_frame(tcb_t *tcb, dword_t usp, dword_t uip, void (*entry)(), void* param) +{ + tcb->stack = get_tcb_stack_top(tcb); + tcb_stack_push(tcb, X86_UDS); // stack segment + tcb_stack_push(tcb, usp); // user stack + tcb_stack_push(tcb, X86_USER_FLAGS); // flags + tcb_stack_push(tcb, X86_UCS); // user code segment + tcb_stack_push(tcb, uip); // user instruction pointer + tcb_stack_push(tcb, (dword_t) param); // parameter + tcb_stack_push(tcb, (dword_t) entry); // entry point in kernel +} + + +/* + * Function is_ipc_sysenter (tcb) + * + * Checks the kernel stack of TCB to see if thread is doing a sysenter/ + * sysexit IPC. Assumes that thread is currently performing an IPC. + * + */ +INLINE int is_ipc_sysenter (tcb_t * tcb) +{ + extern dword_t return_from_sys_ipc; +#if defined(CONFIG_ENABLE_SMALL_AS) + extern dword_t return_from_sys_ipc_small; +# define SYSENTER_IPC_CHECK \ + (*stkptr == (dword_t) &return_from_sys_ipc_small || \ + *stkptr == (dword_t) &return_from_sys_ipc) +#else +# define SYSENTER_IPC_CHECK \ + (*stkptr == (dword_t) &return_from_sys_ipc) +#endif + + dword_t *stkptr = &get_tcb_stack_top(tcb)[IPCSTK_RETADDR]; + + return ((dword_t *) tcb->stack < stkptr) && SYSENTER_IPC_CHECK; +} + + +INLINE tcb_t * get_current_tcb() +{ + tcb_t * tmp; + asm("/* get_current_tcb */ \n\t" + "movl %%esp, %0 \n\t" + "andl %1, %0 \n\t" + "/* get_current_tcb */ \n" + : "=r"(tmp) + : "i"(L4_TCB_MASK) + ); + return (tmp); +} + +INLINE tcb_t* const tid_to_tcb(const l4_threadid_t tid) +{ + return (tcb_t*)((tid.id.thread << L4_NUMBITS_TCBS) | TCB_AREA); +} + +INLINE tcb_t *ptr_to_tcb(ptr_t ptr) +{ + return (tcb_t *) ((dword_t) ptr & L4_TCB_MASK); +} + +INLINE void allocate_tcb(tcb_t *tcb) +{ + asm("orl $0, (%0)\n" + : + : "r"(tcb) + ); +} + + +INLINE void switch_to_initial_thread(tcb_t * tcb) +{ + TRACE_THREAD_SWITCH (get_idle_tcb (), tcb); + + asm("movl %0, %%esp\n" + "ret\n" + : + : "r"(tcb->stack)); + +} + + +#if defined(CONFIG_ENABLE_SMALL_AS) + +#if !defined(OFS_TCB_STACK) || !defined(OFS_TCB_SPACE) +/* Building TCB layout. */ +#else + +INLINE void switch_to_thread(tcb_t* const tcb, tcb_t* const current) +{ + extern x86_tss_t __tss; + + TRACE_THREAD_SWITCH (current, tcb); + + if (EXPECT_FALSE (current->resources)) + save_resources (current, tcb); + + /* Modify stack in TSS. */ + __tss.esp0 = (dword_t) get_tcb_stack_top (tcb); + + dword_t dummy; + __asm__ __volatile__ ( + /* + * Note: We do not use any memory inputs since this prohibits + * us from using args 0-3 or EBP to store temporary results, + * and more importantly WILL lead to wrong result if the input + * parameter is specified relative to ESP. + * + * Clobbering EBP is ignored by gcc. We therefore have to + * save it manually. + */ + "/* switch_to_thread */ \n" + " pushl %%ebp \n" + " pushl $9f \n" + " movl (%6), %%ecx \n" + " movl %%esp, %c8(%5) \n" + " movl %c8(%4), %%esp \n" + " movl __is_small, %%edx \n" + " movl %c9(%4), %%ebp \n" + " cmpb $0xff, %%cl \n" + " je 2f \n" + + " /* switch to small space */ \n" + " cmpl %c9(%5), %%ebp \n" + " je 1f \n" + " movl 4(%6), %%ecx \n" + " movl 8(%6), %%eax \n" + " movl $gdt, %%ebp \n" + " movl %%ecx, 32(%%ebp) \n" + " movl %%eax, 36(%%ebp) \n" + " orl $0x800, %%eax \n" + " movl %%ecx, 24(%%ebp) \n" + " movl %%eax, 28(%%ebp) \n" + " movl %7, %%ecx \n" + " movl %%ecx, %%es \n" +#if !defined(CONFIG_TRACEBUFFER) + " movl %%ecx, %%fs \n" +#endif + " movl %%ecx, %%gs \n" + " testl %%edx, %%edx \n" + " jne 1f \n" + " movl $1, __is_small \n" + "1: popl %%eax \n" + " jmp *%%eax \n" + + "2: /* switch to large space */ \n" + " testl %%edx, %%edx \n" + " je 3f \n" + " movl $0, __is_small \n" + " movl $gdt, %%ebp \n" + " movl $0x0000ffff, 24(%%ebp) \n" + " movl $0x00cbfb00, 28(%%ebp) \n" + " movl $0x0000ffff, 32(%%ebp) \n" + " movl $0x00cbf300, 36(%%ebp) \n" + " movl %7, %%edx \n" + " movl %%edx, %%es \n" +#if !defined(CONFIG_TRACEBUFFER) + " movl %%edx, %%fs \n" +#endif + " movl %%edx, %%gs \n" + + "3: movl %c9(%4), %%ebp \n" + " movl %c9(%5), %%ecx \n" + " popl %%edx \n" + " cmpl %%ebp, %%ecx \n" + " je 4f \n" + " movl %%ebp, %%cr3 \n" + "4: jmp *%%edx \n" + + "9: popl %%ebp \n" + + : /* trash everything */ + "=a" (dummy), // 0 + "=b" (dummy), // 1 + "=S" (dummy), // 2 + "=D" (dummy) // 3 + + : + "0"(tcb), // 4 + "1"(current), // 5 + "2"((dword_t) tcb->space->pagedir () + SPACE_ID_IDX*4), // 6 + "i"(X86_UDS), // 7 + "i"(OFS_TCB_STACK), // 8 + "i"(OFS_TCB_PAGEDIR_CACHE) // 9 + + : "ecx", "edx", "memory"); + + /* + * Check if we need to restore any resources. Note that we have + * to check against CURRENT rather than TCB (i.e., we want to + * restore our own resources, not the resources of the thread we + * switched to). + */ + if (EXPECT_FALSE (current->resources)) + load_resources (current); +} +#endif /* Not building TCB layout */ + +#else /* !CONFIG_ENABLE_SMALL_AS */ + +INLINE void switch_to_thread(tcb_t* const tcb, tcb_t* const current) +{ + extern x86_tss_t __tss; + + TRACE_THREAD_SWITCH (current, tcb); + + if ( EXPECT_FALSE(current->resources) ) + save_resources(current, tcb); + + /* modify stack in tss */ + __tss.esp0 = (dword_t)get_tcb_stack_top(tcb); + + dword_t dummy; + __asm__ __volatile__ ( + "/* switch_to_thread */ \n\t" + "pushl %%ebp \n\t" + + "pushl $2f \n\t" /* store return address */ + + "movl %%esp, %6 \n\t" /* switch stacks */ + "movl %7, %%esp \n\t" + + "popl %%ecx \n\n" + + "cmpl %4, %1 \n\t" /* same address space? */ + "je 1f \n\t" + "movl %4, %%cr3 \n\t" /* no -> reload pagedir */ + "1: \n\t" + + "jmp *%%ecx \n\t" + + "2: \n\t" + "popl %%ebp \n\t" + "/* switch_to_thread */ \n\t" + : /* trash everything */ + "=a" (dummy), // 0 + "=b" (dummy), // 1 + "=S" (dummy), // 2 + "=D" (dummy) // 3 + : + "0" (tcb->pagedir_cache), // 4 + "1" (current->pagedir_cache), // 5 + "m" (current->stack), // 6 + "m" (tcb->stack) // 7 + + : "edx", "memory", "ecx" + ); + + if ( EXPECT_FALSE(current->resources) ) + load_resources(current); +} + +#endif /* !CONFIG_ENABLE_SMALL_AS */ + + +INLINE void switch_to_idle(tcb_t * current) +{ + dword_t dummy; + + TRACE_THREAD_SWITCH (current, get_idle_tcb ()); + + if ( EXPECT_FALSE(current->resources) ) + save_resources(current, get_idle_tcb()); + + /* store current pagedir in idle tcb for efficient switching */ + get_idle_tcb()->pagedir_cache = current->pagedir_cache; + + __asm__ __volatile__( + "/* switch_to_idle */ \n\t" + "pushl %%ebp \n\t" + "pushl $1f \n\t" + "movl %%esp, %2 \n\t" + "movl %3, %%esp \n\t" + "ret \n\t" + "1: \n\t" + "popl %%ebp \n\t" + "/* switch_to_idle */ \n\t" + : "=a" (dummy), "=d"(dummy) + : "m"(current->stack), "m"(get_idle_tcb()->stack) + : "ebx", "ecx", "esi", "edi", "memory" + ); +} + + + + +INLINE dword_t tcb_exist(tcb_t * tcb) +{ +#if 1 + return (tcb->myself.raw); +#else + extern dword_t kernel_ptdir[]; + return (kernel_ptdir[(dword_t) tcb >> 22] & PAGE_VALID ? ((ptr_t) (kernel_ptdir[(dword_t)tcb >> 22] & ~PAGE_MASK))[((dword_t)tcb >> 12) & 0x3FF] & PAGE_VALID : 0); +#endif +} + + +#endif /* __X86_THREAD_H__ */ + diff --git a/kernel/include/x86/tracebuffer.h b/kernel/include/x86/tracebuffer.h new file mode 100644 index 0000000..ddf1a5f --- /dev/null +++ b/kernel/include/x86/tracebuffer.h @@ -0,0 +1,132 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86/tracebuffer.h + * Description: x86 tracebuffer handling. + * + * @LICENSE@ + * + * $Id: tracebuffer.h,v 1.3 2001/11/22 14:56:37 skoglund Exp $ + * + ********************************************************************/ +#ifndef __X86__TRACEBUFFER_H__ +#define __X86__TRACEBUFFER_H__ + +typedef struct { + dword_t cycles; + dword_t pmc0; + dword_t pmc1; + } tracestatus_t; + +typedef struct { + tracestatus_t status; + dword_t identifier; + dword_t data[4]; + } trace_t; + +typedef struct { + dword_t current; + dword_t magic; + dword_t counter; + dword_t threshold; + dword_t pad[4]; + trace_t trace[]; + } tracebuffer_t; + +extern tracebuffer_t *tracebuffer; + +#define TBUF_MAGIC 0x20121977 + +#if defined(CONFIG_PERFMON) + #define RDPMC "rdpmc\n" +#else + #define RDPMC "xor %%eax, %%eax\n" +#endif + +#define TBUF_RECORD_EVENT(_a) \ + asm volatile ( \ + "movl %%fs:0, %%edi \n" \ + "rdtsc \n" \ + "movl %%eax, %%fs:32(%%edi) \n" \ + "xor %%ecx, %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:36(%%edi) \n" \ + "inc %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:40(%%edi) \n" \ + "movl %0, %%fs:44(%%edi) \n" \ + "addl $32, %%edi \n" \ + "andl $0x1fffff, %%edi \n" \ + "movl %%edi, %%fs:0 \n" \ + : \ + : "g" (_a) \ + : "eax", "edx", "edi", "ecx" \ + ) + +#define TBUF_RECORD_EVENT_AND_PAR(_a, _p0) \ + asm volatile ( \ + "movl %%fs:0, %%edi \n" \ + "rdtsc \n" \ + "movl %%eax, %%fs:32(%%edi) \n" \ + "xor %%ecx, %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:36(%%edi) \n" \ + "inc %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:40(%%edi) \n" \ + "movl %0, %%fs:44(%%edi) \n" \ + "movl %%ebx, %%fs:48(%%edi) \n" \ + "addl $32, %%edi \n" \ + "andl $0x1fffff, %%edi \n" \ + "movl %%edi, %%fs:0 \n" \ + : \ + : "g" (_a), "b"(_p0) \ + : "eax", "edx", "edi", "ecx" \ + ) + +#define TBUF_RECORD_EVENT_AND_TWO_PAR(_a, _p0, _p1) \ + asm volatile ( \ + "movl %%fs:0, %%edi \n" \ + "rdtsc \n" \ + "movl %%eax, %%fs:32(%%edi) \n" \ + "xor %%ecx, %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:36(%%edi) \n" \ + "inc %%ecx \n" \ + RDPMC \ + "movl %%eax, %%fs:40(%%edi) \n" \ + "movl %0, %%fs:44(%%edi) \n" \ + "movl %%ebx, %%fs:48(%%edi) \n" \ + "movl %%esi, %%fs:52(%%edi) \n" \ + "addl $32, %%edi \n" \ + "andl $0x1fffff, %%edi \n" \ + "movl %%edi, %%fs:0 \n" \ + : \ + : "g" (_a), "b"(_p0), "S" (_p1) \ + : "eax", "edx", "edi", "ecx" \ + ) + +#define TBUF_INCREMENT_TRACE_COUNTER() \ + asm volatile ( \ + "movl %%fs:8, %%edx \n" \ + "movl %%fs:12, %%edi \n" \ + "inc %%edx \n" \ + "movl %%edx, %%fs:8 \n" \ + "cmpl %%edx, %%edi \n" \ + "jge 1f \n" \ + "int3 \n" \ + "xor %%edx, %%edx \n" \ + "movl %%edx, %%fs:8 \n" \ + "1: \n" \ + : \ + : \ + : "edx", "edi" \ + ); + +#define TBUF_CLEAR_BUFFER() \ + asm volatile ( \ + "movl $0, %fs:0 \n" \ + ); + +#endif /* __X86__TRACEBUFFER_H__ */ diff --git a/kernel/kdb/.cvsignore b/kernel/kdb/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/kdb/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/kdb/.depend b/kernel/kdb/.depend new file mode 100644 index 0000000..0940738 --- /dev/null +++ b/kernel/kdb/.depend @@ -0,0 +1,156 @@ +print.o: print.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +mini-kd.o: mini-kd.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/mapping.h kdebug.h kdebug_keys.h +gdb.o: gdb.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +mdb.o: mdb.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/mapping.h +init.o: init.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +input.o: input.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h kdebug.h +tracepoints.o: tracepoints.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +new-kdb.o: new-kdb.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +interrupt.o: interrupt.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +tracing.o: tracing.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +x86.o: x86.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/tracepoints.h \ + ../include/tracebuffer.h ../include/tracepoint_list.h kdebug.h +asm-x86.o: asm-x86.S ../include/config.h ../include/x86/config.h \ + ../include/x86/cpu.h ../include/tcb_layout.h +x86_dis.o: x86_dis.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h kdebug.h +x86_input.o: x86_input.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h kdebug.h +x86_io.o: x86_io.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h kdebug.h +x86_profiling.o: x86_profiling.c ../include/universe.h \ + ../include/config.h ../include/macros.h ../include/types.h \ + ../include/kernel.h ../include/x86/config.h ../include/x86/cpu.h \ + ../include/lib.h ../include/sync.h ../include/x86/notify.h \ + ../include/kmemory.h ../include/thread.h ../include/ipc.h \ + ../include/tcb.h ../include/x86/tcb.h ../include/schedule.h \ + ../include/interrupt.h ../include/x86/memory.h ../include/x86/mapping.h \ + ../include/x86/space.h ../include/x86/thread.h ../include/tcb_layout.h \ + ../include/kdebug.h ../include/x86/kdebug.h +x86_smp.o: x86_smp.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h kdebug.h +x86_tracestore.o: x86_tracestore.c ../include/universe.h \ + ../include/config.h ../include/macros.h ../include/types.h \ + ../include/kernel.h ../include/x86/config.h ../include/x86/cpu.h \ + ../include/lib.h ../include/sync.h ../include/x86/notify.h \ + ../include/kmemory.h ../include/thread.h ../include/ipc.h \ + ../include/tcb.h ../include/x86/tcb.h ../include/schedule.h \ + ../include/interrupt.h ../include/x86/memory.h ../include/x86/mapping.h \ + ../include/x86/space.h ../include/x86/thread.h ../include/tcb_layout.h \ + ../include/kdebug.h ../include/x86/kdebug.h diff --git a/kernel/kdb/Makefile b/kernel/kdb/Makefile new file mode 100644 index 0000000..044818d --- /dev/null +++ b/kernel/kdb/Makefile @@ -0,0 +1,31 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.13 2001/11/22 13:41:18 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +OBJ_SRC = +LIB_SRC = print.c mini-kd.c gdb.c mdb.c init.c input.c tracepoints.c \ + new-kdb.c interrupt.c tracing.c \ + $(wildcard $(ARCH).c $(ARCH)-$(PLATFORM).c) \ + $(wildcard asm-$(ARCH).S asm-$(ARCH)-$(PLATFORM).S) \ + $(wildcard $(ARCH)_*.c) +LIB = libkdb.a + +###################################################################### +# includes +include ../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/kdb/arm-brutus.c b/kernel/kdb/arm-brutus.c new file mode 100644 index 0000000..0d5fbab --- /dev/null +++ b/kernel/kdb/arm-brutus.c @@ -0,0 +1,13 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm-brutus.c + * Description: wrapper for SA-1100 specific KDB code + * + * @LICENSE@ + * + * $Id: arm-brutus.c,v 1.1 2002/01/24 20:39:17 ud3 Exp $ + * + ********************************************************************/ +#include "arm-sa1100.c" diff --git a/kernel/kdb/arm-dnard.c b/kernel/kdb/arm-dnard.c new file mode 100644 index 0000000..cc6d5cf --- /dev/null +++ b/kernel/kdb/arm-dnard.c @@ -0,0 +1,91 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm-dnard.c + * Description: Kdebug interface for the Dnard. + * + * @LICENSE@ + * + * $Id: arm-dnard.c,v 1.7 2001/12/13 12:26:37 ud3 Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) +#define COMPORT CONFIG_DEBUGGER_COMPORT +#define RATE CONFIG_DEBUGGER_COMSPEED + +#define DATA(x) (*(volatile byte_t*) ((x))) +#define STATUS(x) (*(volatile byte_t*) ((x)+5)) + + +void kdebug_init_serial() +{ + + printf("%s(%x,%d)\n", __FUNCTION__, COMPORT, RATE); + +#define IER (COMPORT+1) +#define EIR (COMPORT+2) +#define LCR (COMPORT+3) +#define MCR (COMPORT+4) +#define LSR (COMPORT+5) +#define MSR (COMPORT+6) +#define DLLO (COMPORT+0) +#define DLHI (COMPORT+1) + + outb(LCR, 0x80); /* select bank 1 */ + outb(DLLO, (((115200/RATE) >> 0) & 0x00FF)); + outb(DLHI, (((115200/RATE) >> 8) & 0x00FF)); + outb(LCR, 0x03); /* set 8,N,1 */ + for (volatile int i = 10000; i--; ); + outb(EIR, 0x07); /* enable FIFOs */ + outb(IER, 0x00); /* enable RX interrupts */ + + inb(IER); + inb(EIR); + inb(LCR); + inb(MCR); + inb(LSR); + inb(MSR); +} +#endif + +#if defined(CONFIG_DEBUGGER_IO_OUTCOM) +void putc(char c) +{ + while (!(inb(COMPORT+5) & 0x60)); + outb(COMPORT,c); + + if (c == '\n') + putc('\r'); +}; +#endif + +#if defined(CONFIG_DEBUGGER_IO_INCOM) +char getc(void) +{ + while (!(inb(COMPORT+5) & 0x01)); + return inb(COMPORT); +}; +#endif + +#if defined(CONFIG_DEBUG_BREAKIN) +void kdebug_check_breakin() +{ + if ((inb(COMPORT+5) & 0x01)) + { + if (inb(COMPORT) == 0x1b) + enter_kdebug("breakin"); + } +} +#endif + +void kdebug_hwreset() +{ + outw(0x24, 0x09); + outw(0x26, inw(0x26) | (1<<3) | (1<<10)); + /* it will take a while */ + while (1); +} + diff --git a/kernel/kdb/arm-ep7211.c b/kernel/kdb/arm-ep7211.c new file mode 100644 index 0000000..7b43e33 --- /dev/null +++ b/kernel/kdb/arm-ep7211.c @@ -0,0 +1,97 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm-ep7211.c + * Description: Kdebug interface for the EP7211. + * + * @LICENSE@ + * + * $Id: arm-ep7211.c,v 1.7 2001/12/11 23:11:50 ud3 Exp $ + * + ********************************************************************/ +#include + +#define HWBASE 0xFFF00000 + +#define HWBASE1 (HWBASE + 0x00000000) +#define HWBASE2 (HWBASE + 0x00001000) + +#define DATA(x) (*(volatile dword_t*) (((x)+0x480))) +#define STATUS(x) (*(volatile dword_t*) (((x)+0x140))) + +#define UTXFF (1 << 23) +#define URXFE (1 << 22) + +#if defined(CONFIG_DEBUGGER_IO_OUTCOM) +void putc(char c) +{ + while (STATUS(HWBASE2) & UTXFF); + DATA(HWBASE2) = c; + + if (c == '\n') + putc('\r'); +} +#endif /* defined(CONFIG_DEBUGGER_IO_OUTCOM) */ + + +#if defined(CONFIG_DEBUGGER_IO_INCOM) +char getc(void) +{ + while (STATUS(HWBASE2) & URXFE); + return DATA(HWBASE2); +}; +#endif /* defined(CONFIG_DEBUGGER_IO_INCOM) */ + +#if defined(CONFIG_DEBUG_BREAKIN) +void kdebug_check_breakin() +{ +#if defined(CONFIG_DEBUGGER_IO_INCOM) + if (!(STATUS(HWBASE2) & URXFE)) + { + if ((DATA(HWBASE2) & 0xFF) == 0x1b) + enter_kdebug("breakin"); + } +#endif +} +#endif + + + +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) +#define RATE CONFIG_DEBUGGER_COMSPEED + +void kdebug_init_serial(void) +{ + printf("%s\n", __FUNCTION__); +#if 0 + +#define PRTEN 1<<13 +#define EVENPTR 1<<14 +#define XSTOP 1<<15 +#define FIFOEN 1<<16 +#define WRDLEN 3<<17 /* 8 Bit word length*/ + + /* enabling Serial port 2 */ + dword_t + dword_t t=indw(SYSCON2+IO_VBASE); + t=t|(1<<2); + outdw(SYSCON2, t); + + /* programming bit rate and line ctl + FIFO disabled */ + dword_t p=(RATE/115200)|WRDLEN; + outdw(COM2_BASE+IO_VBASE, p); + +#endif + TRACE(); +} + + +#endif /* defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) */ + + +void kdebug_hwreset() +{ + panic(__FUNCTION__); +} + diff --git a/kernel/kdb/arm-ipaq.c b/kernel/kdb/arm-ipaq.c new file mode 100644 index 0000000..3f93092 --- /dev/null +++ b/kernel/kdb/arm-ipaq.c @@ -0,0 +1,13 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm-ipaq.c + * Description: wrapper for SA-1100 specific KDB code + * + * @LICENSE@ + * + * $Id: arm-ipaq.c,v 1.1 2002/01/24 21:11:13 ud3 Exp $ + * + ********************************************************************/ +#include "arm-sa1100.c" diff --git a/kernel/kdb/arm-pleb.c b/kernel/kdb/arm-pleb.c new file mode 100644 index 0000000..adbe2e9 --- /dev/null +++ b/kernel/kdb/arm-pleb.c @@ -0,0 +1,13 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm-pleb.c + * Description: wrapper for SA-1100 specific KDB code + * + * @LICENSE@ + * + * $Id: arm-pleb.c,v 1.1 2002/01/24 20:37:12 ud3 Exp $ + * + ********************************************************************/ +#include "arm-sa1100.c" diff --git a/kernel/kdb/arm-sa1100.c b/kernel/kdb/arm-sa1100.c new file mode 100644 index 0000000..4a7c29f --- /dev/null +++ b/kernel/kdb/arm-sa1100.c @@ -0,0 +1,103 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm-brutus.c + * Description: Kdebug interface for the Brutus. + * + * @LICENSE@ + * + * $Id: arm-sa1100.c,v 1.9 2001/12/12 23:05:28 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_PLATFORM(platform.h) +#include INC_PLATFORM(uart.h) + + +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) + +# define BRD L4_BAUDRATE_TO_BRD(CONFIG_DEBUGGER_COMSPEED) + +void kdebug_init_serial(void) +{ + dword_t enbl = 0; + +#if defined(CONFIG_DEBUGGER_IO_INCOM) + enbl |= L4_UART_RXE; +#endif +#if defined(CONFIG_DEBUGGER_IO_OUTCOM) + enbl |= L4_UART_TXE; +#endif + +// printf("%s(%d)\n", __FUNCTION__, CONFIG_DEBUGGER_COMSPEED); +// for (volatile int i = 10000; i--; ); + + L4_UART_UTCR3 = 0; /* Diable UART */ + L4_UART_UTSR0 = 0xf; /* Clear pending interrupts */ + + L4_UART_UTCR0 = L4_UART_DSS; /* No parity, 1 stop bit, 8 bit */ + L4_UART_UTCR1 = BRD >> 8; /* Set baudrate */ + L4_UART_UTCR2 = BRD & 0xff; + L4_UART_UTCR3 = enbl; /* Enable UART */ + +// for (volatile int i = 10000; i--; ); +} +#endif + + +void putc(char chr) +{ + volatile dword_t tmp; + + /* + * Wait till the transmit FIFO has a free slot. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_TNF) ); + + /* + * Add the character to the transmit FIFO. + */ + L4_UART_UTDR = (dword_t) chr; + + if (chr == '\n') + putc('\r'); +} + +char getc(void) +{ + volatile dword_t tmp; + + /* + * Wait till the receive FIFO has something in it. + */ + do { + tmp = L4_UART_UTSR1; + } while ( !(tmp & L4_UART_RNE) ); + + /* + * Read a character from the receive FIFO. + */ + return (char) L4_UART_UTDR; +} + +#if defined(CONFIG_DEBUG_BREAKIN) +void kdebug_check_breakin() +{ + /* Check if the receive FIFO has something in it. */ + if ( L4_UART_UTSR1 & L4_UART_RNE) + /* Check if it's an ESC. */ + if ((char) L4_UART_UTDR == 0x1b) + enter_kdebug("breakin"); +} +#endif + +void kdebug_hwreset() +{ + *(ptr_t) RSTCTL_VBASE = 1; + while (1); +} + + diff --git a/kernel/kdb/arm.c b/kernel/kdb/arm.c new file mode 100644 index 0000000..2706661 --- /dev/null +++ b/kernel/kdb/arm.c @@ -0,0 +1,244 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm.c + * Description: ARM specific kdebug stuff. + * + * @LICENSE@ + * + * $Id: arm.c,v 1.25 2001/12/13 03:06:05 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) +#include INC_PLATFORM(platform.h) +#include "kdebug.h" + + + + + +extern void kdebug_init_serial(); +void kdebug_init_arch() +{ +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) + kdebug_init_serial(); +#endif +} + +#if defined(CONFIG_DEBUGGER_KDB) +int kdebug_arch_entry(exception_frame_t* frame) +{ + if ((frame->spsr & 0x1F) == 0x10) /* called from user mode */ + { + if (((*(ptr_t)frame->r14) >> 24) == 0xEA) + { + printf("%s", (char*) (frame->r14 + 4)); + return 0; + }; + if (((*(ptr_t)frame->r14) >> 16) == 0xE35E) + switch ((*(ptr_t)frame->r14) & 0xFFFF) + { + case 0: /* outchar */ + putc(frame->r0 & 0xff); + return 1; + case 2: /* outstring */ + printf((char*)frame->r0); + return 1; + case 5: /* outhex32 */ + printf("%x", frame->r0); + return 1; + case 11: /* outdec */ + printf("%d", frame->r0); + return 1; + case 13: + frame->r0 = getc(); + return 1; + default: + printf ("Unknown kdebug command: %x\n", + (*(ptr_t)frame->r14) & 0xFFFF); + return 0; + }; + } + return 0; +} + +void kdebug_arch_exit(exception_frame_t* frame) +{ + return; +}; + +void kdebug_perfmon() +{ + return; +} + +void kdebug_dump_pgtable(ptr_t pgtable) +{ + + int start=0; int entries=FLD_MAX; + fld_t* page_dir = (fld_t*) phys_to_virt(pgtable); + int i, j; + sld_t *page_table; + + printf("\nLevel 1 Page Table Dump at %x\n", (int)page_dir); + for( i = start; (i < FLD_MAX) && (entries > 0); i++, entries-- ) + switch (page_dir[i].invalid.type) { + case FLD_SECTION: + printf("%x -> %x (1M), Dom %x, ", fld_to_vaddr(i), page_dir[i].init, + page_dir[i].section.domain); + switch (page_dir[i].section.ap) { + case AP_RESTRICTED: + printf("AP_RESTRICTED "); + break; + case AP_NOACCESS: + printf("AP_NOACCESS "); + break; + case AP_READACCESS: + printf("AP_READACCESS "); + break; + case AP_ALLACCESS: + printf("AP_ALLACCESS "); + break; + } + printf("\n"); + break; + case FLD_PAGE: + printf("%x -> Page, Dom %x, entry %x\n", fld_to_vaddr(i), + page_dir[i].page.domain, page_dir[i].init); + page_table = + (sld_t *)phys_to_virt(ptba_to_paddr(page_dir[i].page.ptba)); + printf("\tLevel 2 Page Table Dump at %x\n", (int)page_table); + for(j = 0; j < SLD_MAX; j++) + switch (page_table[j].invalid.type) { + case SLD_SMALL: + printf("\t%x -> %x (4K), ", + (fld_to_vaddr(i)|sld_to_vaddr(j)), + page_table[j].init); + switch (page_table[j].small.ap0) { + case AP_RESTRICTED: + printf("AP_RESTRICTED, "); + break; + case AP_NOACCESS: + printf("AP_NOACCESS, "); + break; + case AP_READACCESS: + printf("AP_READACCESS, "); + break; + case AP_ALLACCESS: + printf("AP_ALLACCESS, "); + break; + } + printf("\n"); + break; + case SLD_LARGE: + printf("\t%x -> %x (64K), ", + (fld_to_vaddr(i) | sld_to_vaddr(j)), + page_table[j].init); + switch (page_table[j].large.ap0) { + case AP_RESTRICTED: + printf("AP_RESTRICTED, "); + break; + case AP_NOACCESS: + printf("AP_NOACCESS, "); + break; + case AP_READACCESS: + printf("AP_READACCESS, "); + break; + case AP_ALLACCESS: + printf("AP_ALLACCESS, "); + break; + } + printf("\n"); + j += LRG_ENTS; + break; + } + break; + } + printf("\n"); +} + +void kdebug_dump_frame(exception_frame_t *frame) +{ + dword_t fsr, far; + __asm__ __volatile__ + ("mrc p15, 0, %0, c5, c0 \n\t" + "mrc p15, 0, %1, c6, c0 \n\t" + : "=r" (fsr), "=r" (far)); + + printf("frame: %p excp no: %x\n", frame, frame->excp_no); + printf(" r0 %x %x %x %x\n", + frame->r0, frame->r1, frame->r2, frame->r3); + printf(" r4 %x %x %x %x\n", + frame->r4, frame->r5, frame->r6, frame->r7); + printf(" r8 %x %x %x %x\n", + frame->r8, frame->r9, frame->r10, frame->r11); + printf(" r12 %x %x %x\n", + frame->r12, frame->r13, frame->r14); + printf("spsr %x lr %x far %x\n", frame->spsr, frame->lr, far); + printf("cpsr %x sp %x fsr %x\n", frame->cpsr, frame->sp, fsr); + +} + + +void kdebug_pf_tracing(int state) +{ + extern int __kdebug_pf_tracing; + __kdebug_pf_tracing = state; +} + +void kdebug_single_stepping(exception_frame_t *frame, dword_t onoff) +{ +} + +void kdebug_breakpoint() +{ +} + +void kdebug_arch_help() +{ +} + +void kdebug_cpustate(tcb_t *current) +{ +} + +#endif /* CONFIG_DEBUGGER_KDB */ + +int kdebug_step_instruction(exception_frame_t * frame) +{ + printf("s - Unsupported\n"); + return 0; +} + +int kdebug_step_block(exception_frame_t * frame) +{ + printf("S - Unsupported\n"); + return 0; +} + + +void kdebug_disassemble(exception_frame_t * frame) +{ +#if defined(CONFIG_DEBUG_DISAS) + extern int arm_disas(dword_t pc); + char c; + dword_t pc; + restart: + printf("ip [current]: "); + pc = kdebug_get_hex(frame->r14, "current"); + do { + printf("%x:\t", pc); + pc += arm_disas(pc); + printf("\n"); + c = getc(); + } while ((c != 'q') && (c != 'u')); + if (c == 'u') + goto restart; +#endif +}; + + + + diff --git a/kernel/kdb/arm_dis.c b/kernel/kdb/arm_dis.c new file mode 100644 index 0000000..2ba51c9 --- /dev/null +++ b/kernel/kdb/arm_dis.c @@ -0,0 +1,18 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm_dis.c + * Description: Disassembler wrapper for ARM. + * + * @LICENSE@ + * + * $Id: arm_dis.c,v 1.1 2001/12/13 03:04:02 ud3 Exp $ + * + ********************************************************************/ +#include +#include "kdebug.h" + +#if defined(CONFIG_DEBUG_DISAS) +#include "../contrib/arm_dis.c" +#endif diff --git a/kernel/kdb/asm-x86.S b/kernel/kdb/asm-x86.S new file mode 100644 index 0000000..df58202 --- /dev/null +++ b/kernel/kdb/asm-x86.S @@ -0,0 +1,297 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: asm-x86.S + * Description: X86-specifc glue for the kernel debugger. + * + * @LICENSE@ + * + * $Id: asm-x86.S,v 1.11 2001/12/04 21:18:22 uhlig Exp $ + * + ********************************************************************/ +#include +#include +#include +#include + +#if (__GNUC__ >= 3) +# define KDEBUG_INIT _Z11kdebug_initv +# define KMEM_ALLOC _Z10kmem_allocj +# define TRACE_PF_HANDLER _Z16tracs_pf_handlerjjjjj +# define TRACE_IPC_HANDLER _Z17trace_ipc_handllerjjjjjjj +# define PMC_OVERFLOW_HANDLER _Z20pmc_overflow_handlerv +# define TRACE_EXCEPTION_HANDLER _Z17exception_handlerP17exception_frame_t +#else +# define KDEBUG_INIT kdebug_init__Fv +# define KMEM_ALLOC kmem_alloc__FUi +# define TRACE_PF_HANDLER trace_pf_handler__FUiUiUiUiUi +# define TRACE_IPC_HANDLER trace_ipc_handler__FUiUiUiUiUiUiUi +# define PMC_OVERFLOW_HANDLER pmc_overflow_handler__Fv +# define TRACE_EXCEPTION_HANDLER exception_handler__FP17exception_frame_t +#endif + +/* + * Define to keep the old copy of the stack contents. Useful if one + * catches faults inside KDB. + */ +//#define KEEP_OLD_STACK_CONTENTS + +#if defined(CONFIG_X86_P4_BTS) +# define DEBUGCTL_MASK (~0x0d) +#else +# define DEBUGCTL_MASK (~0x01) +#endif + +#if defined(CONFIG_KEEP_LAST_BRANCHES) || defined(CONFIG_X86_P4_BTS) +#define clr_dbgctl() \ + mov $IA32_DEBUGCTL, %ecx ; \ + rdmsr ; \ + andl $DEBUGCTL_MASK, %eax ; \ + wrmsr +#define set_dbgctl() \ + mov $IA32_DEBUGCTL, %ecx ; \ + rdmsr ; \ + movl x86_debugctl_state, %ebx ; \ + orl %ebx, %eax ; \ + wrmsr +#else +#define clr_dbgctl() +#define set_dbgctl() +#endif + +#define ENTRY(name) \ + .globl name; \ + .align 4; \ + name##: + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +#define EXCEPTION_EC(num)\ + pusha;\ + pushl %ds;\ + pushl %es;\ + pushl $##num;\ + pushl %esp;\ + call TRACE_EXCEPTION_HANDLER;\ + addl $8, %esp;\ + popl %es;\ + popl %ds;\ + popa;\ + addl $4, %esp;\ + iret + + +#define DEF_EXC_EC(num, entry) \ + ENTRY(entry) EXCEPTION_EC(num) + +#define EXCEPTION(num)\ + pushl $0;\ + pusha;\ + pushl %ds;\ + pushl %es;\ + pushl $##num;\ + pushl %esp;\ + call TRACE_EXCEPTION_HANDLER; \ + addl $8, %esp;\ + popl %es;\ + popl %ds;\ + popa;\ + addl $4, %esp;\ + iret + + +#define DEF_EXC(num, entry) \ + ENTRY(entry) EXCEPTION(num) +#endif /*new debugger*/ + +#define ke(text) \ + int $3 ; \ + jmp 9f ; \ + .ascii text ; \ +9: + + .section .kdebug + +ENTRY(int_1) + pushl $0x0 + pusha + pushl %ds + pushl %es + pushl $1 + jmp 0f + +ENTRY(int_2) + pushl $0x0 + pusha + pushl %ds + pushl %es + pushl $2 + jmp 0f + + +ENTRY(int_3) + pushl $0x0 + pusha + pushl %ds + pushl %es + pushl $3 + +0: +#if defined(CONFIG_ENABLE_SMALL_AS) + mov $X86_KDS, %eax + mov %eax, %ds + mov %eax, %es +#endif + +#if defined(CONFIG_SMP) +enter_smp: + mov %esp, %eax + andl $L4_TCB_MASK, %eax + movl OFS_TCB_INTR_PENDING+4(%eax), %ebx + movl $-1, %eax /* -1 no one in lock */ + lock cmpxchg %ebx, %ss:_kdebug_spinlock + jz 2f +1: + cmp $-1, %ss:_kdebug_spinlock + je exit_smp + + /* check if our cpu id is in the spinlock */ + cmp %ebx, %ss:_kdebug_spinlock + jne 1b +2: + lock incl %ss:_kdebug_counter +#endif + + clr_dbgctl() + + cmpl $KDEBUG_INIT, %ss:(kernel_info_page + 0x10) + je 2f + call *%ss:(kernel_info_page + 0x14) +2: + mov %esp, %ss:_kdebug_saved_esp + mov $_kdebug_stack_top, %esp + pushl _kdebug_saved_esp +#if defined(KEEP_OLD_STACK_CONTENTS) + cmpl $_kdebug_stack_bottom, (%esp) + jl 4f + movl $_kdebug_stack_bottom, %esi + movl $_kdebug_old_stack, %edi + movl $256, %ecx + rep + movsl %ds:(%esi), %es:(%edi) + addl $(_kdebug_old_stack-_kdebug_stack_bottom), (%esp) +4: +#endif + call *%ss:(kernel_info_page + 0x14) + mov %ss:_kdebug_saved_esp, %esp + +#if defined(CONFIG_SMP) + movl %eax, %ss:(_kdebug_spinlock) + /*lock decl %ss:_kdebug_counter*/ + cmp $-1, %eax + jne enter_smp +exit_smp: + +/* + lock btrl $0, %ss:_kdebug_spinlock +3: cmpl $0, %ss:_kdebug_counter + jne 3b */ +#endif + + set_dbgctl() + addl $4, %esp + popl %es + popl %ds + popa + addl $4,%esp + iret + + + +ENTRY(grabpage__Fv) + /* save the registers the callee doesn't save itself */ + pushl %ecx + pushl %edx + pushl $4096 + call KMEM_ALLOC + subl $KERNEL_OFFSET, %eax + addl $4,%esp + popl %edx + popl %ecx + ret + +_kdebug_spinlock: + .long -1 +_kdebug_counter: + .long 0 + + .section .kdebug-bss + .global _kdebug_stack_bottom + .global _kdebug_stack_top + .global _kdebug_saved_esp + .align 16 +_kdebug_stack_bottom: + .space 1024 +_kdebug_stack_top: + +#if defined(KEEP_OLD_STACK_CONTENTS) +_kdebug_old_stack: + .space 1024 +#endif + +#if defined(CONFIG_KEEP_LAST_BRANCHES) || defined(CONFIG_X86_P4_BTS) + .global x86_debugctl_state +x86_debugctl_state: + .long 0 +#endif + +_kdebug_saved_esp: + .long 0 + +/* the assembler stubs for the new debugger */ + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + .section .kdebug + +DEF_EXC(0, monitor_int_0) +DEF_EXC(4, monitor_int_4) +DEF_EXC(5, monitor_int_5) +DEF_EXC(6, monitor_int_6) +DEF_EXC(7, monitor_int_7) +DEF_EXC_EC(8, monitor_int_8) +DEF_EXC(9, monitor_int_9) +DEF_EXC_EC(10, monitor_int_10) +DEF_EXC_EC(11, monitor_int_11) +DEF_EXC_EC(12, monitor_int_12) +DEF_EXC(16, monitor_int_16) +DEF_EXC_EC(17, monitor_int_17) +DEF_EXC_EC(18, monitor_int_18) +DEF_EXC(19, monitor_int_19) + + +ENTRY(trace_pf) + pushl %eax + pushl %ecx + pushl %edx + call TRACE_PF_HANDLER + popl %edx + popl %ecx + popl %eax + jmp (original_int_14) + + +ENTRY(trace_ipc) + pusha + call TRACE_IPC_HANDLER + popa + jmp (original_int_48) + + +ENTRY(apic_pmc_of_int) + pusha + call PMC_OVERFLOW_HANDLER + popa + iret + + +#endif /* defined(CONFIG_DEBUGGER_NEW_KDB) */ diff --git a/kernel/kdb/asm-x86.o b/kernel/kdb/asm-x86.o new file mode 100644 index 0000000..c300f09 Binary files /dev/null and b/kernel/kdb/asm-x86.o differ diff --git a/kernel/kdb/gdb.c b/kernel/kdb/gdb.c new file mode 100644 index 0000000..27275f2 --- /dev/null +++ b/kernel/kdb/gdb.c @@ -0,0 +1,452 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: gdb.c + * Description: GDB interface for the kernel debugger. + * + * @LICENSE@ + * + * $Id: gdb.c,v 1.3 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_DEBUGGER_GDB) +#include "kdebug.h" + +dword_t __kdebug_ipc_tracing = 0; +dword_t __kdebug_ipc_tr_mask = 0; +dword_t __kdebug_ipc_tr_thread = 0; +dword_t __kdebug_ipc_tr_dest = 0; +dword_t __kdebug_ipc_tr_this = 0; +int __kdebug_pf_tracing = 0; + +#if defined(CONFIG_DEBUG_TRACE_MDB) +int __kdebug_mdb_tracing = 0; +#endif + +static char * hexchars = "0123456789abcdef"; +l4_threadid_t gdb_current_thread; + +struct last_ipc_t +{ + l4_threadid_t myself; + l4_threadid_t dest; + dword_t snd_desc; + dword_t rcv_desc; + dword_t ipc_buffer[3]; + dword_t ip; +} last_ipc; + +void panic(const char *msg) +{ + printf("panic: %s", msg); + enter_kdebug("panic"); + while(1); +} + +static int hex(char c) +{ + if ((c >= 'a') && (c <= 'f')) return (c-'a'+10); + if ((c >= '0') && (c <= '9')) return (c-'0'); + if ((c >= 'A') && (c <= 'F')) return (c-'A'+10); + return (-1); +} + +static void int2hex(int val, unsigned char * buf) +{ + buf[0] = hexchars[(val >> 4) & 0xf]; + buf[1] = hexchars[(val >> 0) & 0xf]; +} + +static int mem2hex(unsigned char * addr, unsigned char * buf, int count) +{ + while(count) + { + int2hex(*addr, buf); + addr++; + buf+=2; + count--; + } + *buf = 0; + return 1; +} + +static int string_to_int(unsigned char * str) +{ + int val = 0; + unsigned char * tmp = str; + while(*tmp) + { + switch(*tmp) + { + case '0' ... '9': + val = val * 16 + (*tmp - '0'); break; + case 'a' ... 'f': + val = val * 16 + (*tmp - 'a' + 10); break; + case 'A' ... 'F': + val = val * 16 + (*tmp - 'A' + 10); break; + case '-': + break; + default: + return val; + } + tmp++; + } + + if (str[0] == '-') + return 0 - val; + else + return val; +} + +int strncmp(const char * s1, const char * s2, int len) +{ + for (int i = 0; i < len; i++) + { + if (s1[i] < s2[i]) return -1; + if (s1[i] > s2[i]) return 1; + } + return 0; +} + +void serial_putc(const char c); +char serial_getc(void); + +#define GDBSPIN do { spin1(23); } while(0) +#define GDB_BUF_SIZE 128 +#define GDB_GETC serial_getc +#define GDB_PUTC serial_putc +static unsigned char gdb_buffer[GDB_BUF_SIZE]; + +void gdb_send_response(char * msg = NULL) +{ + unsigned char checksum; + + /* $#. */ + do { + GDB_PUTC('$'); + checksum = 0; + unsigned char * buf = msg ? (unsigned char*)msg : gdb_buffer; + + while ( *buf ) + { + GDB_PUTC( *buf ); + checksum += *buf; + buf++; + } + + GDB_PUTC('#'); + GDB_PUTC(hexchars[checksum >> 4]); + GDB_PUTC(hexchars[checksum % 16]); + } while ( GDB_GETC() != '+' ); +} + +static unsigned char * gdb_receive_request() +{ + unsigned char checksum; + unsigned char rcv_checksum; + int count; + char c; + + + while(1) + { + // wait for start character + while ( GDB_GETC() != '$' ) GDBSPIN; + + restart: + checksum = 0; + count = 0; + + // now receive message into buffer + while ( count < GDB_BUF_SIZE ) + { + c = GDB_GETC(); + GDBSPIN; + if (c == '$') + goto restart; + + if (c == '#') + { + // mark end of message + gdb_buffer[count] = 0; + + rcv_checksum = ( hex(GDB_GETC()) << 4 ) + hex(GDB_GETC()); + if ( rcv_checksum != checksum) + { + // invalid checksum + GDB_PUTC('-'); + break; + } + else + { + GDB_PUTC('+'); + return &gdb_buffer[0]; + } + } + + // special handling for 0x7d!!! + if (c == 0x7d) + { + checksum = checksum + c; + c = GDB_GETC(); + } + + // now the default handling - add char to buffer + checksum = checksum + c; + gdb_buffer[count] = c; + count = count + 1; + } + } +} + +static void gdb_send_registers(exception_frame_t * frame) +{ + struct { + dword_t eax, ecx, edx, ebx, esp, ebp, esi, edi; + dword_t eip, flags; + dword_t cs, ss, ds, es, fs, gs; + } registers = { + frame->eax, frame->ecx, frame->edx, frame->ebx, frame->esp, + frame->ebp, frame->esi, frame->edi, + frame->fault_address, frame->eflags, + frame->cs, frame->ss, frame->ds, frame->es, 0 , 0}; + mem2hex((unsigned char*)®isters, gdb_buffer, sizeof(registers)); + gdb_send_response(); +} + +static void gdb_send_mem(unsigned char * addr, int len) +{ + //printf("gdb_send_mem(%p, %x)\n", addr, len); + if ((addr > (unsigned char*)TCB_AREA) && + len > 0 ) + { + // XXX: check pagetable!!! + mem2hex(addr, gdb_buffer, len); + gdb_send_response(); + } + else + gdb_send_response("E00"); +} + +void kdebug_entry(exception_frame_t* frame) +{ + if (kdebug_arch_entry(frame) == 0) + { + printf("gdb-debug entry\n"); + gdb_send_response("S05"); + + int exit_kdb = 0; + while( !exit_kdb ) + { + unsigned char * buf = gdb_receive_request(); + //printf("gdb-cmd: %s\n", buf); + + switch(buf[0]) + { + case '?': + gdb_send_response("S00"); // reason for stopping + break; + + case 'c': + case 'D': + if (buf[1] != 0) + printf("continue at some address not supported yet - ignored\n"); + kdebug_single_stepping(frame, 0); // disable single stepping + exit_kdb = 1; + break; + + case 'm': + { + /* format: mnnn,size */ + unsigned char * addr = (unsigned char*)string_to_int(&buf[1]); + unsigned char * tmp; + int len = 0; + /* now try to find "," */ + for (tmp = &buf[2]; *tmp && *tmp != ','; tmp++); + if (*tmp == ',') + { + tmp++; + len = string_to_int(tmp); + } + // sending with len 0 is invalid!!! + gdb_send_mem(addr, len); + break; + } + case 'X': + { + /* format: Maddr,len:val */ + unsigned char * addr = (unsigned char*)string_to_int(&buf[1]); + if (addr < (unsigned char*)TCB_AREA) + { + gdb_send_response("E00"); + break; + } + + unsigned char * tmp; + int len = 0; + + /* now find "," */ + for (tmp = &buf[2]; *tmp && *tmp != ','; tmp++); + if (*tmp == ',') + { + tmp++; + len = string_to_int(tmp); + /* and finally the data */ + while(*tmp && *tmp != ':') tmp++; + if (*tmp == ':') + { + /* here follows the data */ + tmp++; + printf("set memory @%x, len=%x, val=%s\n", + addr, len, tmp); + + while(len) + { + printf("set mem %p to %x\n", addr, *tmp); + (*addr) = (*tmp); + addr++;tmp++; + len--; + } + gdb_send_response("OK"); + break; + } + } + gdb_send_response("E00"); + } break; + case 'H': + switch(buf[1]) + { + case 'c': { + if (buf[2] == '-' && buf[3] == '1') + gdb_current_thread = L4_INVALID_ID; + else + gdb_current_thread.id.thread = string_to_int(&buf[2]); + gdb_send_response("OK"); + } break; + case 'g': + gdb_send_response("E01"); // not implemented + break; + } break; // 'H' + + case 'g': + gdb_send_registers(frame); + break; + + case 'P': // set register value + { + if (buf[3] != '=') { + int reg = string_to_int(&buf[1]); + int val = string_to_int(&buf[4]); + + switch(reg) + { + case 0: frame->eax = val; break; + case 1: frame->ecx = val; break; + case 2: frame->edx = val; break; + case 3: frame->ebx = val; break; + case 4: frame->esp = val; break; + case 5: frame->ebp = val; break; + case 6: frame->esi = val; break; + case 7: frame->edi = val; break; + case 8: frame->fault_address = val; break; + case 9: frame->eflags = val; break; + case 10: frame->cs = val; break; + case 11: frame->ss = val; break; + case 12: frame->ds = val; break; + case 13: frame->es = val; break; + case 14: + case 15: + default: break; + } + gdb_send_response("OK"); + } + else gdb_send_response("E00"); + } + case 'q': + if (buf[1] == 'C') // get_current_thread + { + tcb_t *current = ptr_to_tcb((ptr_t) frame); + gdb_buffer[0] = 'Q'; gdb_buffer[1] = 'C'; + gdb_buffer[2] = hexchars[(current->myself.id.thread >> 12) & 0xf]; + gdb_buffer[3] = hexchars[(current->myself.id.thread >> 8) & 0xf]; + gdb_buffer[4] = hexchars[(current->myself.id.thread >> 4) & 0xf]; + gdb_buffer[5] = hexchars[(current->myself.id.thread >> 0) & 0xf]; + gdb_buffer[6] = 0; + gdb_send_response(); + break; + }; + if (strncmp((char*)&buf[1], "fThreadInfo", 11) == 0) + { + unsigned char * buf = gdb_buffer; + *buf++ = 'm'; + tcb_t * tcb = get_idle_tcb(); + while(tcb->present_next != get_idle_tcb()) + { + *buf++ = hexchars[(tcb->myself.id.thread >> 12) & 0xf]; + *buf++ = hexchars[(tcb->myself.id.thread >> 8) & 0xf]; + *buf++ = hexchars[(tcb->myself.id.thread >> 4) & 0xf]; + *buf++ = hexchars[(tcb->myself.id.thread >> 0) & 0xf]; + *buf++ = ','; + tcb = tcb->present_next; + } + *(buf-1) = 0; + gdb_send_response(); + break; + } + if (strncmp((char*)&buf[1], "sThreadInfo", 11) == 0) + { + // no more threads... + gdb_send_response("l"); + break; + } + if (strncmp((char*)&buf[1], "ThreadExtraInfo,",16) == 0) + { + l4_threadid_t tid = L4_NIL_ID; + tid.id.thread = string_to_int(&buf[18]); + tcb_t * tcb = tid_to_tcb(tid); + printf("ThreadExtraInfo: %p\n", tcb); + mem2hex((unsigned char*)"that is kind of interesting...", gdb_buffer, 30); + gdb_send_response(); + break; + } + gdb_send_response(""); + break; + + case 'k': + //kdebug_hwreset(); + break; + + case 's': /* single step */ + kdebug_single_stepping(frame, 1); + exit_kdb = 1; + break; + + case 'Z': + switch(buf[1]) { + case 0: // software breakpoint + + case 1: // hardware breakpoint + gdb_send_response("`'"); + break; + case 2: // write watchpoint + case 3: // read watchpoint + case 4: // access watchpoint + default: + gdb_send_response("`'"); + break; + } break; + default: + printf("unknown gdb command (%s)\n", buf); + gdb_send_response(""); + break; + } + } + } + kdebug_arch_exit(frame); +} + + +#endif /* CONFIG_DEBUGGER_GDB */ diff --git a/kernel/kdb/gdb.o b/kernel/kdb/gdb.o new file mode 100644 index 0000000..91e8e6f Binary files /dev/null and b/kernel/kdb/gdb.o differ diff --git a/kernel/kdb/init.c b/kernel/kdb/init.c new file mode 100644 index 0000000..85f6e4a --- /dev/null +++ b/kernel/kdb/init.c @@ -0,0 +1,32 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: init.c + * Description: Initialization functions for kdebug. + * + * @LICENSE@ + * + * $Id: init.c,v 1.4 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +void kdebug_init_arch(); + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +void init_tracing(); +int name_tab_index; +#endif + +void kdebug_init() +{ + kdebug_init_arch(); + kernel_info_page.kdebug_exception = (void (*)()) kdebug_entry; + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + //initialisation of the global variables + name_tab_index = 0; + init_tracing(); +#endif +} diff --git a/kernel/kdb/init.o b/kernel/kdb/init.o new file mode 100644 index 0000000..02cfe4b Binary files /dev/null and b/kernel/kdb/init.o differ diff --git a/kernel/kdb/input.c b/kernel/kdb/input.c new file mode 100644 index 0000000..c0060a1 --- /dev/null +++ b/kernel/kdb/input.c @@ -0,0 +1,387 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: input.c + * Description: Various kdebug input functions. + * + * @LICENSE@ + * + * $Id: input.c,v 1.14 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +#include "kdebug.h" + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + +void enter_string(char* str); +dword_t resolve_name(char* name); + +//name table +struct { + dword_t tid; + char name[9]; +} name_tab[32]; + +extern int name_tab_index; + +#endif + +tcb_t *kdebug_get_thread(tcb_t *current) +{ + l4_threadid_t tid; + + printf("Thread no [current]: "); + + tid.raw = kdebug_get_hex((dword_t) current, "current"); + if ( tid.raw < TCB_AREA ) tid.raw = (dword_t) tid_to_tcb(tid); + else tid.raw = (tid.raw & L4_TCB_MASK); + + return (tcb_t *) tid.raw; +} + + +tcb_t *kdebug_get_task(tcb_t *current) +{ + l4_threadid_t tid; + + printf("Task no [current]: "); + + tid.raw = kdebug_get_hex((dword_t) current, "current"); + if ( tid.raw < (1 << L4_X0_TASKID_BITS) ) + tid = (l4_threadid_t) { x0id: {0, 0, tid.raw, 0} }; + if ( tid.raw < TCB_AREA ) tid.raw = (dword_t) tid_to_tcb(tid); + tid.x0id.thread = 0; + tid.raw = (tid.raw & L4_TCB_MASK); + + return (tcb_t *) tid.raw; +} + +ptr_t kdebug_get_pgtable(tcb_t *current, char *str) +{ + tcb_t *tcb; + ptr_t pgtab; + int first_time; + + if ( str ) + printf("%s", str); + + pgtab = (ptr_t) kdebug_get_hex((dword_t) get_current_pgtable(), "current"); + + if ( (dword_t) pgtab < (1 << L4_X0_TASKID_BITS) ) + { + /* Seems like a task id. Search for valid thread. */ + for ( tcb = current, first_time = 1; + tcb != current || first_time; + tcb = tcb->present_next, first_time = 0 ) + if ( tcb->myself.x0id.task == (dword_t) pgtab) + { + pgtab = tcb->space->pagedir_phys (); + break; + } + } + else if ( (dword_t) pgtab < TCB_AREA ) + { + /* Might be a thread id. Search for match. */ + for ( tcb = current, first_time = 1; + tcb != current || first_time; + tcb = tcb->present_next, first_time = 0 ) + if ( tcb->myself.raw == (dword_t) pgtab) + { + pgtab = tcb->space->pagedir_phys (); + break; + } + } + else if ( ((dword_t) pgtab >= TCB_AREA && + (dword_t) pgtab < (TCB_AREA + TCB_AREA_SIZE)) ) + /* Pointer into TCB area. */ + pgtab = ((tcb_t *) ((dword_t) pgtab & L4_TCB_MASK))->space->pagedir_phys (); + else + /* Hopefully a valid page table address. */ + ; + + return pgtab; +} + +dword_t kdebug_get_hex(dword_t def, const char *str) +{ + dword_t val = 0; +#if !defined(CONFIG_DEBUGGER_NEW_KDB) + char t, c; +#endif + int i = 0; + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + char name[8]; + + enter_string(name); + if (name[0] != '\0') { + val = resolve_name(name); + i = 1; + } +#else + while ( (t = c = getc()) != '\r' ) + { + switch(c) + { + case '0' ... '9': c -= '0'; break; + case 'a' ... 'f': c -= 'a' - 'A'; + case 'A' ... 'F': c = c - 'A' + 10; break; + case 8: val >>= 4; i--; putc(8); putc(' '); putc(8); continue; + case 'x': if ( val == 0 && i == 1 ) { i--; putc('x'); } + default: continue; + } + val <<= 4; + val += c; + putc(t); + if ( ++i == 8 ) + break; + } +#endif + if ( i == 0 ) + { + /* No value given. Use default. */ + val = def; + if ( str ) printf("%s", str); + else printf("%x", val); + } + + putc('\n'); + return val; +} + + +dword_t kdebug_get_dec(dword_t def, const char *str) +{ + dword_t val = 0, no_input = 1; + char c; + + while ( (c = getc()) != '\r' ) + { + switch(c) + { + case '0' ... '9': + val = val * 10 + (c - '0'); + break; + default: + continue; + } + putc(c); + no_input = 0; + } + + if ( no_input ) + { + /* No value given. Use default. */ + val = def; + if ( str ) printf("%s", str); + else printf("%d", val); + } + + putc('\n'); + return val; +} + + + +static char *get_key_string(char key, const char *choices) L4_SECT_KDEBUG; + +char kdebug_get_choice(const char *str, const char *choices, + char def, int no_newline) +{ + char *p, c; + + printf("%s (%s)", str, choices); + if ( (p = get_key_string(def, choices)) ) + { + printf(" ["); + for (; *p != '/' && *p != 0; p++ ) + putc(*p >= 'A' && *p <= 'Z' ? (*p + ('a'-'A')) : *p); + putc(']'); + } + printf(": "); + + for (;;) + { + c = getc(); + p = get_key_string(c == '\r' ? def : c, choices); + for (; p && *p != '/' && *p != 0; p++ ) + putc(*p >= 'A' && *p <= 'Z' ? (*p + ('a'-'A')) : *p); + if ( p || c == '\r' ) + break; + } + + if ( ! no_newline ) + putc('\n'); + + return (c == '\r') ? def : c; +} + +static char *get_key_string(char key, const char *choices) +{ + const char *p; + + if ( key == 0 ) return NULL; + + for ( p = choices; *p; p++ ) + { + if ( (*p >= 'A' && *p <= 'Z') && (*p + ('a'-'A')) == key ) + break; + if ( (p == choices || p[-1] == '/') && (p[1] == 0 || p[1] == '/') && + (*p == key) ) + break; + } + + if ( *p == 0 ) return NULL; + while ( p > choices && p[-1] != '/' ) p--; + return (char *) p; +} + + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + +dword_t to_hex(char* name); + +void strcpy(char *dest, char *src) { + + int i = 0; + while (src[i]) { + dest[i] = src[i]; + i++; + } + dest[i] = '\0'; +} + +//other return value as known! +int strcmp(char *str1, char *str2) { + + int i = 0; + + while (str1[i] || str2[i]) { + if (str1[i] != str2[i]) + return 0; + i++; + } + return 1; +} + +//gives the tid of a thread +dword_t resolve_name(char* name) { + for (int i=0; i<32; i++) + if (strcmp(name_tab[i].name, name)) + return name_tab[i].tid; + //the thread has no name + return to_hex(name); +} + +//to use this in other functions too (e.g. exception monitoring) +//rest of restrict +//takes a string and converts it into a dword; +dword_t to_hex(char* name) { + char c; + dword_t res = 0; + + for (int i=0; name[i]; i++) {//until string not ended + c = name[i]; + if (c >= 48 &&c <= 57) c = c - 48; //0,..,9 + else if (c >= 97 && c <= 102) c = c - 87;//a,..,f + else { + printf("!!unknown name!!\n"); + return 0xffffffff; + } + if (i>=8) printf("warning: overrun in returned dword! first bits are lost!"); + res = res << 4;//works, because only the lowest 4 bits of c are used + res = res | c; + } + return res; +} + +void dump_names() { + putc('\n'); + //check, if the adress is in the pagetable of the thread!!! + for (int i=0; i> 4; + } + res[8] = '\0'; + return res; +} + +//backspace dosn't work... +void enter_string(char *str) { + char c; + int i = 0; + + while ( (c = getc()) != '\r' ) { + str[i] = c; + putc(c); + if (c == 0x08) i--; //backspace + if (++i == 8) { //to be able to delete the last character + if ( (c = getc()) == 0x08 ) { + putc(c); + i--; + } + else break; + } + } + str[i] = '\0'; + putc(' '); +} + +/** + * name a thread + **/ +void set_name() { + + int tmp = -1; + dword_t tid; + + if (name_tab_index > 31) { + enter_kdebug("too many names"); + return; + } + + printf("thread id: "); + tid = kdebug_get_hex(0xffffffff, "invalid"); + + //rename or new name? + for (int i=0; i +#if defined(CONFIG_DEBUGGER_NEW_KDB) + +#include "kdebug_keys.h" +#include "kdebug.h" + +extern dword_t get_pf_address(); +extern int pf_usermode(dword_t errcode); +extern dword_t rd_perfctr(int ctrsel); +extern dword_t rd_tsc(); +extern int is_restricted(dword_t tid, dword_t errcode, char type); +extern void trace(char type, dword_t args[10]); +extern dword_t get_user_time(); +ptr_t return_to;/*the address of the original handler after the + exception monitoring*/ +extern dword_t* original_interrupt[IDT_SIZE]; + +extern struct { + + struct { + unsigned use : 1; + unsigned to_do : 1; + unsigned restr : 1; + unsigned only_sendpart : 1; + } ipc; + + struct { + unsigned use : 1; + unsigned to_do : 1; + unsigned restr : 1; + } pf; + + struct { + unsigned use : 1; + unsigned to_do : 1; + unsigned restr : 1; + unsigned with_errcode : 1; + } exception; + +} trace_controlling; + +// the handler for pf_tracing +//this handler is never reached when pf_trace_mode == 1 (no tracing) +void trace_pf_handler(dword_t eax, dword_t ecx, dword_t edx, dword_t errcode, dword_t ip) { + + tcb_t * current = get_current_tcb(); + dword_t fault = (get_pf_address()); //the faultaddress + + //is the faulting thread restricted? if so, do nothing + //1 for restricted for pf + if (is_restricted(current->myself.raw, 0, K_MEM_PF_TRACE)) return; + + if (trace_controlling.pf.to_do == DISPLAY) { + printf("%s: thread: %p @ %x ip: %x, pager: %p\n" + " err: %x, cr3: %x\n", + pf_usermode(errcode) ? "UPF" : "KPF", current->myself.raw, fault, ip, current->pager.raw, + errcode, get_current_pgtable()); + + enter_kdebug("PF"); + } + else { + dword_t pmc_0, pmc_1, tsc; + qword_t dummy; + + dummy = rdpmc(0); + pmc_0 = ((dword_t*)dummy)[0]; + dummy = rdpmc(1); + pmc_1 = ((dword_t*)dummy)[0]; + dummy = rdtsc(); + tsc = ((dword_t*)dummy)[0]; + + dword_t args[10] = { + errcode, current->myself.raw, fault, ip, + current->pager.raw, (dword_t)&(* get_current_pgtable()), + tsc, +#if defined(CONFIG_ARCH_X86_I686) + pmc_0, pmc_1, +#else + 0, 0, +#endif +#if defined(CONFIG_SMP) + cpu_id +#endif + }; + trace('p', args); + } +} + + +// the handler for ipc_tracing +//this handler is never reached when ipc_trace_mode == 1 (no tracing) +void trace_ipc_handler(dword_t msg_w2, dword_t dest, dword_t rcv_desc, dword_t msg_w1, dword_t msg_w0, dword_t timeouts, dword_t snd_desc) { + + tcb_t * current = get_current_tcb(); + + //is the faulting thread restricted? if so, do nothing + //0 : restricted for ipc + if (is_restricted(current->myself.raw, snd_desc, K_KERNEL_IPC_TRACE)) return; + + if (trace_controlling.ipc.to_do == DISPLAY){ + printf("ipc: %p -> %p, snd_desc: %x rcv_desc: %x \n" + "(%x %x %x) - ip = %x\n", + current->myself.raw, dest, snd_desc, rcv_desc, + msg_w0, msg_w1, msg_w2, get_user_ip(current)); + + enter_kdebug("IPC"); + } + else { + dword_t pmc_0, pmc_1, tsc; + qword_t dummy; + + dummy = rdpmc(0); + pmc_0 = ((dword_t*)dummy)[0]; + dummy = rdpmc(1); + pmc_1 = ((dword_t*)dummy)[0]; + dummy = rdtsc(); + tsc = ((dword_t*)dummy)[0]; + + dword_t args[12] = { + current->myself.raw, dest, snd_desc, rcv_desc, msg_w0, + msg_w1, msg_w2, get_user_ip(current), timeouts, tsc +#if defined(CONFIG_ARCH_X86_I686) + , pmc_0, pmc_1, +#endif + }; + trace('i', args); + } +} + +//the handler for exception monitoring +void trace_exception_handler(exception_frame_t* frame) { + + dword_t vector_no, errcode, fault_address; + + vector_no = frame->fault_code; + errcode = frame->error_code; + fault_address = frame->fault_address; + + if (is_restricted(vector_no, errcode, K_KERNEL_EXCPTN_TRACE)) + return; + + if (trace_controlling.exception.to_do == DISPLAY){ + printf("exception %x @ %x error code %x\n", vector_no, fault_address, errcode); + + + enter_kdebug(); + } + else { + dword_t pmc_0, pmc_1, tsc; + qword_t dummy; + + dummy = rdpmc(0); + pmc_0 = ((dword_t*)dummy)[0]; + dummy = rdpmc(1); + pmc_1 = ((dword_t*)dummy)[0]; + dummy = rdtsc(); + tsc = ((dword_t*)dummy)[0]; + + dword_t args[11] = { + vector_no, fault_address, errcode, tsc, +#if defined(CONFIG_SMP) + cpu_id, +#else + 0, +#endif +#if defined(CONFIG_ARCH_X86_I686) + pmc_0, pmc_1, +#endif + 0, 0, 0 + }; + trace('e', args); + } + + //the address of the real handler + return_to = original_interrupt[vector_no]; +} + +//a handler for int 59 (the performancecounter overflow) +void pmc_overflow_handler() { + + dword_t pmc_0, pmc_1, tsc; + qword_t dummy; + + dummy = rdpmc(0); + pmc_0 = ((dword_t*)dummy)[0]; + dummy = rdpmc(1); + pmc_1 = ((dword_t*)dummy)[0]; + dummy = rdtsc(); + tsc = ((dword_t*)dummy)[0]; + + printf("pmc0: %x, pmc1: %x tsp: %x\n", pmc_0, pmc_1, tsc); + enter_kdebug("couter_overflow"); +} + +#endif /*defined(CONFIG_DEBUGGER_NEW_KDB) */ diff --git a/kernel/kdb/interrupt.o b/kernel/kdb/interrupt.o new file mode 100644 index 0000000..ef6b83b Binary files /dev/null and b/kernel/kdb/interrupt.o differ diff --git a/kernel/kdb/kdebug.h b/kernel/kdb/kdebug.h new file mode 100644 index 0000000..e32bb1c --- /dev/null +++ b/kernel/kdb/kdebug.h @@ -0,0 +1,86 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: kdebug.h + * Description: Global kdebug definitions and declarations. + * + * @LICENSE@ + * + * $Id: kdebug.h,v 1.26 2001/12/04 21:15:25 uhlig Exp $ + * + ********************************************************************/ +#ifndef __KDB__KDEBUG_H__ +#define __KDB__KDEBUG_H__ + +#include + +void kdebug_init_arch() L4_SECT_KDEBUG; +void kdebug_dump_map(dword_t paddr) L4_SECT_KDEBUG; +int kdebug_arch_entry(exception_frame_t * frame) L4_SECT_KDEBUG; +void kdebug_arch_exit(exception_frame_t * frame) L4_SECT_KDEBUG; +void kdebug_interrupt_association() L4_SECT_KDEBUG; +void kdebug_single_stepping(exception_frame_t *frame, dword_t onoff) L4_SECT_KDEBUG; +void kdebug_perfmon() L4_SECT_KDEBUG; +void kdebug_breakpoint() L4_SECT_KDEBUG; +void kdebug_arch_help() L4_SECT_KDEBUG; +void kdebug_cpustate(tcb_t *current) L4_SECT_KDEBUG; +int kdebug_step_instruction(exception_frame_t * frame) L4_SECT_KDEBUG; +int kdebug_step_block(exception_frame_t * frame) L4_SECT_KDEBUG; +void kdebug_disassemble(exception_frame_t * frame) L4_SECT_KDEBUG; + + +tcb_t *kdebug_find_task_tcb(dword_t tasknum, tcb_t *current) L4_SECT_KDEBUG; +int lookup_mapping(space_t *, dword_t, ptr_t *) L4_SECT_KDEBUG; +#define kdebug_get_mem(ptab, addr, ret) \ +({ \ + ptr_t __retval_p; \ + int __ok; \ + __ok = lookup_mapping((ptab), (dword_t) (addr), &__retval_p); \ + if (__ok) \ + *(ret) = *((typeof(ret)) phys_to_virt(__retval_p)); \ + __ok; \ +}) + +/* From x86_profiling.c */ +void kdebug_init_profiling(void) L4_SECT_KDEBUG; +void kdebug_profiling(tcb_t *current) L4_SECT_KDEBUG; +void kdebug_profile_dump(tcb_t *current) L4_SECT_KDEBUG; + +/* From x86_tracestore.c */ +void kdebug_x86_bts(void) L4_SECT_KDEBUG; +void kdebug_x86_pebs(void) L4_SECT_KDEBUG; + +/* From input.c */ +dword_t kdebug_get_hex(dword_t def = 0, const char *str = NULL) L4_SECT_KDEBUG; +dword_t kdebug_get_dec(dword_t def = 0, const char *str = NULL) L4_SECT_KDEBUG; +tcb_t *kdebug_get_thread(tcb_t *current) L4_SECT_KDEBUG; +tcb_t *kdebug_get_task(tcb_t *current) L4_SECT_KDEBUG; +ptr_t kdebug_get_pgtable(tcb_t *current, char *str = NULL) L4_SECT_KDEBUG; +char kdebug_get_choice(const char *, const char *, char = 0, int = 0) L4_SECT_KDEBUG; + +/* From x86_input.c */ +#if defined(CONFIG_ARCH_X86_I686) +dword_t kdebug_get_perfctr(char *str, dword_t def = 0xff) L4_SECT_KDEBUG; +#elif defined(CONFIG_ARCH_X86_P4) +void kdebug_describe_perfctr(dword_t ctr) L4_SECT_KDEBUG; +dword_t kdebug_get_perfctr(dword_t *, qword_t *, qword_t *) L4_SECT_KDEBUG; +#endif + +/* From tracepoint.c */ +void kdebug_tracepoint(void) L4_SECT_KDEBUG; +void kdebug_list_tracepoints(int) L4_SECT_KDEBUG; + +/* From x86_smp.c */ +#if defined(CONFIG_SMP) +void kdebug_smp_info(); +#endif + + +/* hacky */ +#if defined(CONFIG_DEBUGGER_GDB) +#define CONFIG_DEBUGGER_IO_INCOM 1 +#define CONFIG_DEBUGGER_IO_OUTCOM 1 +#endif + +#endif /* !__KDB__KDEBUG_H__ */ diff --git a/kernel/kdb/kdebug_help.h b/kernel/kdb/kdebug_help.h new file mode 100644 index 0000000..2394700 --- /dev/null +++ b/kernel/kdb/kdebug_help.h @@ -0,0 +1,85 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: kdebug_help.h + * Description: Help definitions for kdebug keystrokes. + * + * @LICENSE@ + * + * $Id: kdebug_help.h,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#if !defined(__KDEBUG_HELP__) +#define __KDEBUG_HELP__ + +#include +#include "kdebug_keys.h" +/* + * Help strings for the different keystrokes. + */ + +struct kdb_help_t { + char key; + char alternate_key; + char *help; +} kdb_general_help[] = { + { K_GO, 0, "Continue" }, + { K_RESET, K_RESET2, "Restart the Computer" }, + { K_CONFIG_STUFF, 0, "Debugger configuration" }, + { K_FRAME_DUMP, 0, "Dump frame" }, + { K_MEM_STUFF, 0, "Memory part" }, + { K_CPU_STUFF, 0, "CPU dependent part" }, + { K_KERNEL_STUFF, 0, "Kernel things" }, + { K_STEP_INSTR, 0, "Step Instruction" }, + { K_DUMP_TRACE, 0, "Dump Trace" }, + { K_STEP_BLOCK, 0, "Step Block" }, + { 0, 0, NULL } +}, +kdb_cpu_help[] = { + { K_CPU_STATE, 0, "CPU state" }, + { K_CPU_PERFCTR, 0, "Performance counter" }, +#if defined(CONFIG_DEBUG_DISAS) + { K_CPU_DISASSEMBLE, 0, "Disassembler" }, +#endif +#if defined(CONFIG_ENABLE_PROFILING) + { K_CPU_PROFILE, 0, "Profiling" }, + { K_CPU_PROFILE_DUMP, 0, "Dump Profile" }, +#endif + { K_CPU_BREAKPOINT, 0, "set/clear breakpoints" }, +// { K_CPU_SINGLE_STEPPING, 0, "Single stepping" }, + { 0, 0, NULL } +}, +kdb_kernel_help[] = { + { K_KERNEL_STATS, 0, "Dump statistics" }, + { K_KERNEL_QUEUES, 0, "List Priority Queues" }, + { K_KERNEL_IPC_TRACE, 0, "IPC tracing" }, + { K_KERNEL_EXCPTN_TRACE, 0, "Exception tracing" }, + { K_KERNEL_INTERRUPT, 0, "Interrupt Association" }, + { K_KERNEL_TASK_DUMP, 0, "Dump Task" }, + { K_KERNEL_TCB_DUMP, 0, "Dump TCB" }, +#if defined(CONFIG_ENABLE_TRACEPOINTS) + { K_KERNEL_TRACEPOINT, 0, "Set/Clear Tracepoints" }, +#endif + { 0, 0, NULL } +}, +kdb_mem_help[] = { + { K_MEM_DUMP, 0, "Dump Memory" }, + { K_MEM_DUMP_OTHER, 0, "Dump Memory (other space)" }, + { K_MEM_MDB_DUMP, 0, "Dump Mapping DB" }, +#if defined(CONFIG_DEBUG_TRACE_MBD) + { K_MEM_MDB_TRACE, 0, "Trace Mapping DB" }, +#endif + { K_MEM_PTAB_DUMP, 0, "Dump Pagetable" }, + { K_MEM_PF_TRACE, K_MEM_PF_TRACE2, "Pagefault tracing" }, + { 0, 0, NULL } +}, +kdb_config_help[] = { + { K_CONFIG_CACHE, 0, "Enable/disable cache while in debugger. Starting disabled." }, + { K_CONFIG_DUMP_NAMES, 0, "List of Nicknames" }, + { K_CONFIG_KNOWN_NAMES, 0, "Set some known names" }, + { K_CONFIG_NAMES, 0, "Name a thread" }, + { 0, 0, NULL } +}; + +#endif diff --git a/kernel/kdb/kdebug_keys.h b/kernel/kdb/kdebug_keys.h new file mode 100644 index 0000000..42df1ec --- /dev/null +++ b/kernel/kdb/kdebug_keys.h @@ -0,0 +1,208 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: kdebug_keys.h + * Description: Keystroke Definitions for the Kernel Debugger. + * + * @LICENSE@ + * + * $Id: kdebug_keys.h,v 1.8 2001/12/12 23:12:52 ud3 Exp $ + * + ********************************************************************/ +#ifndef __KDB__KDEBUG_KEYS_H__ +#define __KDB__KDEBUG_KEYS_H__ + +#if defined(CONFIG_DEBUGGER_NEW_KDB) + +//to make the tracebuffers readable... +#define YES 1 +#define NO 0 +#define TRACING 1 +#define DISPLAY 0 +#define THREADS_IN_LIST 1 +#define ALL_OTHER_THREADS 0 + +/* + * List of all keystrokes for the Kernel Debugger sorted by define. + * (Plese keep this list sorted alphabetically.) + */ +#define K_CONFIG_STUFF 'o' +#define K_CONFIG_CACHE 'c' +#define K_CONFIG_DUMP_NAMES 'K' +#define K_CONFIG_KNOWN_NAMES 'n' +#define K_CONFIG_NAMES 's' + +#define K_DUMP_TRACE 'T' +#define K_FRAME_DUMP ' ' + +#define K_CPU_BREAKPOINT 'b' +#define K_CPU_DISASSEMBLE 'U' +#define K_CPU_PERFCTR 'e' +#define K_CPU_PROFILE 'c' +#define K_CPU_PROFILE_DUMP 'C' +//#define K_CPU_SINGLE_STEPPING 'T' +#define K_CPU_STATE 'A' +#define K_CPU_STUFF 'c' + +#define K_GO 'g' +#define K_HELP '?' +#define K_HELP2 'h' + +#define K_KERNEL_EXCPTN_TRACE 'x' +#define K_KERNEL_INTERRUPT 'I' +#define K_KERNEL_IPC_TRACE 'i' +#define K_KERNEL_QUEUES 'Q' +#define K_KERNEL_STATS '#' +#define K_KERNEL_STUFF 'k' +#define K_KERNEL_TASK_DUMP 'k' +#define K_KERNEL_TCB_DUMP 't' +#define K_KERNEL_TRACEPOINT 'r' + +#define K_LEAVE_MENU 'q' + +#define K_MEM_DUMP 'd' +#define K_MEM_DUMP_OTHER 'D' +#define K_MEM_MDB_DUMP 'm' +#define K_MEM_MDB_TRACE 'M' +#define K_MEM_PF_TRACE 'f' +#define K_MEM_PF_TRACE2 'P' +#define K_MEM_PTAB_DUMP 'p' +#define K_MEM_STUFF 'm' + +#define K_RESET '^' +#define K_RESET2 '6' +#define K_RESTRICT_TRACE 'r' +#define K_STEP_BLOCK 'S' +#define K_STEP_INSTR 's' + + + +#else /* CONFIG_DEBUGGER_KDB */ +/* + * List of all keystrokes for the Kernel Debugger. (Please keep this + * list sorted alphabetically.) + */ + +#define K_CPUSTATE 'A' +#define K_BREAKPOINT 'b' +#define K_PROFILE 'c' +#define K_PROFILE_DUMP 'C' +#define K_MEM_DUMP 'd' +#define K_MEM_OTHER_DUMP 'D' +#define K_PERFMON 'e' +#define K_PF_TRACE 'f' +#define K_GO 'g' +#define K_HELP2 'h' +#define K_IPC_TRACE 'i' +#define K_INTERRUPTS 'I' +#define K_TASK_DUMP 'k' +#define K_MDB_DUMP 'm' +#define K_MDB_TRACE 'M' +#define K_PTAB_DUMP 'p' +#define K_PF_TRACE2 'P' +#define K_QUEUES 'q' +#define K_TRACEPOINT 'r' +#define K_STEP_INSTR 's' +#define K_STEP_BLOCK 'S' +#define K_TCB_DUMP 't' +#define K_SINGLE_STEPPING 'T' +#define K_LAST_IPC 'u' +#define K_DISASSEMBLE 'U' +#define K_SWITCH_TRACE 'w' +#define K_SWITCH_TRACE_DUMP 'W' +#define K_SMP_INFO 'x' +#define K_SMP_SWITCH_CPU 'X' +#define K_TRACE_DUMP 'y' +#define K_TRACE_FLUSH 'Y' +#define K_FRAME_DUMP ' ' +#define K_RESET2 '6' +#define K_STATISTICS '#' +#define K_HELP '?' +#define K_RESET '^' + + + +/* + * Help strings for the different keystrokes. + */ + +struct kdb_help_t { + char key; + char alternate_key; + char *help; +} kdb_help[] = { + { K_GO, 0, "Continue" }, + { K_RESET, K_RESET2, "Reset" }, + { K_FRAME_DUMP, 0, "Dump Frame" }, + { K_TCB_DUMP, 0, "Dump TCB" }, + { K_TASK_DUMP, 0, "Dump Task" }, + { K_PTAB_DUMP, 0, "Dump Page Table" }, + { K_MEM_DUMP, 0, "Dump Memory" }, + { K_MEM_OTHER_DUMP, 0, "Dump Memory (other space)" }, + { K_MDB_DUMP, 0, "Dump Mapping DB" }, + { K_MDB_TRACE, 0, "Trace Mapping DB" }, + { K_STATISTICS, 0, "Dump Statistics" }, + { K_QUEUES, 0, "List Priority Queues" }, + { K_INTERRUPTS, 0, "Interrupt Association" }, + { K_CPUSTATE, 0, "CPU State" }, + +#if defined(CONFIG_DEBUG_TRACE_UPF) || defined(CONFIG_DEBUG_TRACE_KPF) + { K_PF_TRACE, K_PF_TRACE2, "Trace pagefaults" }, +#endif + +#if defined(CONFIG_DEBUG_TRACE_IPC) + { K_IPC_TRACE, 0, "Trace IPCs" }, + { K_LAST_IPC, 0, "Show Last IPC" }, +#endif + +#if defined(CONFIG_ENABLE_SWITCH_TRACE) + { K_SWITCH_TRACE, 0, "Trace thread switches" }, + { K_SWITCH_TRACE_DUMP, 0, "Dump thread switch trace" }, +#endif + +#if defined(CONFIG_DEBUG_TRACE_MBD) + { K_MDB_TRACE, 0, "Trace Mapping DB" }, +#endif + +#if defined(CONFIG_TRACEBUFFER) + { K_TRACE_DUMP, 0, "Dump tracebuffer" }, + { K_TRACE_FLUSH, 0, "Flush tracebuffer" }, +#endif + +#if defined(CONFIG_ENABLE_TRACEPOINTS) + { K_TRACEPOINT, 0, "Set/Clear Tracepoints" }, +#endif + +#if defined(CONFIG_ENABLE_PROFILING) + { K_PROFILE, 0, "Profiling" }, + { K_PROFILE_DUMP, 0, "Dump Profile" }, +#endif + +#if defined(CONFIG_PERFMON) + { K_PERFMON, 0, "Performance Monitoring" }, +#endif + + { K_BREAKPOINT, 0, "Set/Clear Breakpoints" }, + { K_SINGLE_STEPPING, 0, "Single Stepping" }, + { K_STEP_INSTR, 0, "Step Instruction" }, + { K_STEP_BLOCK, 0, "Step Block" }, + +#if defined(CONFIG_DEBUG_DISAS) + { K_DISASSEMBLE, 0, "Disassemble" }, +#endif + +#if defined(CONFIG_SMP) + { K_SMP_INFO, 0, "SMP Info" }, + { K_SMP_SWITCH_CPU, 0, "Switch to other CPU" }, +#endif + + { K_HELP, K_HELP2, "This Help Message" }, + + { 0, 0, NULL } +}; + + +#endif /* CONFIG_DEBUGGER_NEW_KDB */ + +#endif /* !__KDB__KDEBUG_KEYS_H__ */ diff --git a/kernel/kdb/libkdb.a b/kernel/kdb/libkdb.a new file mode 100644 index 0000000..a95b3eb Binary files /dev/null and b/kernel/kdb/libkdb.a differ diff --git a/kernel/kdb/mdb.c b/kernel/kdb/mdb.c new file mode 100644 index 0000000..536acf0 --- /dev/null +++ b/kernel/kdb/mdb.c @@ -0,0 +1,209 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mdb.c + * Description: Mapping database sumping and statistics functions. + * + * @LICENSE@ + * + * $Id: mdb.c,v 1.15 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + +static void dump_mdbmaps(mnode_t *, dword_t, dword_t, + rnode_t *, char *) L4_SECT_KDEBUG; +static void dump_mdbroot(rnode_t *, dword_t, dword_t, char *) L4_SECT_KDEBUG; + + +static inline dword_t mdb_arraysize(dword_t pgsize) +{ + return 1 << (mdb_pgshifts[pgsize+1] - mdb_pgshifts[pgsize]); +} + +static inline dword_t mdb_pgsize(dword_t pgsize) +{ + return 1 << mdb_pgshifts[pgsize]; +} + +static inline rnode_t * index_root(rnode_t *root, dword_t pgsz, dword_t paddr) +{ + return root + ((paddr >> mdb_pgshifts[pgsz]) & (mdb_arraysize(pgsz) - 1)); +} + +static inline int hw_pgsize (int mdb_pgsize) +{ + int s = 0; + while (hw_pgshifts[s] < mdb_pgshifts[mdb_pgsize]) + s++; + return s; +} + +static void dump_mdbmaps(mnode_t *map, dword_t paddr, dword_t size, + rnode_t *proot, char *spc) +{ + mnode_t *pmap = NULL; + + while ( map ) { + if ( map == sigma0_mapnode ) + printf("sigma0_mapnode (%p)\n", sigma0_mapnode); + else + { + space_t * space = map->get_space(); + int hwsize = hw_pgsize (size); + printf("%s[%d] space=%p vaddr=%p pgent=%p (%p)\n", + spc - map->get_depth()*2, + map->get_depth(), space, + pmap ? map->get_pgent(pmap)->vaddr(space, hwsize, map) : + map->get_pgent(proot)->vaddr(space, hwsize, map), + pmap ? map->get_pgent(pmap) : map->get_pgent(proot), + map); + } + + pmap = map; + if ( map->is_next_root() ) + { + dualnode_t *dual = (dualnode_t *) map->get_nextr(); + + if ( dual->root == NULL ) + printf("============> [EMPTY ROOT]\n"); + else + dump_mdbroot(index_root(dual->root, size-1, paddr), + paddr, size-1, spc - 4 - map->get_depth()*2); + map = dual->map; + } + else + map = map->get_nextm(); + } +} + +static void dump_mdbroot(rnode_t *root, dword_t paddr, + dword_t size, char *spc) +{ + printf("%s%x: %d%s %s (%p)\n", + spc, paddr & ~((1 << mdb_pgshifts[size]) - 1), + (mdb_pgshifts[size] >= 20) ? 1 << (mdb_pgshifts[size] - 20) : + 1 << (mdb_pgshifts[size] - 10), + (mdb_pgshifts[size] >= 20) ? "MB" : "KB", + root->is_next_root() ? "[ROOT]" : "[MAP] ", root); + + if ( root->is_next_root() ) + { + dualnode_t *dual = (dualnode_t *) root->get_map(); + dump_mdbmaps(dual->map, paddr, size, root, spc - 4); + dump_mdbroot(index_root(dual->root, size-1, paddr), paddr, + size-1, spc - 4); + } + else + { + if ( root->get_map() != NULL ) + dump_mdbmaps(root->get_map(), paddr, size, + root, spc - 4); + } +} + + +void kdebug_dump_map(dword_t paddr) +{ + static char spaces[] = " "; + dualnode_t *dual = (dualnode_t *) sigma0_mapnode->get_nextr(); + putc('\n'); + dump_mdbroot(index_root(dual->root, NUM_PAGESIZES-1, paddr), paddr, + NUM_PAGESIZES-1, spaces + sizeof(spaces)-1); +} + +#define MAX_MDB_DEPTH 5 +#define MAX_MDB_MAPS 10 + +static dword_t num_depths[MAX_MDB_DEPTH+1] L4_SECT_KDEBUG; +static dword_t num_maps[MAX_MDB_MAPS+1] L4_SECT_KDEBUG; +static dword_t max_depth L4_SECT_KDEBUG; +static dword_t max_maps L4_SECT_KDEBUG; + +static void stat_mdbroot(rnode_t *root, int size, int num) +{ + dualnode_t *dual; + mnode_t *map; + dword_t cnt; + + for ( ; num--; root++ ) + { + if ( root->is_next_root() ) + { + dual = (dualnode_t *) root->get_map(); + stat_mdbroot(dual->root, size-1, mdb_arraysize(size-1)); + map = dual->map; + } + else + map = root->get_map(); + + cnt = 0; + while ( map ) + { + if ( map->get_depth() > max_depth ) + max_depth = map->get_depth(); + if ( map->get_depth() > MAX_MDB_DEPTH ) + num_depths[MAX_MDB_DEPTH] += 1; + else + num_depths[map->get_depth()] += 1; + + cnt++; + if ( map->is_next_root() ) + { + dual = (dualnode_t *) map->get_nextr(); + stat_mdbroot(dual->root, size-1, mdb_arraysize(size-1)); + map = dual->map; + } + else + map = map->get_nextm(); + } + + if ( cnt > max_maps ) + max_maps = cnt; + if ( cnt > MAX_MDB_MAPS ) + num_maps[MAX_MDB_MAPS] += 1; + else + num_maps[cnt] += 1; + } +} + +void kdebug_mdb_stats(dword_t start, dword_t end) +{ + dualnode_t *dual = (dualnode_t *) sigma0_mapnode->get_nextr(); + dword_t addr; + int i, j; + + for ( i = 0; i < MAX_MDB_DEPTH; i++ ) + num_depths[i] = 0; + for ( i = 0; i < MAX_MDB_MAPS; i++ ) + num_maps[i] = 0; + max_depth = max_maps = 0; + + for ( i = 1, addr = start & ~(mdb_pgsize(NUM_PAGESIZES-1)-1); + addr < (end & ~(mdb_pgsize(NUM_PAGESIZES-1)-1)); + addr += mdb_pgsize(NUM_PAGESIZES-1), i++ ) {} + stat_mdbroot(index_root(dual->root, NUM_PAGESIZES-1, start), + NUM_PAGESIZES-1, i); + + printf("\nMapping database statistics (%p -> %p)\n", start, end); + printf("Depth\tNum.\t\tMaps\tNum.\n"); + for ( i = j = 0; i <= MAX_MDB_DEPTH || j <= MAX_MDB_MAPS; i++, j++ ) + { + if ( i <= MAX_MDB_DEPTH ) + printf(" %d%c\t %d", i, i == MAX_MDB_DEPTH ? '+' : ' ', + num_depths[i]); + else + printf(" \t"); + + if ( j <= MAX_MDB_MAPS ) + printf("\t\t %d%c\t %d\n", j, j == MAX_MDB_MAPS ? '+' : ' ', + num_maps[j]); + else + printf("\n"); + } + + printf("\n Max:\t %d\t\t Max:\t %d\n", max_depth, max_maps); +} diff --git a/kernel/kdb/mdb.o b/kernel/kdb/mdb.o new file mode 100644 index 0000000..ebcab05 Binary files /dev/null and b/kernel/kdb/mdb.o differ diff --git a/kernel/kdb/mini-kd.c b/kernel/kdb/mini-kd.c new file mode 100644 index 0000000..b796670 --- /dev/null +++ b/kernel/kdb/mini-kd.c @@ -0,0 +1,713 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mini-kd.c + * Description: Main entry pint for kernel debugger (rather + * misleading filename). + * + * @LICENSE@ + * + * $Id: mini-kd.c,v 1.71 2001/12/12 22:48:31 ud3 Exp $ + * + ********************************************************************/ +#include +#include + +#if defined(CONFIG_DEBUGGER_KDB) && !defined(CONFIG_DEBUGGER_NEW_KDB) +#include "kdebug.h" +#include "kdebug_keys.h" + +dword_t __kdebug_ipc_tracing = 0; +dword_t __kdebug_ipc_tr_mask = 0; +dword_t __kdebug_ipc_tr_thread = 0; +dword_t __kdebug_ipc_tr_dest = 0; +dword_t __kdebug_ipc_tr_this = 0; +int __kdebug_pf_tracing = 0; + +struct last_ipc_t +{ + l4_threadid_t myself; + l4_threadid_t dest; + dword_t snd_desc; + dword_t rcv_desc; + dword_t ipc_buffer[3]; + dword_t ip; +} last_ipc; + + +#if defined(CONFIG_DEBUG_TRACE_MDB) +int __kdebug_mdb_tracing = 0; +#endif + +#if defined(CONFIG_ENABLE_SWITCH_TRACE) +switch_trace_type_t kdebug_switch_trace_type = SWTRACE_NONE; +switch_trace_t kdebug_switch_trace[CONFIG_SWITCH_TRACE_SIZE]; +dword_t kdebug_switch_trace_idx; +tcb_t *kdebug_switch_trace_id; +#endif + +void panic(const char *msg) +{ + printf("panic: %s", msg); + enter_kdebug("panic"); + while(1); +} + +void kdebug_interrupt_association() +{ + printf("\nint association\n"); + int num = 0; + for (int i = 0; i < MAX_INTERRUPTS; i++) + if (interrupt_owner[i]) + printf("interrupt %2d (%x): tcb %p (%t)%c", + i, interrupt_owner[i]->intr_pending, + interrupt_owner[i], interrupt_owner[i], + (num++) & 1 ? '\n' : '\t'); +} + +#define MAX_KMEM_SIZECNT 10 +static dword_t num_chunks[MAX_KMEM_SIZECNT+1]; + +void kdebug_kmem_stats(void) +{ + extern dword_t *kmem_free_list; + extern dword_t free_chunks; + dword_t num, *cur, *prev, i, j, idx, max_chunks; + + /* Clear out statistics. */ + for ( idx = 0; idx <= MAX_KMEM_SIZECNT; idx++ ) + num_chunks[idx] = 0; + max_chunks = 0; + + for ( num = 1, cur = kmem_free_list, prev = NULL; + cur; + prev = cur, cur = (dword_t *) *cur ) + { + /* Are chunks contigous? */ + if ( (dword_t) prev + KMEM_CHUNKSIZE == (dword_t) cur ) + num++; + else + num = 1; + + for ( i = j = 1, idx = 0; i <= num; i++ ) + { + if ( i == j ) + { + /* Number of chunks is power of 2. */ + dword_t mask = (j * KMEM_CHUNKSIZE)-1; + dword_t tmp = (dword_t) cur - ((j-1) * KMEM_CHUNKSIZE); + + /* Check if chunks are properly aligned. */ + if ( (tmp & mask) == 0 ) + { + if ( idx < MAX_KMEM_SIZECNT ) + num_chunks[idx]++; + else + num_chunks[MAX_KMEM_SIZECNT]++; + if ( idx > max_chunks ) + max_chunks = idx; + } + + j <<= 1; + idx++; + } + } + } + + printf("\nKmem statistics. Free chunks = %d (%dKB)\n", + free_chunks, (free_chunks*KMEM_CHUNKSIZE)/1024); + printf("Chunks\tNum.\n"); + for ( i = 0; i <= MAX_KMEM_SIZECNT; i++ ) + { + printf(" %d%c\t %d\n", (1 << i), + i == MAX_KMEM_SIZECNT ? '+' : ' ', + num_chunks[i]); + } + printf("\n Max:\t %d\n", 1 << max_chunks); +} + + +void kdebug_dump_tcb(tcb_t* tcb) +{ + /* max width 79 !!! */ +#if !defined(CONFIG_SMP) + printf("=== TCB: %p === TID: %p === PRIO: 0x%2x ===============", + tcb, (void*) tcb->myself.raw, tcb->priority); +#else + printf("=== TCB: %p === TID: %p === PRIO: 0x%2x === CPU: %2x ===", + tcb, (void*) tcb->myself.raw, + tcb->priority, tcb->cpu); +#endif + printf("%s ===\n", tcb->magic == TCB_MAGIC ? "====== OK" : " *BROKEN*"); + printf("UIP: %x queues: %c%c%c%c present: %p:%p space: %p\n", + get_user_ip(tcb), + 'R' + 0x20*!(tcb->queue_state & TS_QUEUE_READY), + 'P' + 0x20*!(tcb->queue_state & TS_QUEUE_PRESENT), + 'W' + 0x20*!(tcb->queue_state & TS_QUEUE_WAKEUP), + 'S' + 0x20*!(tcb->queue_state & TS_QUEUE_SEND), + tcb->present_prev, tcb->present_next, tcb->space); + printf("USP: %x tstate: %s ready: %p:%p pager: %x\n", + get_user_sp(tcb), + tcb->thread_state == TS_RUNNING ? "RUNNING" : + tcb->thread_state == TS_POLLING ? "POLLING" : + tcb->thread_state == TS_LOCKED_RUNNING ? "LCKRUNN" : + tcb->thread_state == TS_LOCKED_WAITING ? "LCKWAIT" : + tcb->thread_state == TS_ABORTED ? "ABORTED" : + tcb->thread_state == TS_WAITING ? + ((tcb->partner == L4_NIL_ID) ? "OWAIT " : + "WAITING"): +#if defined(CONFIG_SMP) + tcb->thread_state == TS_XCPU_LOCKED_RUNNING ? "XLKRUNN" : + tcb->thread_state == TS_XCPU_LOCKED_WAITING ? "XLKWAIT" : +#endif + "???????", + tcb->ready_prev, tcb->ready_next, tcb->pager.raw); + printf("KSP: %p resour: %c%c%c%c wakeup: %p:%p excpt: %x\n", + tcb->stack, + tcb->resources & TR_IPC_MEM ? 'M' : 'm', + tcb->resources & TR_FPU ? 'F' : 'f', + tcb->resources & TR_LONG_IPC_PTAB ? 'P' : 'p', + tcb->resources & TR_DEBUG_REGS ? 'D' : 'd', + tcb->wakeup_prev, tcb->wakeup_next, tcb->excpt); + printf("KIP: %p send: %p:%p\n", + (ptr_t)((((dword_t)tcb->stack >= TCB_AREA) && + ((dword_t)tcb->stack < TCB_AREA+TCB_AREA_SIZE)) ? + *tcb->stack : (dword_t)-1), + tcb->send_prev, tcb->send_next); + printf("\n"); + printf("timeslc:\t%d/%d\n", tcb->current_timeslice, tcb->timeslice); + printf("partner:\t%T\ttimeout %x/%x (cur. time: %x)\n", + tcb->partner.raw, (dword_t)tcb->ipc_timeout.raw, + (dword_t)tcb->absolute_timeout, (dword_t)kernel_info_page.clock); + printf("sndqueue:\t%p\n", tcb->send_queue); + printf("IPC: %x:%x:%x\n", tcb->ipc_buffer[0], tcb->ipc_buffer[1], + tcb->ipc_buffer[2]); + printf("unwind:\t%p\n", tcb->unwind_ipc_sp); +#ifdef CONFIG_SMP + printf("tcb spinlock:\t%x\n", tcb->tcb_spinlock.lock); +#endif +#if defined(CONFIG_ENABLE_SMALL_AS) + smallid_t id = tcb->space->smallid (); + printf("Small space: "); + if (id.is_valid ()) + printf("%02x [size=%dMB, idx=%d]\n", id.value (), + id.bytesize () >> 20, id.idx ()); + else + printf("no\n"); +#endif +} + + +#if defined(CONFIG_ENABLE_SWITCH_TRACE) +static void kdebug_thread_switch_trace (tcb_t * current) +{ + char c = kdebug_get_choice ("\nThread switch trace", + "All/None/taSk/thRead", 'a'); + switch (c) + { + case 'a': + kdebug_switch_trace_type = SWTRACE_ALL; + break; + case 'n': + kdebug_switch_trace_type = SWTRACE_NONE; + break; + case 's': + kdebug_switch_trace_type = SWTRACE_TASK; + kdebug_switch_trace_id = kdebug_get_task (current); + break; + case 'r': + kdebug_switch_trace_type = SWTRACE_THREAD; + kdebug_switch_trace_id = kdebug_get_thread (current); + break; + } + + zero_memory ((ptr_t) kdebug_switch_trace, sizeof (kdebug_switch_trace)); + kdebug_switch_trace_idx = 0; +} + +static void kdebug_thread_switch_trace_dump (void) +{ + printf ("\nThread switch trace "); + switch (kdebug_switch_trace_type) + { + case SWTRACE_NONE: + printf ("(none):\n"); + break; + case SWTRACE_ALL: + printf ("(all):\n"); + break; + case SWTRACE_TASK: + printf ("(task %02x):\n", tasknum (kdebug_switch_trace_id)); + break; + case SWTRACE_THREAD: + printf ("(thread %p):\n", kdebug_switch_trace_id); + break; + } + + tcb_t *otcb = NULL; + for (int i = kdebug_switch_trace_idx, n = 0; + n < CONFIG_SWITCH_TRACE_SIZE; n++) + { + switch_trace_t *st = kdebug_switch_trace + i; + + if (st->t_tcb != NULL) + { + if (otcb == NULL) + printf ("???????? (??.?"/* fuck trigraphs */"?) eip=???????? esp=???????? -> "); + else if (otcb == get_idle_tcb ()) + printf ("%p (idler) eip=XXXXXXXX esp=XXXXXXXX -> ", otcb); + else + printf ("%p (%t) eip=%p esp=%p -> ", otcb, + otcb->myself, st->f_uip, st->f_usp); + if (st->t_tcb == get_idle_tcb ()) + printf ("%p (idler) eip=XXXXXXXX esp=XXXXXXXX\n", st->t_tcb); + else + printf ("%p (%t) eip=%p esp=%p\n", st->t_tcb, + st->t_tcb->myself, st->t_uip, st->t_usp); + } + + if (++i == CONFIG_SWITCH_TRACE_SIZE) + i = 0; + otcb = st->t_tcb; + } +} +#endif + + +tcb_t *kdebug_find_task_tcb(dword_t tasknum, tcb_t *current) +{ + tcb_t *tcb; + int first_time; + + for ( tcb = current, first_time = 1; + tcb != current || first_time; + tcb = tcb->present_next, first_time = 0 ) + if ( tcb->myself.x0id.task == tasknum) + return tcb; + + return NULL; +} + + +int kdebug_entry(exception_frame_t* frame) +{ + /* kdebug_arch_entry can decide about whether + to enter the interactive KDB (0) or not (1) */ + if (kdebug_arch_entry(frame) == 0) + { + +#if defined(CONFIG_SMP) + smp_enter_kdebug(); +#endif + + int exit_kdb = 0; + char c; + + /* Works because frame resides on the kernel stack. */ + tcb_t *current = ptr_to_tcb((ptr_t) frame); + space_t *space = NULL; + + extern dword_t _kdebug_stack_bottom[]; + extern dword_t _kdebug_stack_top[]; + if ( (dword_t) current < TCB_AREA || + ((dword_t) frame >= (dword_t) &_kdebug_stack_bottom && + (dword_t) frame < (dword_t) &_kdebug_stack_top) ) + /* In case we entered kdebug on startup, or caught an + exception inside KDB. */ + current = get_idle_tcb(); + + printf("\n--------------------------------------------------------\n"); + + while ( ! exit_kdb ) + { + printf("\nKD: "); + + /* + * Keep case targets sorted alphabetically. + */ + switch(c = getc()) + { + case K_BREAKPOINT: + kdebug_breakpoint(); + break; + + case K_CPUSTATE: + kdebug_cpustate(current); + break; + +#if defined(CONFIG_DEBUG_DISAS) + case K_DISASSEMBLE: + kdebug_disassemble(frame); + break; +#endif + + case K_FRAME_DUMP: + putc('\n'); + kdebug_dump_frame(frame); + break; + + case K_GO: + putc(c); putc('\n'); + exit_kdb = 1; + break; + + case K_HELP: + case K_HELP2: + printf("\nL4Ka Kernel Debugger Help:\n"); + for ( dword_t i = 0; kdb_help[i*2].key; i++ ) + { + struct kdb_help_t *h = kdb_help + i; + printf(h->key == ' ' ? " spc" : + h->alternate_key ? " %c/%c" : " %c ", + h->key, h->alternate_key); + dword_t n = printf(" %s", h->help); + + h += sizeof(kdb_help)/sizeof(kdb_help_t)/2; + if ( ! h->key ) break; + for ( n = 38-n; n--; ) putc(' '); + printf(h->key == ' ' ? "spc" : + h->alternate_key ? "%c/%c" : "%c ", + h->key, h->alternate_key); + printf(" %s\n", h->help); + } + //kdebug_arch_help(); + putc('\n'); + break; + + case K_INTERRUPTS: + kdebug_interrupt_association(); + break; + + case K_IPC_TRACE: + { + c = kdebug_get_choice("ipc tracing", "+/*/-/r", 0, 1); + __kdebug_ipc_tr_mask = __kdebug_ipc_tr_thread = 0; + switch (c) + { + case '+': __kdebug_ipc_tracing = 2; break; + case '*': __kdebug_ipc_tracing = 1; break; + case '-': __kdebug_ipc_tracing = 0; break; + case 'r': + __kdebug_ipc_tracing = 0; + __kdebug_ipc_tr_this = __kdebug_ipc_tr_dest = 0; + while ( __kdebug_ipc_tracing == 0 ) + { + switch (c = getc()) + { + case '>': __kdebug_ipc_tr_dest = 1; putc(c); break; + case '.': __kdebug_ipc_tr_this = 1; putc(c); break; + case '+': __kdebug_ipc_tracing = 2; putc(c); break; + case '*': __kdebug_ipc_tracing = 1; putc(c); break; + } + } + if ( (__kdebug_ipc_tr_this + __kdebug_ipc_tr_dest) == 0 ) + __kdebug_ipc_tr_this = 1; + printf("\nThread mask [ffffffff]: "); + __kdebug_ipc_tr_mask = kdebug_get_hex(0xffffffff); + __kdebug_ipc_tr_thread = (dword_t) + kdebug_get_thread(current) & __kdebug_ipc_tr_mask; + break; + } + putc('\n'); + break; + } + + case K_LAST_IPC: + printf("\nlast_ipc: %x -> %x snd_desc: %x rcv_desc: %x " + "(%x, %x, %x) - ip=%x\n", + last_ipc.myself.raw, last_ipc.dest.raw, + last_ipc.snd_desc, last_ipc.rcv_desc, + last_ipc.ipc_buffer[0], last_ipc.ipc_buffer[1], + last_ipc.ipc_buffer[2], last_ipc.ip); + break; + + case K_MDB_DUMP: + putc(c); + kdebug_dump_map(kdebug_get_hex()); + break; + +#if defined(CONFIG_DEBUG_TRACE_MDB) + case K_MDB_TRACE: + c = kdebug_get_choice("mdb traing", "+/*/-"); + switch (c) + { + case '+': __kdebug_mdb_tracing = 2; break; + case '*': __kdebug_mdb_tracing = 1; break; + case '-': __kdebug_mdb_tracing = 0; break; + } + break; +#endif + + case K_MEM_DUMP: + space = get_current_space (); + /* FALLTHROUGH */ + case K_MEM_OTHER_DUMP: + { + dword_t *p, dw; + byte_t dc; + int i, j; + + putc(c); + p = (dword_t *) kdebug_get_hex(); + + if (space == NULL) + space = (space_t *) kdebug_get_pgtable( + current, "Address space (page-table/task-id/thread-id)" + " [current]: "); + + for ( i = 0; i < 16; i++ ) + { + printf(" %p: ", &p[i*4]); + for ( j = 0; j < 4; j++ ) + { + if ( kdebug_get_mem(space, &p[i*4+j], &dw) ) + printf("%p ", dw); + else + printf("######## "); + } + printf(" "); + for ( j = 0; j < 16; j++ ) + { + if ( kdebug_get_mem(space, (byte_t *) p+i*16+j, &dc) ) + printf("%c", dc >= ' ' ? dc < 0x80 ? dc :'.':'.'); + else + putc('#'); + } + putc('\n'); + } + + space = NULL; + break; + } + + case K_PERFMON: + kdebug_perfmon(); + break; + +#if defined(CONFIG_DEBUG_TRACE_UPF) || defined(CONFIG_DEBUG_TRACE_KPF) + case K_PF_TRACE: + case K_PF_TRACE2: + c = kdebug_get_choice("pf tracing", "+/*/-"); + switch (c) + { + case '+': kdebug_pf_tracing(2); break; + case '*': kdebug_pf_tracing(1); break; + case '-': kdebug_pf_tracing(0); break; + } + break; +#endif + +#if defined(CONFIG_ENABLE_PROFILING) + case K_PROFILE: + kdebug_profiling(current); + break; + + case K_PROFILE_DUMP: + kdebug_profile_dump(current); + break; +#endif + + case K_PTAB_DUMP: + putc(c); + kdebug_dump_pgtable(kdebug_get_pgtable(current)); + break; + + case K_QUEUES: + printf("\n"); + for (int i = MAX_PRIO; i >= 0; i--) + { + /* check whether we have something for this prio */ + tcb_t* walk = get_idle_tcb(); + do { + if ((int) walk->priority == i) + { + /* if so, print */ + printf("[%d]:", i); + walk = get_idle_tcb(); + do { + if ((int) walk->priority == i) { + if (walk->queue_state & TS_QUEUE_READY) + printf(" %p", walk); + else + printf(" (%p)", walk); + } + walk = walk->present_next; + } while (walk != get_idle_tcb()); + printf("\n"); + break; + } + walk = walk->present_next; + } while (walk != get_idle_tcb()); + } + printf("\n"); + break; + + case K_RESET: + case K_RESET2: + printf("reset ... bye\n\n"); + kdebug_hwreset(); + break; + + case K_SINGLE_STEPPING: + c = kdebug_get_choice("single stepping", "+/-"); + switch (c) + { + case '+': kdebug_single_stepping(frame, 1); break; + case '-': kdebug_single_stepping(frame, 0); break; + } + break; + + case K_STATISTICS: + c = kdebug_get_choice("stats", "Kmem/Mdb"); + switch (c) + { + case 'm': kdebug_mdb_stats(0x0, 0xffffffff); break; + case 'k': kdebug_kmem_stats(); break; + } + break; + + case K_STEP_BLOCK: + exit_kdb = kdebug_step_block(frame); + break; + + case K_STEP_INSTR: + exit_kdb = kdebug_step_instruction(frame); + break; + +#if defined(CONFIG_ENABLE_SWITCH_TRACE) + case K_SWITCH_TRACE: + kdebug_thread_switch_trace (current); + break; + + case K_SWITCH_TRACE_DUMP: + kdebug_thread_switch_trace_dump (); + break; +#endif + + case K_TASK_DUMP: + { + tcb_t *tcb, *task = kdebug_get_task(current); + dword_t task_id = task->myself.x0id.task; + dword_t first_time = 1; + int n; + + printf("Task %02x:\n", task_id); + for ( tcb = current; + (tcb != current) || first_time; + tcb = tcb->present_next, first_time = 0 ) + { + if ( tcb->myself.x0id.task != task_id ) + continue; + + printf("%p (%t): ", tcb, tcb->myself); + + printf(" queues=[%c%c%c%c]", + 'R' + 0x20*!(tcb->queue_state & TS_QUEUE_READY), + 'P' + 0x20*!(tcb->queue_state & TS_QUEUE_PRESENT), + 'W' + 0x20*!(tcb->queue_state & TS_QUEUE_WAKEUP), + 'S' + 0x20*!(tcb->queue_state & TS_QUEUE_SEND)); + printf(" state=%s", + tcb->thread_state == TS_RUNNING ? "RUNNING" : + tcb->thread_state == TS_POLLING ? "POLLING" : + tcb->thread_state == TS_LOCKED_RUNNING ? "LCKRUNN" : + tcb->thread_state == TS_LOCKED_WAITING ? "LCKWAIT" : + tcb->thread_state == TS_ABORTED ? "ABORTED" : + tcb->thread_state == TS_WAITING ? + ((tcb->partner == L4_NIL_ID) ? "OWAIT " : + "WAITING") : "???????"); + n = printf(" partner=%p (%t)", tcb->partner, + tcb->partner); + for ( n = 29-n; n > 0; n-- ) putc(' '); + printf(" uip=%p", get_user_ip(tcb)); + putc('\n'); + } + break; + } + + case K_TCB_DUMP: + putc(c); putc('\n'); + kdebug_dump_tcb(kdebug_get_thread(current)); + break; + +#if defined(CONFIG_TRACEBUFFER) + case K_TRACE_DUMP: + { + putc(c); putc('\n'); + kdebug_dump_tracebuffer(); + break; + } + + case K_TRACE_FLUSH: + { + putc(c); putc('\n'); + kdebug_flush_tracebuffer(); + break; + } +#endif + +#if defined(CONFIG_ENABLE_TRACEPOINTS) + case K_TRACEPOINT: + kdebug_tracepoint(); + break; +#endif + +#if defined(CONFIG_SMP) + case K_SMP_SWITCH_CPU: + { + printf("current cpu: %d, switch to cpu: ", get_cpu_id()); + int cpu = kdebug_get_dec(0); + kdebug_arch_exit(frame); + return cpu; + } + + case K_SMP_INFO: + kdebug_smp_info(); + break; +#endif + } + } + +#if defined(CONFIG_SMP) + smp_leave_kdebug(); +#endif + } + kdebug_arch_exit(frame); + return -1; +} + + +/* +** +** Function for safely accessing memory without causing page faults. +** +*/ + +int lookup_mapping(space_t * space, dword_t vaddr, ptr_t * paddr) +{ + pgent_t *pg = space->pgent (0); + dword_t pgsz = HW_NUM_PGSIZES-1; + + /* Look for valid page table entry. */ + pg = pg->next(space, table_index(vaddr, pgsz), pgsz); + while ( pg->is_valid(space, pgsz) && pg->is_subtree(space, pgsz) ) + { + pg = pg->subtree(space, pgsz--); + pg = pg->next(space, table_index(vaddr, pgsz), pgsz); + } + + if ( ! pg->is_valid(space, pgsz) ) + /* Return value of 0 indicates invalid address. */ + return 0; + + /* Store physical address into return parameter. */ + if (paddr) + *paddr = (ptr_t)(pg->address(space, pgsz) + (vaddr & page_mask(pgsz))); + + return 1; +} + + + + +#endif /* CONFIG_DEBUGGER_KDB */ diff --git a/kernel/kdb/mini-kd.o b/kernel/kdb/mini-kd.o new file mode 100644 index 0000000..2ff89b5 Binary files /dev/null and b/kernel/kdb/mini-kd.o differ diff --git a/kernel/kdb/mips-pr31700.c b/kernel/kdb/mips-pr31700.c new file mode 100644 index 0000000..e8eb6f1 --- /dev/null +++ b/kernel/kdb/mips-pr31700.c @@ -0,0 +1,52 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mips-pr31700.c + * Description: Kdebug glue for the MIPS PR31700. + * + * @LICENSE@ + * + * $Id: mips-pr31700.c,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +#define UART_TX (1 << 14) +#define UART_ENABLE 1 + +#if CONFIG_DEBUGGER_COMSPEED == 57600 +# define UART_SPEED 4 +#else +# error Wrong speed for serial line +#endif + +#undef UART_SPEED +#define UART_SPEED 23 + +void kdebug_init_arch() +{ + siu_out(UARTA_CONTROL_2, UART_SPEED); +} + +void kdebug_hwreset() +{ + +} + +void putc(char c) +{ + dword_t tmp = 0x44444444; + siu_out(UARTA_CONTROL_1, UART_ENABLE | UART_TX); + + siu_out(UARTA_DMA_CONTROL_1, (dword_t)virt_to_phys(&tmp)); + siu_out(UARTA_DMA_CONTROL_2, 3); +} + +char getc() +{ + return 0; +} + + diff --git a/kernel/kdb/mips-r4000.c b/kernel/kdb/mips-r4000.c new file mode 100644 index 0000000..52371ff --- /dev/null +++ b/kernel/kdb/mips-r4000.c @@ -0,0 +1,39 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips-r4000.c + * Description: Kdebug glue for the MIPS R4000. + * + * @LICENSE@ + * + * $Id: mips-r4000.c,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include "sgialib.h" + +void kdebug_hwreset() +{ + romvec->reboot(); +} + +void kdebug_init_arch() +{ +} + +void putc(char c) +{ + unsigned long cnt; + char it = c; + + romvec->write(1, &it, 1, &cnt); +} + +char getc() +{ + unsigned long cnt; + char c; + + romvec->read(0, &c, 1, &cnt); + return c; +} diff --git a/kernel/kdb/mips.c b/kernel/kdb/mips.c new file mode 100644 index 0000000..32e1364 --- /dev/null +++ b/kernel/kdb/mips.c @@ -0,0 +1,68 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips.c + * Description: MIPS specific kdebug stuff. + * + * @LICENSE@ + * + * $Id: mips.c,v 1.5 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) + + +#if defined(CONFIG_DEBUGGER_KDB) +int kdebug_arch_entry(exception_frame_t* frame) +{ + return 0; +} + +void kdebug_arch_exit(exception_frame_t* frame) +{ + return; +}; + +void kdebug_dump_pgtable(ptr_t pgtable) +{ + +} + +void kdebug_dump_frame(exception_frame_t *frame) +{ +} + + +void kdebug_pf_tracing(int state) +{ + extern int __kdebug_pf_tracing; + __kdebug_pf_tracing = state; +} + +void kdebug_single_stepping(exception_frame_t *frame, dword_t onoff) +{ +} + +void kdebug_breakpoint() +{ +} + +void kdebug_arch_help() +{ +} + +void kdebug_check_breakin() +{ + +} + +void kdebug_perfmon() +{ + +} + + +#endif + diff --git a/kernel/kdb/new-kdb.c b/kernel/kdb/new-kdb.c new file mode 100644 index 0000000..e7aef47 --- /dev/null +++ b/kernel/kdb/new-kdb.c @@ -0,0 +1,770 @@ +/********************************************************************* + * + * Copyright (C) 2001-2002, Karlsruhe University + * + * File path: new-kdb.c + * Description: New kernel debugger implementation. + * + * @LICENSE@ + * + * $Id: new-kdb.c,v 1.4 2002/02/19 18:03:39 ud3 Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +#include +#include "kdebug.h" +#include "kdebug_keys.h" +#include "kdebug_help.h" + +static int exit_kdb; + +extern int num_lines; +extern int name_tab_index; + +extern void dump_names(); +extern void set_name(); + +extern void kdebug_ipc_tracing(); +extern void kdebug_exception_tracing(); +extern void kdebug_pagefault_tracing(); + +extern void kdebug_arch_exit(exception_frame_t * frame); +extern int kdebug_arch_entry(exception_frame_t * frame); +extern void use_cache(); + +extern void strcpy(char *dest, char *src); +extern void kdebug_dump_trace(); + + +//name table +extern struct { + dword_t tid; + char name[9]; +} name_tab[32]; + +#if defined(CONFIG_DEBUG_TRACE_MDB) +int __kdebug_mdb_tracing = 0; +#endif + +void panic(const char *msg) +{ + printf("panic: %s", msg); + enter_kdebug("panic"); + while(1); +} + +void kdebug_reset() { + char c; + printf("reset computer? [n] "); + c = getc(); + if (c == 'y') { + putc(c); + kdebug_hwreset(); + } + else { + putc('n'); + putc('\n'); + } +} + +//taken from mini_kdb.c for small spaces + +tcb_t *kdebug_find_task_tcb(dword_t tasknum, tcb_t *current) +{ + tcb_t *tcb; + int first_time; + + for ( tcb = current, first_time = 1; + tcb != current || first_time; + tcb = tcb->present_next, first_time = 0 ) + if ( tcb->myself.x0id.task == tasknum) + return tcb; + + return NULL; +} + +void kdebug_print_help(struct kdb_help_t *h) { + for ( dword_t i = 0; h[i].key; i++ ) + { + printf(h[i].key == ' ' ? " spc" : + h[i].alternate_key ? " %c/%c" : " %c ", + h[i].key, h[i].alternate_key); + printf(" %s\n", h[i].help); + } +} + +void dump_mem(dword_t* p) {//output in other formats than hex + int i,j; + printf("\n memory dump: %x - %x", p, p+(4*(num_lines-3))); + for (i = 0; i < num_lines - 2; i++) { + printf("\n %p: ", &p[i*4]); + for (j = 0; j < 4; j++) + p[i*4+j] == 0x00000000 ? printf(" 0 ") : printf("%x ", p[i*4+j]); + printf(" "); + for (j = 0; j < 16; j++) + printf("%c", ((unsigned char* )p)[i*16+j] >= ' ' ? ((unsigned char* )p)[i*16+j] < 0x80 ? ((unsigned char* )p)[i*16+j] : '.' : '.'); + }; + printf("\n\n q: exit to debugger, pg up:scroll up, pg dn: scroll down "); +} + +#define CHUNKSIZE 0x400 + +#define MAX_KMEM_SIZECNT 10 +static dword_t num_chunks[MAX_KMEM_SIZECNT+1]; + +void kdebug_kmem_stats(void) +{ + extern dword_t *kmem_free_list; + extern dword_t free_chunks; + dword_t num, *cur, *prev, i, j, idx, max_chunks; + + /* Clear out statistics. */ + for ( idx = 0; idx <= MAX_KMEM_SIZECNT; idx++ ) + num_chunks[idx] = 0; + max_chunks = 0; + + for ( num = 1, cur = kmem_free_list, prev = NULL; + cur; + prev = cur, cur = (dword_t *) *cur ) + { + /* Are chunks contigous? */ + if ( (dword_t) prev + CHUNKSIZE == (dword_t) cur ) + num++; + else + num = 1; + + for ( i = j = 1, idx = 0; i <= num; i++ ) + { + if ( i == j ) + { + /* Number of chunks is power of 2. */ + dword_t mask = (j * CHUNKSIZE)-1; + dword_t tmp = (dword_t) cur - ((j-1) * CHUNKSIZE); + + /* Check if chunks are properly aligned. */ + if ( (tmp & mask) == 0 ) + { + if ( idx < MAX_KMEM_SIZECNT ) + num_chunks[idx]++; + else + num_chunks[MAX_KMEM_SIZECNT]++; + if ( idx > max_chunks ) + max_chunks = idx; + } + + j <<= 1; + idx++; + } + } + } + + printf("\nKmem statistics. Free chunks = %d (%dKB)\n", + free_chunks, (free_chunks*CHUNKSIZE)/1024); + printf("Chunks\tNum.\n"); + for ( i = 0; i <= MAX_KMEM_SIZECNT; i++ ) + { + printf(" %d%c\t %d\n", (1 << i), + i == MAX_KMEM_SIZECNT ? '+' : ' ', + num_chunks[i]); + } + printf("\n Max:\t %d\n", 1 << max_chunks); +} + +void kdebug_dump_tcb(tcb_t* tcb) +{ + /* max width 79 !!! */ +#if !defined(CONFIG_SMP) + printf("=== TCB: %p === TID: %p === PRIO: 0x%2x ===============", + tcb, (void*) tcb->myself.raw, tcb->priority); +#else + printf("=== TCB: %p === TID: %p === PRIO: 0x%2x === CPU: %2x ===", + tcb, (void*) tcb->myself.raw, + tcb->priority, tcb->cpu); +#endif + printf("%s ===\n", tcb->magic == TCB_MAGIC ? "====== OK" : " *BROKEN*"); + printf("UIP: %x queues: %c%c%c%c present: %p:%p space: %p\n", + get_user_ip(tcb), + 'R' + 0x20*!(tcb->queue_state & TS_QUEUE_READY), + 'P' + 0x20*!(tcb->queue_state & TS_QUEUE_PRESENT), + 'W' + 0x20*!(tcb->queue_state & TS_QUEUE_WAKEUP), + 'S' + 0x20*!(tcb->queue_state & TS_QUEUE_SEND), + tcb->present_prev, tcb->present_next, tcb->space); + printf("USP: %x tstate: %s ready: %p:%p pager: %x\n", + get_user_sp(tcb), + tcb->thread_state == TS_RUNNING ? "RUNNING" : + tcb->thread_state == TS_POLLING ? "POLLING" : + tcb->thread_state == TS_LOCKED_RUNNING ? "LCKRUNN" : + tcb->thread_state == TS_LOCKED_WAITING ? "LCKWAIT" : + tcb->thread_state == TS_ABORTED ? "ABORTED" : + tcb->thread_state == TS_WAITING ? + ((tcb->partner == L4_NIL_ID) ? "OWAIT " : + "WAITING"): + "???????", + tcb->ready_prev, tcb->ready_next, tcb->pager.raw); + printf("KSP: %p resour: %c%c%c%c wakeup: %p:%p excpt: %x\n", + tcb->stack, + tcb->resources & TR_IPC_MEM ? 'M' : 'm', + tcb->resources & TR_FPU ? 'F' : 'f', + tcb->resources & TR_LONG_IPC_PTAB ? 'P' : 'p', + tcb->resources & TR_DEBUG_REGS ? 'D' : 'd', + tcb->wakeup_prev, tcb->wakeup_next, tcb->excpt); + printf("KIP: %p send: %p:%p\n", + (ptr_t)((((dword_t)tcb->stack >= TCB_AREA) && + ((dword_t)tcb->stack < TCB_AREA+TCB_AREA_SIZE)) ? + *tcb->stack : (dword_t)-1), + tcb->send_prev, tcb->send_next); + printf("\n"); + printf("timeslc:\t%d/%d\n", tcb->current_timeslice, tcb->timeslice); + printf("partner:\t%T\ttimeout %x (cur. time: %x)\n", + tcb->partner.raw, (dword_t)tcb->ipc_timeout.raw, (dword_t)kernel_info_page.clock); + printf("sndqueue:\t%p\n", tcb->send_queue); + printf("IPC: %x:%x:%x\n", tcb->ipc_buffer[0], tcb->ipc_buffer[1], + tcb->ipc_buffer[2]); + printf("unwind:\t%p\n", tcb->unwind_ipc_sp); +#ifdef CONFIG_SMP + printf("tcb spinlock:\t%x\n", tcb->tcb_spinlock.lock); +#endif +#if defined(CONFIG_ENABLE_SMALL_AS) + smallid_t id = tcb->space->smallid (); + printf("Small space: "); + if (id.is_valid ()) + printf("%02x [size=%dMB, idx=%d]\n", id.value (), + id.bytesize () >> 20, id.idx ()); + else + printf("no\n"); +#endif +} + + +/** + * outputs the interrupt association + **/ +void kdebug_interrupt_association() { + printf("\nint association\n"); + int num = 0; + for (int i = 0; i < MAX_INTERRUPTS; i++) + if (interrupt_owner[i]) + printf("interrupt %2d: tcb %p (%t)%c", + i, interrupt_owner[i], interrupt_owner[i], + (num++) & 1 ? '\n' : '\t'); +} + +void common_menu(char c, struct kdb_help_t *h, exception_frame_t* frame) { + + tcb_t *current = ptr_to_tcb((ptr_t) frame); + space_t *space = NULL; + + switch (c) { + + case K_CPU_BREAKPOINT: + kdebug_breakpoint(); + break; + + case K_DUMP_TRACE: + kdebug_dump_trace(); + break; + + case K_FRAME_DUMP: + putc('\n'); + kdebug_dump_frame(frame); + break; + + case K_GO: + putc(c); + putc('\n'); + exit_kdb = 1; + return; + break; + + case K_HELP: + case K_HELP2: + kdebug_print_help(h); + printf("\nPress any key to go back.\n"); + break; + + case K_KERNEL_TCB_DUMP: + kdebug_dump_tcb(kdebug_get_thread(current)); + break; + + case K_MEM_DUMP: + space = get_current_space (); + /* FALLTHROUGH */ + case K_MEM_DUMP_OTHER: + { + dword_t *p, dw; + byte_t dc; + int i, j; + + putc(c); + p = (dword_t *) kdebug_get_hex(); + + if (space == NULL) + space = (space_t *) kdebug_get_pgtable( + current, "Address space (page-table/task-id/thread-id)" + " [current]: "); + + for ( i = 0; i < 16; i++ ) + { + printf(" %p: ", &p[i*4]); + for ( j = 0; j < 4; j++ ) + { + if ( kdebug_get_mem(space, &p[i*4+j], &dw) ) + printf("%p ", dw); + else + printf("######## "); + } + printf(" "); + for ( j = 0; j < 16; j++ ) + { + if ( kdebug_get_mem(space, (byte_t *) p+i*16+j, &dc) ) + printf("%c", dc >= ' ' ? dc < 0x80 ? dc :'.':'.'); + else + putc('#'); + } + putc('\n'); + } + + space = NULL; + break; + } + + + case K_MEM_PTAB_DUMP: + putc(c); + kdebug_dump_pgtable(kdebug_get_pgtable(current)); + break; + + case K_RESET: + case K_RESET2: + kdebug_reset(); + break; + } +} + +/* the configuration submenu */ +void config_debugger(exception_frame_t* frame) { + + char c; + + while ( ((c = getc()) != K_LEAVE_MENU) && (!exit_kdb) ) { + printf("Debugger configuration: "); + switch (c) { + + case K_CONFIG_CACHE: + use_cache(); + break; + + case K_CONFIG_KNOWN_NAMES: + + name_tab[0].tid = 0x04020001; + strcpy(name_tab[0].name, "sigma0"); + + name_tab[1].tid = 0x04040001; + strcpy(name_tab[1].name, "roottask"); + + name_tab[2].tid = 0x00000000; + strcpy(name_tab[2].name, "nil"); + + name_tab[3].tid = 0xffffffff; + strcpy(name_tab[3].name, "invalid"); + + name_tab[4].tid = 0x12345678; + strcpy(name_tab[4].name, "idler"); + + name_tab_index = 5; + dump_names(); + break; + + case K_CONFIG_NAMES: + set_name(); + break; + + case K_CONFIG_DUMP_NAMES: + dump_names(); + break; + + default: + //here are the shortcuts + common_menu(c, kdb_config_help, frame); + } + } +} + +/* the submenu for all memory stuff */ +void kdebug_memory_stuff(exception_frame_t* frame) { + + char c; + + while( ((c = getc()) != K_LEAVE_MENU) && (!exit_kdb) ) { + + printf("Memory menu:\n"); + + switch (c) { + + case K_MEM_MDB_DUMP: + putc(c); + kdebug_dump_map(kdebug_get_hex()); + break; + +#if defined(CONFIG_DEBUG_TRACE_MDB) + case K_MEM_MDB_TRACE: + c = kdebug_get_choice("mdb traing", "+/*/-"); + switch (c) + { + case '+': __kdebug_mdb_tracing = 2; break; + case '*': __kdebug_mdb_tracing = 1; break; + case '-': __kdebug_mdb_tracing = 0; break; + } + break; +#endif + case K_MEM_PF_TRACE: + case K_MEM_PF_TRACE2: +// printf("Pagefault tracing: "); + kdebug_pagefault_tracing(); + break; + default: + //here are some undocumented shortcuts + common_menu(c, kdb_mem_help, frame); + } + } +} + +/* the submenu for all the cpu dependent stuff */ +void kdebug_cpu_stuff(exception_frame_t* frame) { + char c; + tcb_t *current = ptr_to_tcb((ptr_t) frame); + + while( ((c = getc()) != K_LEAVE_MENU) && (!exit_kdb) ) { + + printf("CPU menu:\n"); + + switch (c) { + +#if defined(CONFIG_DEBUG_DISAS) + case K_CPU_DISASSEMBLE: +// printf("disassembler\n"); + kdebug_disassemble(frame); + break; +#endif + + case K_CPU_PERFCTR: + kdebug_perfmon(); + break; + +#if defined(CONFIG_ENABLE_PROFILING) + case K_CPU_PROFILE: + kdebug_profiling(current); + break; + + case K_CPU_PROFILE_DUMP: + kdebug_profile_dump(current); + break; +#endif + +#if 0 //i think i don't need this togeter with step instruction + case K_CPU_SINGLE_STEPPING: + c = kdebug_get_choice("single stepping", "+/-"); + switch (c) + { + case '+': kdebug_single_stepping(frame, 1); break; + case '-': kdebug_single_stepping(frame, 0); break; + } + break; +#endif + + case K_CPU_STATE: + printf("cpu state for"); + kdebug_cpustate(current); + break; + default: + //here are the shortcuts + common_menu(c, kdb_cpu_help, frame); + } + } +} + +/* submenu for all kernel things */ +void kdebug_kernel_stuff( exception_frame_t* frame) { + char c; + tcb_t *current = ptr_to_tcb((ptr_t) frame); + + while ( ((c = getc()) != K_LEAVE_MENU) && (!exit_kdb) ) { + printf("Kernel menu:\n"); + + switch (c) { + + case K_KERNEL_EXCPTN_TRACE: +// printf("exception tracing: \n"); + kdebug_exception_tracing(); + break; + + case K_KERNEL_INTERRUPT: + kdebug_interrupt_association(); + break; + + case K_KERNEL_IPC_TRACE: +// printf("ipc tracing: \n"); + kdebug_ipc_tracing(); + break; + + case K_KERNEL_QUEUES: + printf("\n"); + for (int i = MAX_PRIO; i >= 0; i--) + { + /* check whether we have something for this prio */ + tcb_t* walk = get_idle_tcb(); + do { + if ((int) walk->priority == i) + { + /* if so, print */ + printf("[%d]:", i); + walk = get_idle_tcb(); + do { + if ((int) walk->priority == i) { + if (walk->queue_state & TS_QUEUE_READY) + printf(" %p", walk); + else + printf(" (%p)", walk); + } + walk = walk->present_next; + } while (walk != get_idle_tcb()); + printf("\n"); + break; + } + walk = walk->present_next; + } while (walk != get_idle_tcb()); + } + printf("\n"); + break; + + case K_KERNEL_STATS: + c = kdebug_get_choice("stats", "Kmem/Mdb"); + switch (c) + { + case 'm': kdebug_mdb_stats(0x0, 0xffffffff); break; + case 'k': kdebug_kmem_stats(); break; + } + break; + + case K_KERNEL_TASK_DUMP: + { + tcb_t *tcb, *task = kdebug_get_task(current); + dword_t task_id = task->myself.x0id.task; + dword_t first_time = 1; + int n; + + printf("Task %02x:\n", task_id); + for ( tcb = current; + (tcb != current) || first_time; + tcb = tcb->present_next, first_time = 0 ) + { + if ( tcb->myself.x0id.task != task_id ) + continue; + + printf("%p (%t): ", tcb, tcb->myself); + + printf(" queues=[%c%c%c%c]", + 'R' + 0x20*!(tcb->queue_state & TS_QUEUE_READY), + 'P' + 0x20*!(tcb->queue_state & TS_QUEUE_PRESENT), + 'W' + 0x20*!(tcb->queue_state & TS_QUEUE_WAKEUP), + 'S' + 0x20*!(tcb->queue_state & TS_QUEUE_SEND)); + printf(" state=%s", + tcb->thread_state == TS_RUNNING ? "RUNNING" : + tcb->thread_state == TS_POLLING ? "POLLING" : + tcb->thread_state == TS_LOCKED_RUNNING ? "LCKRUNN" : + tcb->thread_state == TS_LOCKED_WAITING ? "LCKWAIT" : + tcb->thread_state == TS_ABORTED ? "ABORTED" : + tcb->thread_state == TS_WAITING ? + ((tcb->partner == L4_NIL_ID) ? "OWAIT " : + "WAITING") : "???????"); + n = printf(" partner=%p (%t)", tcb->partner, + tcb->partner); + for ( n = 29-n; n > 0; n-- ) putc(' '); + printf(" uip=%p", get_user_ip(tcb)); + putc('\n'); + } + break; + } + +#if defined(CONFIG_ENABLE_TRACEPOINTS) + case K_KERNEL_TRACEPOINT: + kdebug_tracepoint(); + break; +#endif + + default: + //here are the shortcuts + common_menu(c, kdb_kernel_help, frame); + } + } +} + + +/** + * the enter point to the debugger + **/ +int kdebug_entry(exception_frame_t* frame) { + + /* kdebug_arch_entry can decide about whether + to enter the interactive KDB (0) or not (1) */ + if (kdebug_arch_entry(frame) == 0) + { + +#if defined(CONFIG_SMP) + smp_enter_kdebug(); +#endif + + exit_kdb = 0; + char c; + + /* Works because frame resides on the kernel stack. */ + tcb_t *current = ptr_to_tcb((ptr_t) frame); + + extern dword_t _kdebug_stack_bottom[]; + extern dword_t _kdebug_stack_top[]; + if ( (dword_t) current < TCB_AREA || + ((dword_t) frame >= (dword_t) &_kdebug_stack_bottom && + (dword_t) frame < (dword_t) &_kdebug_stack_top) ) + /* In case we entered kdebug on startup, or caught an + exception inside KDB. */ + current = get_idle_tcb(); + +#if !defined(CONFIG_SMP) + printf("\n--------------------kernel-debugger--------------------\n"); +#else + extern dword_t __cpu_id; + printf("\n----------------kernel-debugger-cpu-%d-----------------\n", __cpu_id); +#endif + while (! exit_kdb) { + + printf("\nL4KD: "); + c = getc(); + + switch(c) { + + case K_CONFIG_STUFF: + printf("Configuration of the debugger:\n"); + config_debugger(frame); + break; + + case K_CPU_STUFF: + printf("cpu dependent part\n"); + kdebug_cpu_stuff(frame); + break; + + case K_HELP: + case K_HELP2: + printf("\nL4Ka Kernel Debugger Help:\n"); + kdebug_print_help(kdb_general_help); + printf("\nPress '%c', '%c', '%c' or '%c' for the Memory, CPU, Kernel\n" + " or cOnfiguration submenu,\n" + "any other key to go back to the main menu\n\n", + K_MEM_STUFF, K_CPU_STUFF, K_KERNEL_STUFF, K_CONFIG_STUFF); + + int back; + back = 0; + + while (!back) { + c = getc(); + if ( (c == K_CPU_STUFF) || (c == K_KERNEL_STUFF) || + (c == K_MEM_STUFF) || (c == K_CONFIG_STUFF) ) { + switch (c) { + case K_CONFIG_STUFF: + printf("Configuration submenu:\n"); + kdebug_print_help(kdb_config_help); + break; + case K_CPU_STUFF: + printf("CPU submenu:\n"); + kdebug_print_help(kdb_cpu_help); + break; + case K_KERNEL_STUFF: + printf("Kernel submenu:\n"); + kdebug_print_help(kdb_kernel_help); + break; + case K_MEM_STUFF: + printf("Memory submenu:\n"); + kdebug_print_help(kdb_mem_help); + break; + } + } + else { + back = 1; + } + } + // I want an other Helpmenu as in the common function here. + c = NULL; + break; + + case K_KERNEL_STUFF: + printf("kernel things\n"); + kdebug_kernel_stuff(frame); + break; + + case K_MEM_STUFF: + printf("memory dependent part:\n"); + kdebug_memory_stuff(frame); + break; + + case K_RESET: + case K_RESET2: + kdebug_reset(); + break; + + case K_STEP_BLOCK: + exit_kdb = kdebug_step_block(frame); + break; + + case K_STEP_INSTR: + exit_kdb = kdebug_step_instruction(frame); + break; + + default: + //here are the shortcuts + common_menu(c, kdb_general_help, frame); + } /* end of switch */ + } /* end of while (! exit_kdb) */ + +#if defined(CONFIG_SMP) + smp_leave_kdebug(); +#endif + } + kdebug_arch_exit(frame); + return -1; +} + + +/* +** +** Functions for safely accessing memory without causing page faults. +** +*/ + +extern dword_t mdb_pgshifts[]; + +int lookup_mapping(space_t * space, dword_t vaddr, ptr_t * paddr) +{ + pgent_t *pg = space->pgent (0); + dword_t pgsz = NUM_PAGESIZES-1; + + /* Look for valid page table entry. */ + pg = pg->next(space, table_index(vaddr, pgsz), pgsz); + while ( pg->is_valid(space, pgsz) && pg->is_subtree(space, pgsz) ) + { + pg = pg->subtree(space, pgsz--); + pg = pg->next(space, table_index(vaddr, pgsz), pgsz); + } + + if ( ! pg->is_valid(space, pgsz) ) + /* Return value of 0 indicates invalid address. */ + return 0; + + /* Store physical address into return parameter. */ + if (paddr) + *paddr = (ptr_t)(pg->address(space, pgsz) + (vaddr & page_mask(pgsz))); + + return 1; +} + +#endif /* CONFIG_DEBUGGER_NEW_KDB */ diff --git a/kernel/kdb/new-kdb.o b/kernel/kdb/new-kdb.o new file mode 100644 index 0000000..d9a9155 Binary files /dev/null and b/kernel/kdb/new-kdb.o differ diff --git a/kernel/kdb/pmc_values.h b/kernel/kdb/pmc_values.h new file mode 100644 index 0000000..1845567 --- /dev/null +++ b/kernel/kdb/pmc_values.h @@ -0,0 +1,289 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: pmc_values.h + * Description: Definition macros for performance counters the x86 + * PentiumPro family of processors. (What's the point + * of this file?) + * + * @LICENSE@ + * + * $Id: pmc_values.h,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#ifndef __pmc_values_h__ +#define __pmc_values_h__ + +/* Performance counter registers */ +#define PERFCTR0 193 +#define PERFCTR1 194 +#define PERFEVENTSEL0 390 +#define PERFEVENTSEL1 391 + +/* + * All these #defines come from the + * Intel Archictecture Software Developer's Manual, Volume 3 + * available from http://developer.intel.com + * which has more information about these counters. +*/ + +/* event masks */ +#define PMC_USER_MASK (1 << 16) +#define PMC_OS_MASK (1 << 17) +#define PMC_OCCURENCE_MASK (1 << 18) +#define PMC_ENABLE_MASK ((1 << 22)|(1<<20)) + +/* P6 Family Processor performance-monitoring events */ +/* (DCU) Unit */ + +/* All memory references, both cacheable and noncacheable. */ +#define DATA_MEM_REFS (0x0043) + +/* Total lines allocated in the DCU. */ +#define DCU_LINES_IN (0x0045) + +/* Number of M state lines allocated in the DCU. */ +#define DCU_M_LINES_IN (0x0046) + +/* Number of M state lines evicted from the DCU. This includes evictions via + snoop HITM, intervention or replacement. */ + +#define DCU_M_LINES_OUT (0x0047) + +/* +Weighted number of cycles while a DCU miss is outstanding. An access +that also misses the L2 is short-changed by 2 cycles (i.e., if counts +N cycles, should be N+2 cycles). Subsequent loads to the same cache +line will not result in any additional counts. Count value not +precise, but still useful. +*/ +#define DCU_MISS_OUTSTANDING (0x0048) + +/* Instruction Fetch Unit (IFU) */ + +/* Number of instruction fetches, both cacheable and noncacheable. */ +#define IFU_IFETCH (0x0080) + +/* Number of instruction fetch misses. */ +#define IFU_IFETCH_MISS (0x0081) + +/* Number of ITLB misses. */ +#define ITLB_MISS (0x0085) + +/* Number of cycles that the instruction fetch pipe stage is stalled, including cache misses, ITLB misses, ITLB faults, and victimcache evictions. */ +#define IFU_MEM_STALL (0x0086) + +/* Number of cycles that the instruction length decoder is stalled. */ +#define ILD_STALL (0x0087) + +/* L2 Cache events */ + +/* Number of L2 instruction fetches. */ +#define L2_IFETCH (0xf28) + +/* Number of L2 data loads. */ +#define L2_LD (0x0f29) + +/* Number of L2 data stores. */ +#define L2_ST (0x0f2A) + + +/* Number of lines allocated in the L2. */ +#define L2_LINES_IN (0x24) + +/* Number of lines removed from the L2 for any reason. */ +#define L2_LINES_OUT (0x26) + +/* Number of modified lines allocated in the L2. */ +#define L2_M_LINES_INM (0x25) + +/* Number of modified lines removed from the L2 for any reason. */ +#define L2_M_LINES_OUTM (0x27) + +/* Number of L2 requests. */ +#define L2_RQSTS (0x0f2E) + +/* Number of L2 address strobes. */ +#define L2_ADS (0x21) + +/* Number of cycles during which the data bus was busy. */ +#define L2_DBUS_BUSY (0x22) + +/* Number of cycles during which the data bus was busy transferring data from L2 to the processor. */ +#define L2_DBUS_BUSY_RD (0x23) + +/* External Bus Logic (EBL) */ + +/* Number of clocks during which DRDY is asserted by CPU. */ +#define BUS_DRDY_CLOCKS_SELF (0x62) + +/* (Any) Number of clocks during which DRDY is asserted by any agent. */ +#define BUS_DRDY_CLOCKS_ANY (0x2062) + +/* Number of clocks during which LOCK is asserted. Always counts in processor clocks. */ +#define BUS_LOCK_CLOCKS_SELF (0x63) + +/* Number of clocks during which LOCK is asserted. Always counts in processor clocks. */ +#define BUS_LOCK_CLOCKS_ANY (0x2063) + +/* Number of bus requests outstanding. Counts only DCU full- line cacheable reads, not RFOs, writes, instruction fetches, or anything else. Counts "waiting for bus to complete" (last data chunk received). + */ +#define BUS_REQ_OUTSTANDING_SELF (0x60) + +/* Number of bus requests outstanding. Counts only DCU full- line cacheable reads, not RFOs, writes, instruction fetches, or anything else. Counts "waiting for bus to complete" (last data chunk received). + */ +#define BUS_REQ_OUTSTANDING_ANY (0x2060) + +/* Number of burst read transactions. */ +#define BUS_TRAN_BRD_SELF (0x65) + +/* Number of burst read transactions. */ +#define BUS_TRAN_BRD_ANY (0x2065) + +/* Number of read for ownership transactions. */ +#define BUS_TRAN_RFO (0x66) + +/* Number of write back transactions. */ +#define BUS_TRANS_WB (0x67) + +/* Number of instruction fetch transactions. */ +#define BUS_TRAN_IFETCH (0x68) + +/* Number of invalidate transactions. */ +#define BUS_TRAN_INVAL (0x69) + +/* Number of partial write transactions. */ +#define BUS_TRAN_PWR (0x6A) + +/* Number of partial transactions. */ +#define BUS_TRANS_P (0x6B) + +/* Number of I/O transactions. */ +#define BUS_TRANS_IO (0x6C) + +/* Number of deferred transactions. */ +#define BUS_TRAN_DEF (0x6D) + +/* Number of burst transactions. */ +#define BUS_TRAN_BURST (0x6E) + +/* Number of all transactions. */ +#define BUS_TRAN_ANY (0x70) + +/* Number of memory transactions. */ +#define BUS_TRAN_MEM (0x6F) + +/* Number of bus clock cycles during which this processor is receiving data. */ +#define BUS_DATA_RCV (0x64) + +/* Number of bus clock cycles during which this processor is driving the BNR pin. */ +#define BUS_BNR_DRV (0x61) + +/* Number of bus clock cycles during which this processor is driving the HIT pin. Includes cycles due to snoop stalls. */ +#define BUS_HIT_DRV (0x7A) + +/* Number of bus clock cycles during which this processor is driving the HITM pin. Includes cycles due to snoop stalls. */ +#define BUS_HITM_DRV (0x7B) + +/* (Self) Number of clock cycles during which the bus is snoop stalled. */ +#define BUS_SNOOP_STALL (0x7E) + +/* Floating- Point Unit */ + +/* Number of computational floating-point operations retired. Counter 0 only */ +#define FLOPS (0xC1) + +/* Number of computational floating-point operations executed. Counter 0 only. */ +#define FP_COMP_OPS_EXE (0x10) + +/* Number of floating- point exception cases handled by microcode. Counter 1 only. */ +#define FP_ASSIST (0x11) + +/* Number of multiplies. Counter 1 only. */ +#define MUL (0x12) + +/* Number of divides. Counter 1 only. */ +#define DIV (0x13) + +/* Number of cycles during which the divider is busy. Counter 0 only. */ +#define CYCLES_DIV_BUSY (0x14) + +/* Memory Ordering */ + +/* Number of store buffer blocks. */ +#define LD_BLOCKS (0x03) + +/* Number of store buffer drain cycles. */ +#define SB_DRAINS (0x04) + +/* Number of misaligned data memory references. */ +#define MISALIGN_MEM_REF (0x05) + +/* Instruction Decoding and Retirement */ + +/* Number of instructions retired. */ +#define INST_RETIRED (0xC0) + +/* Number of UOPs retired. */ +#define UOPS_RETIRED (0xC2) + +/* Number of instructions decoded. */ +#define INST_DECODER (0xD0) + +/*Interrupts */ + +/* Number of hardware interrupts received. */ +#define HW_INT_RX (0xC8) + +/* Number of processor cycles for which interrupts are disabled. */ +#define CYCLES_INT_MASKED (0xC6) + +/* Number of processor cycles for which interrupts are disabled and interrupts are pending. */ +#define CYCLES_INT_PENDING_AND_MASKED (0xC7) + +/* Branches */ + + /* Number of branch instructions retired. */ +#define BR_INST_RETIRED (0xC4) + + /* Number of mispredicted branches retired. */ +#define BR_MISS_PRED_RETIRED (0xC5) + + /* Number of taken branches retired. */ +#define BR_TAKEN_RETIRED (0xC9) + + /* Number of taken mispredictions branches retired. */ +#define BR_MISS_PRED_NRET (0xCA) + + /* Number of branch instructions decoded. */ +#define BR_INST_DECODED (0xE0) + + /* Number of branches that miss the BTB. */ +#define BTB_MISSES (0xE2) + + /* Number of bogus branches. */ +#define BR_BOGUS (0xE4) + + /* Number of time BACLEAR is asserted. */ +#define BACLEARS (0xE6) + +/* Stalls */ + + /* Number of cycles during which there are resource related stalls. */ +#define RESOURCE_STALLS (0xA2) + + /* Number of cycles or events for partial stalls. */ +#define PARTIAL_RAT_STALLS (0xD2) + +/* Segment Register Loads */ + +/* Number of segment register loads. */ +#define SEGMENT_REG_LOADS (0x06) + +/*Clocks */ + +/* Number of cycles during which the processor is not halted. */ +#define CPU_CLK_UNHALTED (0x79) + +#endif /* __pmc_values_h__ */ diff --git a/kernel/kdb/print.c b/kernel/kdb/print.c new file mode 100644 index 0000000..d7b507c --- /dev/null +++ b/kernel/kdb/print.c @@ -0,0 +1,223 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: print.c + * Description: Various output functions for the kernel debugger. + * + * @LICENSE@ + * + * $Id: print.c,v 1.34 2001/12/04 16:56:50 uhlig Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) + +static int print_hex(dword_t val) L4_SECT_KDEBUG; +static int print_hex(word_t val) L4_SECT_KDEBUG; +static int print_hex(byte_t val) L4_SECT_KDEBUG; +static int print_string(char* s) L4_SECT_KDEBUG; +static int print_dec(dword_t val, dword_t width = 0) L4_SECT_KDEBUG; +int do_printf(const char** format_p) L4_SECT_KDEBUG; + +static const byte_t hexchars[] L4_SECT_KDEBUG = "0123456789abcdef"; + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +extern struct { + dword_t tid; + char name[9]; +} name_tab[32]; +#endif + +static int print_hex(dword_t val) +{ + int i, n = 1; + for ( i = 28; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} + +static int print_hex(word_t val) +{ + int i, n = 1; + for ( i = 12; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} + +static int print_hex(byte_t val) +{ + int i, n = 1; + for ( i = 4; i >= 0; i -= 4, n++ ) + putc(hexchars[(val >> i) & 0xF]); + return n; +} + +static int print_string(char* s) +{ + int n = 0; + while ( *s ) { putc(*s++); n++; } + return n; +} + + +static int print_dec(dword_t val, dword_t width) +{ + char buff[16]; + int i = 14; + + buff[15] = '\0'; + do + { + buff[i] = (val % 10) + '0'; + val = val / 10; + i--; + if ( width > 0 ) width--; + } while( val ); + + while ( i >= 0 && width-- > 0 ) + buff[i--] = ' '; + + return print_string(&buff[i+1]); +} + + +DEFINE_SPINLOCK(printf_spin_lock); + +int do_printf(const char** format_p) +{ + const char* format = *format_p; + int n = 0; + int i = 0; + int width = 8; + +#define arg(x) (((dword_t*) format_p)[(x)+1]) + + spin_lock(&printf_spin_lock); + + /* sanity check */ + if (format == NULL) + return 0; + + while (*format) + { + switch (*(format)) + { + case '%': + width = 0; + reentry: + switch (*(++format)) + { + case '0'...'9': + width = width*10 + (*format)-'0'; + goto reentry; + break; + case 'c': + putc(arg(i)); + n++; + break; + case 'd': + n += print_dec(arg(i), width); + break; + case 'p': + case 'x': + switch(width) { + case 2: n += print_hex((byte_t) arg(i)); break; + case 4: n += print_hex((word_t) arg(i)); break; + default: n += print_hex((dword_t) arg(i)); break; + } + break; + case 's': + if ((char*) arg(i)) + n += print_string((char*) arg(i)); + else + n += print_string("(null)"); + break; + case 'T': + if (l4_is_invalid_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("INVALID "); break; + } + if (l4_is_nil_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("NIL_ID "); break; + } +#if defined(CONFIG_DEBUGGER_NEW_KDB) + //print nickname if possible + for (i=0; i<32; i++) + if (name_tab[i].tid == (dword_t) arg(i)) { + print_string(name_tab[i].name); + break; + } + //else print hex value +#endif + if (arg(i) < 17) + { + n += print_string("IRQ_"); + if (arg(i) < 11) { putc(' '); n++; } + n += print_dec(arg(i)-1); if (arg(i) < 11) putc(' '); + n += print_string(" "); + } + print_hex(arg(i)); + break; + case 't': + if (l4_is_invalid_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("INVALID"); break; + } + if (l4_is_nil_id((l4_threadid_t) {raw : arg(i)})) + { + n += print_string("NIL_ID"); break; + } +#if defined(CONFIG_DEBUGGER_NEW_KDB) + //print nickname if possible + for (i=0; i<32; i++) + if (name_tab[i].tid == (dword_t) arg(i)) { + print_string(name_tab[i].name); + break; + } + //else print hex value +#endif + if (arg(i) < 17) + { + n += print_string("IRQ_"); + n += print_dec(arg(i)-1); + } + else + { + print_hex((byte_t) (((l4_threadid_t) { + raw : arg(i)}).x0id.task)); + putc('.'); + print_hex((byte_t) (((l4_threadid_t) { + raw : arg(i)}).x0id.thread)); + n += 5; + } + break; + case '%': + putc('%'); + n++; + format++; + continue; + default: + n += print_string("?"); + break; + }; + i++; + break; + default: + putc(*format); + n++; + if(*format == '\n') + putc('\r'); + break; + } + format++; + } + spin_unlock(&printf_spin_lock); + return n; +} + +int printf(const char* format,...) +{ + return do_printf(&format); +}; diff --git a/kernel/kdb/print.o b/kernel/kdb/print.o new file mode 100644 index 0000000..a694c44 Binary files /dev/null and b/kernel/kdb/print.o differ diff --git a/kernel/kdb/sgialib.h b/kernel/kdb/sgialib.h new file mode 100644 index 0000000..e340d84 --- /dev/null +++ b/kernel/kdb/sgialib.h @@ -0,0 +1,122 @@ +/* $Id: sgialib.h,v 1.1 2000/09/14 15:36:34 uhlig Exp $ + * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#ifndef _MIPS_SGIALIB_H +#define _MIPS_SGIALIB_H + +#include + +extern struct linux_promblock *sgi_pblock; +extern struct linux_romvec *romvec; +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +extern int prom_flags; +#define PROM_FLAG_ARCS 1 + +/* Init the PROM library and it's internal data structures. Called + * at boot time from head.S before start_kernel is invoked. + */ +extern int prom_init(int argc, char **argv, char **envp); + +/* Simple char-by-char console I/O. */ +extern void prom_putchar(char c); +extern char prom_getchar(void); + +/* Generic printf() using ARCS console I/O. */ +extern void prom_printf(char *fmt, ...); + +/* Memory descriptor management. */ +#define PROM_MAX_PMEMBLOCKS 32 +struct prom_pmemblock { + unsigned long base; /* Within KSEG0. */ + unsigned int size; /* In bytes. */ + unsigned int type; /* free or prom memory */ +}; + +/* Get next memory descriptor after CURR, returns first descriptor + * in chain is CURR is NULL. + */ +extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); +#define PROM_NULL_MDESC ((struct linux_mdesc *) 0) + +/* Called by prom_init to setup the physical memory pmemblock + * array. + */ +extern void prom_meminit(void); +extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); + +/* Returns pointer to PROM physical memory block array. */ +extern struct prom_pmemblock *prom_getpblock_array(void); + +/* PROM device tree library routines. */ +#define PROM_NULL_COMPONENT ((pcomponent *) 0) + +/* Get sibling component of THIS. */ +extern pcomponent *prom_getsibling(pcomponent *prom_this); + +/* Get child component of THIS. */ +extern pcomponent *prom_getchild(pcomponent *prom_this); + +/* Get parent component of CHILD. */ +extern pcomponent *prom_getparent(pcomponent *child); + +/* Copy component opaque data of component THIS into BUFFER + * if component THIS has opaque data. Returns success or + * failure status. + */ +extern long prom_getcdata(void *buffer, pcomponent *prom_this); + +/* Other misc. component routines. */ +extern pcomponent *prom_childadd(pcomponent *prom_this, pcomponent *tmp, void *data); +extern long prom_delcomponent(pcomponent *prom_this); +extern pcomponent *prom_componentbypath(char *path); + +/* This is called at prom_init time to identify the + * ARC architecture we are running on + */ +extern void prom_identify_arch(void); + +/* Environemt variable routines. */ +extern char *prom_getenv(char *name); +extern long prom_setenv(char *name, char *value); + +/* ARCS command line acquisition and parsing. */ +extern char *prom_getcmdline(void); +extern void prom_init_cmdline(void); + +/* Acquiring info about the current time, etc. */ +extern struct linux_tinfo *prom_gettinfo(void); +extern unsigned long prom_getrtime(void); + +/* File operations. */ +extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt); +extern long prom_open(char *name, enum linux_omode md, unsigned long *fd); +extern long prom_close(unsigned long fd); +extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_getrstatus(unsigned long fd); +extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm); +extern long prom_mount(char *name, enum linux_mountops op); +extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf); +extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk); + +/* Running stand-along programs. */ +extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr); +extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp); +extern long prom_exec(char *name, long argc, char **argv, char **envp); + +/* Misc. routines. */ +extern void prom_halt(void) __attribute__((noreturn)); +extern void prom_powerdown(void) __attribute__((noreturn)); +extern void prom_restart(void) __attribute__((noreturn)); +extern void prom_reboot(void) __attribute__((noreturn)); +extern void prom_imode(void) __attribute__((noreturn)); +extern long prom_cfgsave(void); +extern struct linux_sysid *prom_getsysid(void); +extern void prom_cacheflush(void); + +#endif /* !(_MIPS_SGIALIB_H) */ diff --git a/kernel/kdb/sgiarcs.h b/kernel/kdb/sgiarcs.h new file mode 100644 index 0000000..bfe9a34 --- /dev/null +++ b/kernel/kdb/sgiarcs.h @@ -0,0 +1,375 @@ +/* $Id: sgiarcs.h,v 1.2 2001/07/13 20:01:08 ud3 Exp $ + * + * SGI ARCS firmware interface defines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * copy-n-paste from linux + */ + +#ifndef _MIPS_SGIARCS_H +#define _MIPS_SGIARCS_H + +/* Various ARCS error codes. */ +#define PROM_ESUCCESS 0x00 +#define PROM_E2BIG 0x01 +#define PROM_EACCESS 0x02 +#define PROM_EAGAIN 0x03 +#define PROM_EBADF 0x04 +#define PROM_EBUSY 0x05 +#define PROM_EFAULT 0x06 +#define PROM_EINVAL 0x07 +#define PROM_EIO 0x08 +#define PROM_EISDIR 0x09 +#define PROM_EMFILE 0x0a +#define PROM_EMLINK 0x0b +#define PROM_ENAMETOOLONG 0x0c +#define PROM_ENODEV 0x0d +#define PROM_ENOENT 0x0e +#define PROM_ENOEXEC 0x0f +#define PROM_ENOMEM 0x10 +#define PROM_ENOSPC 0x11 +#define PROM_ENOTDIR 0x12 +#define PROM_ENOTTY 0x13 +#define PROM_ENXIO 0x14 +#define PROM_EROFS 0x15 +/* SGI ARCS specific errno's. */ +#define PROM_EADDRNOTAVAIL 0x1f +#define PROM_ETIMEDOUT 0x20 +#define PROM_ECONNABORTED 0x21 +#define PROM_ENOCONNECT 0x22 + +/* Device classes, types, and identifiers for prom + * device inventory queries. + */ +enum linux_devclass { + system, processor, cache, adapter, controller, peripheral, memory +}; + +enum linux_devtypes { + /* Generic stuff. */ + Arc, Cpu, Fpu, + + /* Primary insn and data caches. */ + picache, pdcache, + + /* Secondary insn, data, and combined caches. */ + sicache, sdcache, sccache, + + memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter, + multifunc_adapter, dsk_controller, tp_controller, cdrom_controller, + worm_controller, serial_controller, net_controller, disp_controller, + parallel_controller, ptr_controller, kbd_controller, audio_controller, + misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral, + modem_peripheral, monitor_peripheral, printer_peripheral, + ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral, + net_peripheral, misc_peripheral, anon +}; + +enum linux_identifier { + bogus, ronly, removable, consin, consout, input, output +}; + +/* A prom device tree component. */ +struct linux_component { + enum linux_devclass dclass; /* node class */ + enum linux_devtypes type; /* node type */ + enum linux_identifier iflags; /* node flags */ + unsigned short vers; /* node version */ + unsigned short rev; /* node revision */ + unsigned long key; /* completely magic */ + unsigned long amask; /* XXX affinity mask??? */ + unsigned long cdsize; /* size of configuration data */ + unsigned long ilen; /* length of string identifier */ + char *iname; /* string identifier */ +}; +typedef struct linux_component pcomponent; + +struct linux_sysid { + char vend[8], prod[8]; +}; + +/* ARCS prom memory descriptors. */ +enum arcs_memtypes { + arcs_eblock, /* exception block */ + arcs_rvpage, /* ARCS romvec page */ + arcs_fcontig, /* Contiguous and free */ + arcs_free, /* Generic free memory */ + arcs_bmem, /* Borken memory, don't use */ + arcs_prog, /* A loaded program resides here */ + arcs_atmp, /* ARCS temporary storage area, wish Sparc OpenBoot told this */ + arcs_aperm, /* ARCS permanent storage... */ +}; + +/* ARC has slightly different types than ARCS */ +enum arc_memtypes { + arc_eblock, /* exception block */ + arc_rvpage, /* romvec page */ + arc_free, /* Generic free memory */ + arc_bmem, /* Borken memory, don't use */ + arc_prog, /* A loaded program resides here */ + arc_atmp, /* temporary storage area */ + arc_aperm, /* permanent storage */ + arc_fcontig, /* Contiguous and free */ +}; + +union linux_memtypes { + enum arcs_memtypes arcs; + enum arc_memtypes arc; +}; + +struct linux_mdesc { + union linux_memtypes type; + unsigned long base; + unsigned long pages; +}; + +/* Time of day descriptor. */ +struct linux_tinfo { + unsigned short yr; + unsigned short mnth; + unsigned short day; + unsigned short hr; + unsigned short min; + unsigned short sec; + unsigned short msec; +}; + +/* ARCS virtual dirents. */ +struct linux_vdirent { + unsigned long namelen; + unsigned char attr; + char fname[32]; /* XXX imperical, should be a define */ +}; + +/* Other stuff for files. */ +enum linux_omode { + rdonly, wronly, rdwr, wronly_creat, rdwr_creat, + wronly_ssede, rdwr_ssede, dirent, dirent_creat +}; + +enum linux_seekmode { + absolute, relative +}; + +enum linux_mountops { + media_load, media_unload +}; + +/* This prom has a bolixed design. */ +struct linux_bigint { +#ifdef __MIPSEL__ + unsigned long lo; + long hi; +#else /* !(__MIPSEL__) */ + long hi; + unsigned long lo; +#endif +}; + +struct linux_finfo { + struct linux_bigint begin; + struct linux_bigint end; + struct linux_bigint cur; + enum linux_devtypes dtype; + unsigned long namelen; + unsigned char attr; + char name[32]; /* XXX imperical, should be define */ +}; + +struct linux_romvec { + /* Load an executable image. */ + long (*load)(char *file, unsigned long end, + unsigned long *start_pc, + unsigned long *end_addr); + + /* Invoke a standalong image. */ + long (*invoke)(unsigned long startpc, unsigned long sp, + long argc, char **argv, char **envp); + + /* Load and begin execution of a standalong image. */ + long (*exec)(char *file, long argc, char **argv, char **envp); + + void (*halt)(void) __attribute__((noreturn)); /* Halt the machine. */ + void (*pdown)(void) __attribute__((noreturn)); /* Power down the machine. */ + void (*restart)(void) __attribute__((noreturn)); /* XXX soft reset??? */ + void (*reboot)(void) __attribute__((noreturn)); /* Reboot the machine. */ + void (*imode)(void) __attribute__((noreturn)); /* Enter PROM interactive mode. */ + int _unused1; /* padding */ + + /* PROM device tree interface. */ + pcomponent *(*next_component)(pcomponent *prom_this); + pcomponent *(*child_component)(pcomponent *prom_this); + pcomponent *(*parent_component)(pcomponent *prom_this); + long (*component_data)(void *opaque_data, pcomponent *prom_this); + pcomponent *(*child_add)(pcomponent *prom_this, + pcomponent *tmp, + void *opaque_data); + long (*comp_del)(pcomponent *prom_this); + pcomponent *(*component_by_path)(char *file); + + /* Misc. stuff. */ + long (*cfg_save)(void); + struct linux_sysid *(*get_sysid)(void); + + /* Probing for memory. */ + struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr); + long _unused2; /* padding */ + + struct linux_tinfo *(*get_tinfo)(void); + unsigned long (*get_rtime)(void); + + /* File type operations. */ + long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry, + unsigned long num, unsigned long *count); + long (*open)(char *file, enum linux_omode mode, unsigned long *fd); + long (*close)(unsigned long fd); + long (*read)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*get_rstatus)(unsigned long fd); + long (*write)(unsigned long fd, void *buffer, unsigned long num, + unsigned long *count); + long (*seek)(unsigned long fd, struct linux_bigint *offset, + enum linux_seekmode smode); + long (*mount)(char *file, enum linux_mountops op); + + /* Dealing with firmware environment variables. */ + char *(*get_evar)(char *name); + long (*set_evar)(char *name, char *value); + + long (*get_finfo)(unsigned long fd, struct linux_finfo *buf); + long (*set_finfo)(unsigned long fd, unsigned long flags, + unsigned long mask); + + /* Miscellaneous. */ + void (*cache_flush)(void); +}; + +/* The SGI ARCS parameter block is in a fixed location for standalone + * programs to access PROM facilities easily. + */ +struct linux_promblock { + long magic; /* magic cookie */ +#define PROMBLOCK_MAGIC 0x53435241 + + unsigned long len; /* length of parm block */ + unsigned short ver; /* ARCS firmware version */ + unsigned short rev; /* ARCS firmware revision */ + long *rs_block; /* Restart block. */ + long *dbg_block; /* Debug block. */ + long *gevect; /* XXX General vector??? */ + long *utlbvect; /* XXX UTLB vector??? */ + unsigned long rveclen; /* Size of romvec struct. */ + struct linux_romvec *romvec; /* Function interface. */ + unsigned long pveclen; /* Length of private vector. */ + long *pvector; /* Private vector. */ + long adap_cnt; /* Adapter count. */ + long adap_typ0; /* First adapter type. */ + long adap_vcnt0; /* Adapter 0 vector count. */ + long *adap_vector; /* Adapter 0 vector ptr. */ + long adap_typ1; /* Second adapter type. */ + long adap_vcnt1; /* Adapter 1 vector count. */ + long *adap_vector1; /* Adapter 1 vector ptr. */ + /* More adapter vectors go here... */ +}; + +#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL) +#define ROMVECTOR ((PROMBLOCK)->romvec) + +#if 0 + +/* Cache layout parameter block. */ +union linux_cache_key { + struct param { +#ifdef __MIPSEL__ + unsigned short size; + unsigned char lsize; + unsigned char bsize; +#else /* !(__MIPSEL__) */ + unsigned char bsize; + unsigned char lsize; + unsigned short size; +#endif + } info; + unsigned long allinfo; +}; + +/* Configuration data. */ +struct linux_cdata { + char *name; + int mlen; + enum linux_devtypes type; +}; + +/* Common SGI ARCS firmware file descriptors. */ +#define SGIPROM_STDIN 0 +#define SGIPROM_STDOUT 1 + +/* Common SGI ARCS firmware file types. */ +#define SGIPROM_ROFILE 0x01 /* read-only file */ +#define SGIPROM_HFILE 0x02 /* hidden file */ +#define SGIPROM_SFILE 0x04 /* System file */ +#define SGIPROM_AFILE 0x08 /* Archive file */ +#define SGIPROM_DFILE 0x10 /* Directory file */ +#define SGIPROM_DELFILE 0x20 /* Deleted file */ + +/* SGI ARCS boot record information. */ +struct sgi_partition { + unsigned char flag; +#define SGIPART_UNUSED 0x00 +#define SGIPART_ACTIVE 0x80 + + unsigned char shead, ssect, scyl; /* unused */ + unsigned char systype; /* OS type, Irix or NT */ + unsigned char ehead, esect, ecyl; /* unused */ + unsigned char rsect0, rsect1, rsect2, rsect3; + unsigned char tsect0, tsect1, tsect2, tsect3; +}; + +#define SGIBBLOCK_MAGIC 0xaa55 +#define SGIBBLOCK_MAXPART 0x0004 + +struct sgi_bootblock { + unsigned char _unused[446]; + struct sgi_partition partitions[SGIBBLOCK_MAXPART]; + unsigned short magic; +}; + +/* BIOS parameter block. */ +struct sgi_bparm_block { + unsigned short bytes_sect; /* bytes per sector */ + unsigned char sect_clust; /* sectors per cluster */ + unsigned short sect_resv; /* reserved sectors */ + unsigned char nfats; /* # of allocation tables */ + unsigned short nroot_dirents; /* # of root directory entries */ + unsigned short sect_volume; /* sectors in volume */ + unsigned char media_type; /* media descriptor */ + unsigned short sect_fat; /* sectors per allocation table */ + unsigned short sect_track; /* sectors per track */ + unsigned short nheads; /* # of heads */ + unsigned short nhsects; /* # of hidden sectors */ +}; + +struct sgi_bsector { + unsigned char jmpinfo[3]; + unsigned char manuf_name[8]; + struct sgi_bparm_block info; +}; + +/* Debugging block used with SGI symmon symbolic debugger. */ +#define SMB_DEBUG_MAGIC 0xfeeddead +struct linux_smonblock { + unsigned long magic; + void (*handler)(void); /* Breakpoint routine. */ + unsigned long dtable_base; /* Base addr of dbg table. */ + int (*printf)(const char *fmt, ...); + unsigned long btable_base; /* Breakpoint table. */ + unsigned long mpflushreqs; /* SMP cache flush request list. */ + unsigned long ntab; /* Name table. */ + unsigned long stab; /* Symbol table. */ + int smax; /* Max # of symbols. */ +}; + +#endif + +#endif /* !(_MIPS_SGIARCS_H) */ diff --git a/kernel/kdb/tracepoints.c b/kernel/kdb/tracepoints.c new file mode 100644 index 0000000..b2ce4ab --- /dev/null +++ b/kernel/kdb/tracepoints.c @@ -0,0 +1,119 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: tracepoints.c + * Description: KDB Kernel Tracepoint interface. + * + * @LICENSE@ + * + * $Id: tracepoints.c,v 1.5 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_ENABLE_TRACEPOINTS) +#include +#include "kdebug.h" + + +/* + * Create list of description strings. + */ +#define DEFINE_TP(x, y) #x, + +char *tracepoint_name[] = { + "Quit (no tracepoint)", +# include +}; + + +byte_t tracepoint_is_set[(TP_MAX+7) >> 3] L4_SECT_KDEBUG; +byte_t tracepoint_enters_kdb[(TP_MAX+7) >> 3] L4_SECT_KDEBUG; +dword_t tracepoint_cnt[TP_MAX] L4_SECT_KDEBUG; + + +void kdebug_tracepoint(void) +{ + dword_t num = 0, n, i; + char c1 = 0, c2 = 0; + + c1 = kdebug_get_choice("\nTracepoint", + "Set/Clear/List/Reset counters" + "/clear All/Enable all", 'l'); + switch (c1) + { + case 'a': + for ( i = 0; i < sizeof(tracepoint_is_set); i++ ) + tracepoint_is_set[i] = tracepoint_enters_kdb[i] = 0; + return; + case 'e': + for ( i = 0; i < sizeof(tracepoint_is_set); i++ ) + tracepoint_is_set[i] = ~0, tracepoint_enters_kdb[i] = 0; + return; + case 'r': + for ( i = 0; i < TP_MAX; i++ ) + tracepoint_cnt[i] = 0; + return; + case 's': + case 'c': + break; + case 'l': + c2 = kdebug_get_choice("List", "All/Enabled", 'a'); + kdebug_list_tracepoints(c2 == 'a'); + return; + } + + while ( num == 0 ) + { + printf("Tracepoint [list]: "); + num = kdebug_get_dec(0xffff, "list"); + if ( num >= TP_MAX ) + { + for ( i = 0; i < (TP_MAX+1)/2; i++ ) + { + n = printf(" %2d - %s", i, tracepoint_name[i]); + if ( i + TP_MAX/2 < TP_MAX ) + { + for ( n = 38-n; n--; ) putc(' '); + printf("%2d - %s\n", i + TP_MAX/2, + tracepoint_name[i + TP_MAX/2]); + } + else + printf("\n"); + } + num = 0; + } + else if ( num == 0 ) + return; + } + + if ( c1 == 's' ) + { + c2 = kdebug_get_choice("Enter kdebug", "Yes/No", 'n'); + set_tracepoint(num, c2 == 'y'); + } + else + clr_tracepoint(num); +} + + +void kdebug_list_tracepoints(int list_all) +{ + printf("Num KDB Name Count\n"); + for ( int i = 1; i < TP_MAX; i++ ) + if ( list_all || is_tracepoint_set(i) ) + { + dword_t n = printf("%3d %c %s", i, + does_tracepoint_enter_kdb(i) ? 'y' : ' ', + tracepoint_name[i]); + + for ( n = 40-n; n--; ) putc(' '); + printf("%7d\n", tracepoint_cnt[i]); + } +} + + + + +#endif /* CONFIG_ENABLE_TRACEPOINTS */ diff --git a/kernel/kdb/tracepoints.o b/kernel/kdb/tracepoints.o new file mode 100644 index 0000000..5072f6d Binary files /dev/null and b/kernel/kdb/tracepoints.o differ diff --git a/kernel/kdb/tracing.c b/kernel/kdb/tracing.c new file mode 100644 index 0000000..7f294b6 --- /dev/null +++ b/kernel/kdb/tracing.c @@ -0,0 +1,899 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: tracing.c + * Description: Some sort of tracing facility. + * + * @LICENSE@ + * + * $Id: tracing.c,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include +#if defined(CONFIG_DEBUGGER_NEW_KDB) + +#include "kdebug_keys.h" +#include "kdebug.h" + +//the length of the buffers for ipc and pf tracing +#define TRACE_BUFF_SIZE 100 +//the length of the restriction arrays +#define RESTR_LENGTH 20 +//the length of the trace buffer +#define TRACE_SIZE 718 /* 57 bytes per element, 10 pages used, 718 elementes */ + + +extern char* get_name(dword_t nr, char* res); +extern int pf_usermode(dword_t errcode); +extern dword_t* change_idt_entry(int interrupt_no, ptr_t new_handler); +extern dword_t* change_sysenter_eip_msr(ptr_t new_handler); +extern dword_t to_hex(char* name); + +//the interrupt assembler stubs +extern "C" void trace_pf(); +extern "C" void trace_ipc(); +extern "C" void trace_exception(); +#if 0 +//pmc overflow +extern "C" void apic_int_59(); +#endif +//the interrupt assembler stubs for exception monitoring +extern "C" void monitor_int_0(); +extern "C" void monitor_int_4(); +extern "C" void monitor_int_5(); +extern "C" void monitor_int_6(); +extern "C" void monitor_int_7(); +extern "C" void monitor_int_8(); +extern "C" void monitor_int_9(); +extern "C" void monitor_int_10(); +extern "C" void monitor_int_11(); +extern "C" void monitor_int_12(); +extern "C" void monitor_int_16(); +extern "C" void monitor_int_17(); +extern "C" void monitor_int_18(); +extern "C" void monitor_int_19(); + + +int is_restricted(dword_t tid, dword_t errcode, char type); + + +struct { + + struct { + unsigned use : 1; //turn on/off ipc tracing + unsigned to_do : 1; //enter debugger after every event + unsigned restr : 1; //which thread is restricted + unsigned only_sendpart : 1; //only threads with sendpart + } ipc; + + struct { + unsigned use : 1; + unsigned to_do : 1; + unsigned restr : 1; + } pf; + + struct { + unsigned use : 1; + unsigned to_do : 1; + unsigned restr : 1; + unsigned with_errcode : 1; //only exceptions with errorcode in intervall are restricted + } exception; + +} trace_controlling = { {NO, DISPLAY, THREADS_IN_LIST, NO}, //ipc + {NO, DISPLAY, THREADS_IN_LIST}, //pf + {NO, DISPLAY, THREADS_IN_LIST, NO} //exception +}; + + +struct trace_element{ + trace_element *prev, *next; + char type; + union { + struct { + dword_t errcode; /* to decide if kernel or user pf */ + dword_t tid; + dword_t fault_addr; + dword_t ip; + dword_t pager; + dword_t pg_table; + dword_t time; + dword_t pmc0; + dword_t pmc1; + dword_t cpu_id; + } pf; + + struct { + dword_t sender; + dword_t receiver; + dword_t snd_desc; + dword_t rcv_desc; + dword_t msg_w0; + dword_t msg_w1; + dword_t msg_w2; + dword_t ip; + dword_t timeout; + dword_t time; + dword_t pmc0; + dword_t pmc1; + } ipc; + + struct { + dword_t vector_no; + dword_t fault_addr; + dword_t errcode; + dword_t time; + dword_t cpu_id; + dword_t pmc0; + dword_t pmc1; + } exception; + + dword_t raw[12]; + };//57 Bytes +}trace_buffer[TRACE_SIZE]; /* 57 bytes per element, 10 pages used, 718 elementes */ + +static trace_element* current_trace_pos; +static trace_element* start_trace_pos; + + +//the number of lines on screen (needed for dump mem? /trace ...) +int num_lines; + +ptr_t original_int_14; //the original address of the interrupthandler for int 14 + +ptr_t original_int_48; //the original address of the interrupthandler for int 48 + + +//used for exception monitoring +struct { + unsigned int_used:1; +} int_list[IDT_SIZE]; + +extern "C" struct { + dword_t tid; + char name[9]; +} name_tab[32]; + + +dword_t* original_interrupt[IDT_SIZE]; + + +void init_tracing() { + num_lines = 18; + + + original_int_14 = 0; + original_int_48 = 0; + for (int i=0; ir.restr[i]) printf("%s\n", get_name(list->r.restr[i], tmp)); + + if (list->r.restr_intervall.begin || list->r.restr_intervall.end) + printf("[%s,%s]\n", get_name(list->r.restr_intervall.begin, tmp), + get_name(list->r.restr_intervall.end, tmp)); + } + else { //all threads except the ones in the list are restricted + printf("all except: \n"); + for (int i=0; irestr_except[i]) printf("%s\n", get_name(list->restr_except[i], tmp)); + } +} + + +void del_restr(char type) { + union restriction* list; + int mode = 0; + list = NULL; + + switch (type) { + case K_KERNEL_IPC_TRACE: + list = &restricted_ipc; + mode = trace_controlling.ipc.restr; + break; + + case K_MEM_PF_TRACE: + list = &restricted_pf; + mode = trace_controlling.pf.restr; + + break; + case K_KERNEL_EXCPTN_TRACE: + list = &restricted_exceptions; + mode = trace_controlling.exception.restr; + } + + for (int i=0; ir.restr[i] = 0; + list->restr_except[i] = 0; + } + + list->r.restr_intervall.begin = 0; + list->r.restr_intervall.end = 0; +} + +void trace(char type, dword_t args[12]) { + current_trace_pos->type = type; + for (int i=0; i<11; i++) { + current_trace_pos->raw[i] = args[i]; + } + + current_trace_pos = current_trace_pos->next; + + if (current_trace_pos == start_trace_pos) { + start_trace_pos = start_trace_pos->next; + } + //current and start are the same after an overflow! + //the oldest entry is "deleted" in this case. +} + + +static void dump_trace_element(trace_element *tmp) { + + switch (tmp->type) { + case 'e': + printf("exception %x @ %x errcode %x cpu %d time %d pmc0 %x pmc1 %x\n", + tmp->exception.vector_no, tmp->exception.errcode, tmp->exception.errcode, + tmp->exception.cpu_id, tmp->exception.time, tmp->exception.pmc0, + tmp->exception.pmc1); + break; + + case 'i': + printf("ipc: %x->%x snd_desc %x rcv_desc %x (%x,%x,%x)" + "ip %x timeouts %x time %d pmc0 %x pmc1 %x\n", + tmp->ipc.sender, tmp->ipc.receiver, tmp->ipc.snd_desc, tmp->ipc.rcv_desc, + tmp->ipc.msg_w0, tmp->ipc.msg_w1, tmp->ipc.msg_w2, tmp->ipc.ip, + tmp->ipc.timeout, tmp->ipc.time, tmp->ipc.pmc0, tmp->ipc.pmc1); + break; + + case 'p': + printf("%s: thread %s @ %s ip %x pager %x errcode %s cr3 %x" + "cpu %d time %d pmc0 %x pmc1 %x\n", + pf_usermode(tmp->pf.errcode) ? "UPF" : "KPF" , tmp->pf.tid, + tmp->pf.fault_addr, tmp->pf.ip, tmp->pf.pager, tmp->pf.errcode, + tmp->pf.pg_table, tmp->pf.cpu_id, tmp->pf.time, tmp->pf.pmc0, + tmp->pf.pmc1); + break; + } +} + +// the index is the point, from which the next num_lines entries are shown +void kdebug_dump_trace() { + + printf("Dump Trace: [Exception/Ipc/Pf]\n");///All] "); + char type; + type = getc(); + + trace_element *tmp; + +#if defined(CONFIG_DEBUGGER_IO_OUTSCRN) + + // the last element in the buffer + tmp = current_trace_pos->prev; + + while (itype == type) { + i++; + } + tmp = tmp->prev; + } + +//navigation in the buffer is still mising. (Next/Prev) + for (int i=0; itype == type) { + if ( is_restricted(tmp->raw[0], tmp->raw[3], tmp->type)) { + dump_trace_element(tmp); + } + tmp = tmp->next; + } + } + +#else /* CONFIG_DEBUGGER_OUT_IO_OUTCOM */ + + tmp = start_trace_pos; + + if (tmp->type != 'u') { + // there is somthing in the buffer + do { + if (tmp->type == type) { + if ( is_restricted(tmp->raw[0], tmp->raw[3], tmp->type)) { + dump_trace_element(tmp); + } + } + tmp = tmp->next; + } while (tmp != current_trace_pos); + } + else { + printf("The buffer is empty.\n"); + } +#endif +} + + +/** + * tests, if a thread is restricted or not + **/ +int is_restricted(dword_t tid, dword_t errcode, char type) { + + union restriction* list; + int restr = 0; + dword_t search = 0;//to decide if a thread or an errorcode is restricted + dword_t no_send = 0;//only for ipc tracing: has this ipc a send part? + no_send = 0;//if not ipc tracing send is always set, so that + list = NULL; + + switch (type) { + case K_KERNEL_IPC_TRACE: + list = &restricted_ipc; + restr = trace_controlling.ipc.restr; + search = tid; + if (trace_controlling.ipc.only_sendpart == YES)//trace ipc is restrictet to ipcs with send part + no_send = (errcode == 0xffffffff) ? 1 : 0; + break; + case K_MEM_PF_TRACE: + list = &restricted_pf; + restr = trace_controlling.pf.restr; + search = tid; + break; + case K_KERNEL_EXCPTN_TRACE: + list = &restricted_exceptions; + restr = trace_controlling.exception.restr; + if (!trace_controlling.exception.with_errcode) { + search = tid; + } + else { + search = errcode; + } + break; + } + + if (restr == THREADS_IN_LIST) { //the treads in the list are restricted + for (int i=0; ir.restr[i] || no_send) //the thread is restricted + //send checks if there is a send part in the ipc. if pf or exception + //send is always clear, so nothing happens to it + return 1; + } + //begin = end is not permitted + if (list->r.restr_intervall.begin < list->r.restr_intervall.end) + //the thread no. within the intervall are restricted + if ((search >= list->r.restr_intervall.begin + || search <= list->r.restr_intervall.end) + && (list->r.restr_intervall.begin != list->r.restr_intervall.end + || no_send)) + //the last part checks if something is in the array or not + return 1; + else {//the thread no. outside the intervall are restricted + if ((search <= list->r.restr_intervall.begin + || search >= list->r.restr_intervall.end) + && (list->r.restr_intervall.begin != list->r.restr_intervall.end + || no_send)) + //the last part checks if something is in the array or not + return 1; + } + //the tid is not in the list + return 0; + } + else { //all threads except the ones in the list are restricted + for (int i=0; irestr_except[i] || no_send) return 0; + else return 1; + } + return 0; //is never reached +} + +/** + * decides what to do and makes the neccesarry changes in the idt + * be carefull what you are doing with the idt! + **/ +void kdebug_pagefault_tracing() { + char c; + + printf("pagefault tracing: "); + + int i = 0; + c = getc(); + switch (c) { + case '+': + putc(c); + putc('\n'); + if (! trace_controlling.pf.use) { + original_int_14 = change_idt_entry(14, (ptr_t)(*trace_pf)); + trace_controlling.pf.use = YES; + } + trace_controlling.pf.to_do = DISPLAY; + break; + + case '*': + putc(c); + putc('\n'); + if (! trace_controlling.pf.use) { + original_int_14 = change_idt_entry(14, (ptr_t)(*trace_pf)); + trace_controlling.pf.use = YES; + } + trace_controlling.pf.to_do = TRACING; + break; + + case '-': + putc(c); + putc('\n'); + ptr_t dummy; + if (trace_controlling.pf.use) { + dummy = change_idt_entry(14, original_int_14); + trace_controlling.pf.use = NO; + } + break; + + case K_RESTRICT_TRACE: + printf("restirct: t/T/x/- : "); + c = getc(); + + switch (c) { + case 't'://threads in list + printf("thread: "); + if (trace_controlling.pf.restr == ALL_OTHER_THREADS) { + del_restr(K_MEM_PF_TRACE);//for pf + trace_controlling.pf.restr = THREADS_IN_LIST; + } + i = 0; + while (restricted_pf.r.restr[i] && i +#include +#include "kdebug.h" + +#ifdef CONFIG_TRACEBUFFER +tracebuffer_t *tracebuffer; +#endif + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +static dword_t pmc_overflow_interrupt_mask = 0; +extern "C" void apic_pmc_of_int(); +#endif + +#define any_to_virt(x) ((x) < KERNEL_OFFSET ? ((x)+KERNEL_OFFSET) : (x)) + +/* x86-only prototypes */ +void kdebug_init_serial(void) L4_SECT_KDEBUG; +void kdebug_setperfctr(dword_t sel, dword_t value) L4_SECT_KDEBUG; + + +void kdebug_init_arch() +{ +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) + kdebug_init_serial(); +#endif +} + + +void kdebug_hwreset() +{ + __asm__ __volatile__ ( + " movb $0xFE, %al \n" + " outb %al, $0x64 \n" + ); +} + +void kdebug_single_stepping(exception_frame_t *frame, dword_t onoff) +{ + frame->eflags &= ~(1 << 8); + frame->eflags |= (onoff << 8); +} + + + + +#if defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB) + +enum kdebug_steping_t { + STEPPING_NONE, + STEPPING_INSTR, + STEPPING_BLOCK +} kdebug_stepping = STEPPING_NONE; + + +void dump_count() +{ +#define MAX_DUMP_COUNT 10 + static int count = 0; + count++; + if (count == MAX_DUMP_COUNT) + { + getc(); + count = 0; + } +} + +void kdebug_dump_pgtable(ptr_t pgtable) +{ + int d_beg = 0, d_end = 0; + char c; + + if ((dword_t) pgtable < TCB_AREA) + /* seems to be a physical address */ + pgtable = phys_to_virt(pgtable); + + c = kdebug_get_choice("Dump pagetable", "All/User/Kernel/Tcbs" +#if defined(CONFIG_ENABLE_SMALL_AS) + "/Small spaces" +#endif + , 'a'); + + switch (c) + { + case 'a': d_beg = 0; d_end = 1024; break; + case 'u': + d_beg = 0; + d_end = (USER_AREA_MAX >> PAGEDIR_BITS); + break; + case 'k': + d_beg = (KERNEL_VIRT >> PAGEDIR_BITS); + d_end = 1024; + break; + case 't': + d_beg = (TCB_AREA >> PAGEDIR_BITS); + d_end = ((TCB_AREA + TCB_AREA_SIZE) >> PAGEDIR_BITS); + break; +#if defined(CONFIG_ENABLE_SMALL_AS) + case 's': + d_beg = (SMALL_SPACE_START >> PAGEDIR_BITS); + d_end = (TCB_AREA >> PAGEDIR_BITS); + break; +#endif + } + + + for (int i = d_beg; i < d_end; i++) + { + if (pgtable[i]) { + if (0) {} +#if defined(CONFIG_ENABLE_SMALL_AS) + else if ( i == SPACE_ID_IDX ) + { + space_t * space = (space_t *) virt_to_phys (pgtable); + if (!space->is_small ()) + printf("%x -> small_space=%x [INVALID]\n", + 0x400000 * i, pgtable[i]); + else + printf("%x -> small_space = %x [size=%dMB num=%d]\n", + 0x400000 * i, pgtable[i], + (space->smallid ().bytesize ()) / (1024*1024), + space->smallid ().num ()); + } + else if ( i >= (int) GDT_ENTRY1_IDX && i <= (int) GDT_ENTRY2_IDX ) + { + printf("%x -> GDT Entry %d = %x\n", + 0x400000 * i, i - GDT_ENTRY1_IDX, pgtable[i]); + } +#endif + else if ( (pgtable[i] & PAGE_SUPER) && (pgtable[i] & PAGE_SUPER) ) + { + printf("%x -> %x (4MB) addr=%x [%c%c%c%c%c%c]\n", + 0x400000 * i, pgtable[i], + pgtable[i] & PAGEDIR_MASK, + pgtable[i] & PAGE_WRITABLE ? 'w' : 'r', + pgtable[i] & PAGE_USER ? 'u' : 'k', + pgtable[i] & PAGE_ACCESSED ? 'a' : '.', + pgtable[i] & PAGE_DIRTY ? 'd' : '.', + pgtable[i] & PAGE_GLOBAL ? 'g' : '.', + pgtable[i] & PAGE_CACHE_DISABLE ? '.' : 'c'); + //dump_count(); + } + else { + printf("%x -> %x (PT) addr=%x\n", 0x400000 * i, pgtable[i], + pgtable[i] & PAGE_MASK); + dword_t * ptab = phys_to_virt(ptr_t(pgtable[i] & PAGE_MASK)); + for (int j = 0; j < 1024; j++) { + if (ptab[j] & PAGE_VALID) { + printf("%x -> %x (4K) addr=%x [%c%c%c%c%c%c]\n", + (0x400000 * i + 0x1000 * j), ptab[j], + ptab[j] & PAGE_MASK, + ptab[j] & PAGE_WRITABLE ? 'w' : 'r', + ptab[j] & PAGE_USER ? 'u' : 'k', + ptab[j] & PAGE_ACCESSED ? 'a' : '.', + ptab[j] & PAGE_DIRTY ? 'd' : '.', + ptab[j] & PAGE_GLOBAL ? 'g' : '.', + ptab[j] & PAGE_CACHE_DISABLE ? '.' : 'c'); + //dump_count(); + } + } + } + } + } +} + +void dump_eflags(const dword_t eflags) +{ + printf("%c%c%c%c%c%c%c%c%c%c%c", + eflags & (1 << 0) ? 'C' : 'c', + eflags & (1 << 2) ? 'P' : 'p', + eflags & (1 << 4) ? 'A' : 'a', + eflags & (1 << 6) ? 'Z' : 'z', + eflags & (1 << 7) ? 'S' : 's', + eflags & (1 << 11) ? 'O' : 'o', + eflags & (1 << 10) ? 'D' : 'd', + eflags & (1 << 9) ? 'I' : 'i', + eflags & (1 << 8) ? 'T' : 't', + eflags & (1 << 16) ? 'R' : 'r', + ((eflags >> 12) & 3) + '0' + ); +} + +void kdebug_dump_frame(exception_frame_t *frame) +{ +#if !defined(CONFIG_SMP) + printf("exception %d (current: %p, cr3: %p)\n", frame->fault_code, + frame, get_current_pagetable()); +#else + printf("exception %d (current: %p, cr3: %p, cpu: %d, apic: %d)\n", + frame->fault_code, frame, get_current_pagetable(), get_cpu_id(), + get_apic_cpu_id()); +#endif + printf("fault addr: %x\tstack: %x\terror code %x\n", + frame->fault_address, frame->user_stack, frame->error_code); + + printf("eax: %x\tebx: %x\n", frame->eax, frame->ebx); + printf("ecx: %x\tedx: %x\n", frame->ecx, frame->edx); + printf("esi: %x\tedi: %x\n", frame->esi, frame->edi); + printf("ebp: %x\tefl: %x [", frame->ebp, frame->eflags); + dump_eflags(frame->eflags);printf("]\n"); +#if defined(CONFIG_ENABLE_SMALL_AS) + printf("cs: %x\tss: %x\n", (word_t) frame->cs, (word_t) frame->ss); + printf("ds: %x\tes: %x\n", (word_t) frame->ds, (word_t) frame->es); +#endif +} + +void kdebug_dump_frame_short(exception_frame_t *frame) +{ + printf("eip=%p ", frame->fault_address); +#if defined(CONFIG_DEBUG_DISAS) + extern int x86_disas(dword_t pc); + x86_disas(frame->fault_address); +#endif + printf("\n" + " " + "eax=%p ebx=%p ecx=%p edx=%p ebp=%p\n" + " " + "esi=%p edi=%p esp=%p efl=%p [", + frame->eax, frame->ebx, frame->ecx, frame->edx, frame->ebp, + frame->esi, frame->edi,frame->user_stack, frame->eflags); + dump_eflags(frame->eflags);printf("]\n"); +} + +#if !defined(CONFIG_DEBUGGER_NEW_KDB) /* not necessary in the new debugger */ +void kdebug_pf_tracing(int state) +{ + extern int __kdebug_pf_tracing; + __kdebug_pf_tracing = state; +} +#endif + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +static qword_t saved_time; +static int cache_enabled = 0; + +void use_cache() +{ + (cache_enabled ^= 1) ? printf("cache enabled\n") : printf("cache disabled\n"); +} + +dword_t get_user_time() { + return ((dword_t*)saved_time)[1]; +} + +dword_t* change_idt_entry(int interrupt_no, ptr_t new_handler) { + + extern idt_desc_t idt[]; + dword_t original_handler_address; + + //idt = read_idt_register(); + + if ((interrupt_no < IDT_SIZE) && (interrupt_no >= 0) ) { + + //storing the old value of the IDT entry + original_handler_address = + idt[interrupt_no].x.d.offset_high <<16 | + idt[interrupt_no].x.d.offset_low; + + //here i register the new handler + idt[interrupt_no].x.d.offset_high = ((dword_t) (new_handler) >> 16); + idt[interrupt_no].x.d.offset_low = ((dword_t) (new_handler)); + + printf("the address of the new handler is: %x\n", new_handler); + printf("the address of the old handler is: %x\n", original_handler_address); + } + else { + printf("interrupt no. out of range!\n"); + original_handler_address = 0; //error! + } + return (ptr_t) original_handler_address; +} + +dword_t* change_sysenter_eip_msr(ptr_t new_handler){ + ptr_t original_sysenter_eip_msr = (ptr_t) rdmsr(0x176); + wrmsr(0x176, (qword_t)new_handler); + return original_sysenter_eip_msr; +} + +//#if defined(...) x686 +static dword_t *original_pmc_of_int = 0; + +void enable_pmc_of_int() { + /* set the mask for enable interrupt + it is enabled for both counters till it is disabled. */ + pmc_overflow_interrupt_mask = (1<<20); + + //the counters which should generate the interrupts must be reseted. + kdebug_perfmon(); + + //enter the new handler to the idt + original_pmc_of_int = change_idt_entry(APIC_PERFCTR_INT_VECTOR, (ptr_t)(*apic_pmc_of_int)); +} + +void disable_pmc_of_int() { + //clear the mask to disable interrupt + pmc_overflow_interrupt_mask = 0; + +// clear bit 20 in the eventselect registers (disable the interrupt). the event dosn't change. + qword_t dummy; + + dummy = rdmsr(390); + dummy = dummy & (1 << 20); + wrmsr(390, dummy); + + //bring the old handler back. + change_idt_entry(APIC_PERFCTR_INT_VECTOR, original_pmc_of_int); +} + + +/** + * test if the pagefault was generated in usermode + * last change: 01.18.2001 + **/ + +int pf_usermode(dword_t errcode) { + +#define PF_USERMODE(x) (x & PAGE_USER) +#define PAGE_USER (1<<2) + + return( PF_USERMODE(errcode) ); +} + +dword_t get_pf_address() { + register dword_t tmp; + + asm ("movl %%cr2, %0\n" + :"=r" (tmp)); + + return tmp; +} + +#endif /*new debugger*/ + +int kdebug_arch_entry(exception_frame_t * frame) +{ +#if defined (CONFIG_DEBUGGER_NEW_KDB) +/* save the time */ + saved_time = rdtsc(); + +# if defined(CONFIG_ARCH_X86_I686) +//only on Intel 686 +/* disable the performancecounters while in debugger */ + qword_t dummy; + + dummy = rdmsr(0x186); + dummy = dummy & (1 << 22); + wrmsr(0x186, dummy); +# endif /* config_arch_x86_i686 */ + + if(cache_enabled) + { +/* disable cache while in debugger */ + asm volatile( + "mov %%cr0, %%eax\n" /* copy CR0 into eax */ + "orl $((1<<30)|(1<<29)), %%eax\n" /* set bits CD and NW */ + "mov %%eax, %%cr0\n" /* write back in CR0 */ + : /* no outputs */ + : /* no inputs */ + : "eax" + ); + } +#endif /*new debugger*/ + /* + * The return value of this function determines whether + * the interactive kernel debugger is invoked or not. + * Returning 0 invokes the KDB. + */ + + if (frame->fault_code == 3) + { + /* breakpoint exception - KDB interface + * + * The KDB interface is based on the int3 instruction. The + * int3-handler checks the instructions that caused the + * exception to decode the requested operation. + * + * The following code sequences are known so far: + * + * --- enter_kdebug --- print text thru KDIO and enter KDB + * + * int3 + * jmp 1f + * .ascii "some text" + * 1: + * + * If "some text" starts with *, the text is written to + * KDB's trace and the interactive KDB is not invoked. + * + * + * --- kd_display --- print text thru KDIO + * int3 + * nop + * jmp 1f + * .ascii "some text" + * 1: + * + * + * + * --- other KDB ops --- + * int3 + * cmp x, %al + * + * with x + * 0x00 print character in %al + * 0x01 print pascal string at %eax + * 0x02 print 0-terminated string at %eax + * 0x03 clear page/screen + * 0x04 cursor control ??? + * 0x05 print %eax as 32-bit hex + * 0x06 print %eax as 20-bit hex + * 0x07 print %eax as 16-bit hex + * 0x08 print %eax as 12-bit hex + * 0x09 print %eax as 8-bit hex + * 0x0a print %eax as 4-bit hex + * 0x0b print %eax as decimal + * 0x0c read character into %al (non-blocking) + * 0x0d read character into %al (blocking) + * 0x0e read 32-bit hex into %eax + * 0x0f read 16-bit hex into %eax + * 0x10 read 8-bit hex into %eax + * 0x11 read 4-bit hex into %eax ??? + * 0x1E set EvntSel0 MSR to %eax (proposed) + * 0x1F set EvntSel1 MSR to %eax (proposed) + * + */ + + unsigned char * c = (unsigned char *) frame->fault_address; + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* + * Make sure that we translate user-level addresses into + * something that can be accessed through kernel segments. + */ + tcb_t *current = ptr_to_tcb((ptr_t) frame); + + if ( (dword_t) current >= TCB_AREA && + (dword_t) current < TCB_AREA + TCB_AREA_SIZE ) + { + smallid_t small = current->space->smallid (); + if (small.is_valid () && (dword_t) c < small.bytesize ()) + c += small.offset (); + } +#endif +#if !defined(CONFIG_DEBUGGER_GDB) + /* The fault_address points to the instruction following the int3. + For readability, we let the fault_address instead point to the + int3 instruction itself and restore it in kdebug_arch_exit */ + frame->fault_address--; +#endif + + switch(*c) + { + case 0x3c: + TRACEPOINT(KDB_OPERATION, printf("KDB operation (0x%02x)\n",c[1])); + switch(c[1]) + { + case 0x00: /* outchar */ + putc(frame->eax & 0xff); + return 1; + case 0x01: /* outstring */ + { + /* print a string: , */ + char* p = (char*) any_to_virt(frame->eax); + for (int i = *p++; i--; p++) + putc(*p); + return 1; + } + case 0x02: /* kd_display */ + printf((char*)frame->eax); + return 1; + case 0x05: /* outhex32 */ + printf("%x", frame->eax); + return 1; + case 0x07: /* outhex16 */ + printf("%4x", frame->eax & 0xFFFF); + return 1; + case 0x08: /* outhex8 */ + printf("%3x", frame->eax & 0xFFF); + return 1; + case 0x09: /* outhex8 */ + printf("%2x", frame->eax & 0xFF); + return 1; + case 0x0b: /* outdec */ + printf("%d", frame->eax); + return 1; + case 0x0d: /* inchar */ + frame->eax = getc(); + return 1; + case 0x0e: /* inhex32 */ + frame->eax = kdebug_get_hex(); + return 1; + case 0x0f: /* inhex16 */ + frame->eax &= 0xFFFF0000; + frame->eax |= (kdebug_get_hex() & 0xFFFF); + return 1; + case 0x11: /* inhext */ + frame->eax = kdebug_get_hex(); + return 1; + case 0x1E: /* set EvntSel0 */ + case 0x1F: /* set EvntSel1 */ +#if defined(CONFIG_PERFMON) + kdebug_setperfctr(c[1] & 1, frame->eax); +#endif + return 1; + default: + printf("unknown KDIO call %2x\n", c[1]); + return 0; + } + break; + case 0x90: /* kd_display */ + c++; + if (c[0] == 0xeb) + { + for (int i = 0; i < c[1]; i++) + putc(c[i+2]); + return 1; + } break; + case 0xeb: /* enter_kdebug */ + { + if (c[1] > 0 && c[2] == '*') + /* trace event - not implemented */ + return 1; + + printf("--- "); + for (int i = 0; i < c[1]; i++) + putc(c[i+2]); + printf(" ---\n"); + return 0; + } + } + return 0; + } + + if ( frame->fault_code == 1 ) + { + /* Debug exception */ + switch ( kdebug_stepping ) + { + case STEPPING_BLOCK: + dword_t last_branch_ip; + wrmsr(IA32_DEBUGCTL, 0); +#if defined(CONFIG_ARCH_X86_I686) + last_branch_ip = rdmsr(IA32_LASTBRANCHFROMIP); +#elif defined(CONFIG_ARCH_X86_P4) + last_branch_ip = (rdmsr(IA32_LASTBRANCH_0 + + rdmsr(IA32_LASTBRANCH_TOS)) >> 32); +#endif +#if defined(CONFIG_DEBUG_DISAS) + int x86_disas(dword_t); + printf("eip=%p ", last_branch_ip); + x86_disas(last_branch_ip); + putc('\n'); +#else + printf("eip=%p branch to\n", last_branch_ip); +#endif + /* FALLTHROUGH */ + + case STEPPING_INSTR: + kdebug_dump_frame_short(frame); + kdebug_stepping = STEPPING_NONE; + kdebug_single_stepping(frame, 0); + return 0; + + default: + { + dword_t *dr3; + asm ("mov %%dr3, %0" :"=r"(dr3)); + if (dr3 != 0) + { + if ((*dr3 & 0xff) != 0) { + frame->eflags |= (1 << 16); + return 1; + } + } + } + frame->eflags |= (1 << 16); + kdebug_dump_frame(frame); + return 0; + } + } + + if ( frame->fault_code == 2 ) + { + /* NMI */ + printf("\nNMI\n"); + kdebug_dump_frame(frame); + return 0; + } + + return 0; +} + +void kdebug_arch_exit(exception_frame_t * frame) +{ +#if defined(CONFIG_DEBUGGER_NEW_KDB) +/* reset the clock */ + + wrmsr(0x10, saved_time); + +# if defined(CONFIG_ARCH_X86_I686) +//only on Intel 686 +//#if defined CONFIG_PERFMON || defined CONFIG_ENABLE_PROFILING + qword_t dummy; + dummy = rdmsr(0x186); + dummy = dummy | (1 << 22); + wrmsr(0x186, dummy); +# endif + + if(cache_enabled) + { +/* enable cache after debugging */ + asm volatile( + "mov %%cr0, %%eax\n" /* copy CR0 into eax */ + "xor $((1<<30)|(1<<29)), %%eax\n" /* clear bits CD and NW */ + "mov %%eax, %%cr0\n" /* write back in CR0 */ + : /* no outputs */ + : /* no inputs */ + : "eax" + ); + } +#endif /*new debugger*/ + if (frame->fault_code == 2) /* NMI */ + { + /* re-enable nmi */ + outb(0x61, inb(0x61) | (0xC)); + for (volatile int i = 10000000; i--; ); + /* re-enable nmi */ + outb(0x61, inb(0x61) & ~(0xC)); + + in_rtc(0x8f); + in_rtc(0x0f); + }; +#if !defined(CONFIG_DEBUGGER_GDB) + if (frame->fault_code == 3) + { + /* now readjust the fault_adress we faked in + kdebug_arch_entry to point to the int3 itself */ + frame->fault_address++; + }; +#endif +}; + +#if defined(CONFIG_PERFMON) || defined(CONFIG_DEBUGGER_NEW_KDB) +// this is needed for the new debugger +void kdebug_setperfctr(dword_t sel, dword_t value) +{ + /* validate counter number */ + switch (sel) + { + case 0: break; + case 1: break; + default: return; + }; + + /* set the EvntSelX and clear the associated PerfCtrX */ + __asm__ __volatile__ ( + "/* write EvntSel */\n" + "lea 0x186(%1),%%ecx\n" + "sub %%edx,%%edx\n" + "wrmsr\n" + "/* clear the counter */\n" + "lea 0xc1(%1),%%ecx\n" + "sub %%edx,%%edx\n" + "sub %%eax,%%eax\n" + "wrmsr\n" + : "+a"(value) : "r"(sel) :"ecx", "edx"); +} +#endif + +void kdebug_perfmon() +{ +#if defined(CONFIG_PERFMON) +# if defined(CONFIG_ARCH_X86_I686) + switch(kdebug_get_choice("What", "Set/Print/Clear" +#if defined(CONFIG_DEBUGGER_NEW_KDB) + "/Write/Interrupt enabled/interrupt Disabled\n" +#endif + , 'p')) + { + case 's': + { + dword_t num; + dword_t val; + char c; + + printf("num(0,1) "); + do { + c = getc(); + if ((c == '0') || (c == '1')) + break; + } while (1); + putc(c); + num = c - '0'; + + printf(" (u,k,a) "); + val = 0; + do { + c = getc(); + switch (c) + { + case 'u': val = 0x10000; break; + case 'k': val = 0x20000; break; + case 'a': val = 0x30000; break; + } + } while (!val); + printf("%c ", c); + + /* read event number to count */ + val |= kdebug_get_perfctr("event", 0xff); + + /* enable counter */ + val |= (1 << 22); +#if defined(CONFIG_DEBUGGER_NEW_KDB) +// to enable the pmc overflow interrupt + val |= pmc_overflow_interrupt_mask; +#endif + kdebug_setperfctr(num, val); + } break; + + case 'p': + printf("rdpmc: 0=%x, 1=%x\n", rdpmc(0), rdpmc(1)); + break; + + case 'c': + __asm__ ( + "/* clear the counter */\n" + "mov $0xc1,%%ecx\n" + "sub %%edx,%%edx\n" + "sub %%eax,%%eax\n" + "wrmsr \n" + "mov $0xc2,%%ecx\n" + "wrmsr \n" + : + : + : "eax", "ecx", "edx"); + break; + } +#if defined (CONFIG_DEBUGGER_NEW_KDB) + case 'w': /* write the counter */ + + //select counter + printf("set counter: num(0,1) "); + do { + c = getc(); + if ((c == '0') || (c =='1')) { + break; + } + } while (1); + putc(c); + + //get the value + dword_t value_low; + printf(" low order 32 bits [0]: "); + value_low = kdebug_get_hex(0x0, "0"); + + //set the counter + int counter_address; + counter_address = PERFCTR0 + c - '0'; + wrmsr(counter_address, (qword_t) value_low); + + putc('\n'); + break; + + case 'i': + printf("pmc overflow interrupt enabled. you have to reset the counter(s)\n"); + enable_pmc_of_int(); + break; + case 'd': + printf("pmc overflow interrupt disabled\n"); + disable_pmc_of_int(); + break; + + } +#endif /*new debugger*/ + +# elif defined(CONFIG_ARCH_X86_P4) + dword_t ctr; + + switch ( kdebug_get_choice("Performance counter", + "Enable/Disable/Clear/clear All/View", 'v') ) + { + case 'e': + { + qword_t escr, cccr; + dword_t escrmsr; + + ctr = kdebug_get_perfctr(&escrmsr, &escr, &cccr); + if ( ctr != ~0UL ) + { + wrmsr(escrmsr, escr); + wrmsr(IA32_CCCR_BASE + ctr, cccr); + wrmsr(IA32_COUNTER_BASE + ctr, 0); + } + break; + } + + case 'd': + printf("Counter (0-17): "); + ctr = kdebug_get_dec(99, ""); + if ( ctr >= 0 && ctr <= 17 ) + { + wrmsr(IA32_CCCR_BASE + ctr, 0); + wrmsr(IA32_COUNTER_BASE + ctr, 0); + } + break; + + case 'c': + printf("Counter (0-17): "); + ctr = kdebug_get_dec(99, ""); + if ( ctr >= 0 && ctr <= 17 ) + wrmsr(IA32_COUNTER_BASE + ctr, 0); + break; + + case 'a': + for ( int i = 0; i < 18; i++ ) + wrmsr(IA32_COUNTER_BASE + i, 0); + break; + + case 'v': + for ( int i = 0; i < 18; i++ ) + { + qword_t count = rdmsr(IA32_COUNTER_BASE + i); + printf("%2d: %02x%08x ", i, + (dword_t) ((count >> 32) & 0xff), (dword_t) count); + kdebug_describe_perfctr(i); + putc('\n'); + } + break; + } + + +# endif /* CONFIG_ARCH_X86_P4 */ +#endif /* CONFIG_PERFMON */ +} + +void kdebug_breakpoint() +{ + printf("breakpoint [-/?/0..3]: "); + + /* the breakpoint register to be used */ + dword_t db7; + /* breakpoint address */ + dword_t addr = 0; + + int num = getc();putc(num); + switch (num) { + /* set debug register 0..3 manually */ + case '0'...'3': + num -= '0'; + break; + /* reset all debug registers */ + case '-': + __asm__ __volatile__ ("mov %%db7,%0": "=r" (db7)); + db7 &= ~(0x00000FF); + __asm__ __volatile__ ("mov %0, %%db7": :"r" (db7)); + return;break; + + /* any key dumps debug registers */ + case '?': + default: + __asm__ ("mov %%db7,%0": "=r"(db7)); + printf("\nDR7: %x\n", db7); + __asm__ ("mov %%db6,%0": "=r"(db7)); + printf("DR6: %x\n", db7); addr=db7; + __asm__ ("mov %%db3,%0": "=r"(db7)); + printf("DR3: %x %c\n", db7, addr & 8 ? '*' : ' '); + __asm__ ("mov %%db2,%0": "=r"(db7)); + printf("DR2: %x %c\n", db7, addr & 4 ? '*' : ' '); + __asm__ ("mov %%db1,%0": "=r"(db7)); + printf("DR1: %x %c\n", db7, addr & 2 ? '*' : ' '); + __asm__ ("mov %%db0,%0": "=r"(db7)); + printf("DR0: %x %c\n", db7, addr & 1 ? '*' : ' '); + return; + } + /* read debug control register */ + __asm__ __volatile__ ("mov %%db7,%0" : "=r" (db7)); + + + printf(" [Instr/Access/pOrt/Write/-/+] :"); + /* breakpoint type */ + char t; + while (42) + { + t = getc(); + if ((t=='i') || (t=='a') || (t=='o') || + (t=='w') || (t=='-') || (t=='+')) + break; + } + + putc(t); + switch (t) + { + case '-': + db7 &= ~(2 << (num * 2)); /* disable */ + num = -1; + break; + case '+': + db7 |= (2 << (num * 2)); /* enable */ + num = -1; + break; + case 'i': /* instruction execution */ + addr = kdebug_get_hex(); + db7 &= ~(0x000F0000 << (num * 4)); + db7 |= (0x00000000 << (num * 4)); + db7 |= (2 << (num * 2)); /* enable */ + break; + case 'w': /* data write */ + addr = kdebug_get_hex(); + db7 &= ~(0x000F0000 << (num * 4)); + db7 |= (0x00010000 << (num * 4)); + db7 |= (2 << (num * 2)); /* enable */ + break; + case 'o': /* I/O */ + addr = kdebug_get_hex(); + db7 &= ~(0x000F0000 << (num * 4)); + db7 |= (0x00020000 << (num * 4)); + db7 |= (2 << (num * 2)); /* enable */ + break; + case 'a': /* read/write */ + addr = kdebug_get_hex(); + db7 &= ~(0x000F0000 << (num * 4)); + db7 |= (0x00030000 << (num * 4)); + db7 |= (2 << (num * 2)); /* enable */ + break; + }; + if (num==0) __asm__ __volatile__ ("mov %0, %%db0" : : "r" (addr)); + if (num==1) __asm__ __volatile__ ("mov %0, %%db1" : : "r" (addr)); + if (num==2) __asm__ __volatile__ ("mov %0, %%db2" : : "r" (addr)); + if (num==3) __asm__ __volatile__ ("mov %0, %%db3" : : "r" (addr)); + __asm__ __volatile__ ("mov %0, %%db7" : : "r" (db7)); + +} + +void kdebug_arch_help() +{ + printf( + "c profile C dump profile\n" + "T single stepping\n" + "e perfmon\n" + "b breakpoint\n" + " b? list\n" + " b- disable all\n" + " b#i instruction\n" + " b#w write\n" + " b#o I/O\n" + " b#a access\n" + " b#- disable this dr\n" + ); +} + +INLINE void cpuid(dword_t index, + dword_t* eax, dword_t* ebx, dword_t* ecx, dword_t* edx) +{ + __asm__ ( + "cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "a" (index) + ); +} + +#if defined(CONFIG_X86_IOAPIC) +#include INC_ARCH(apic.h) +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) +void kdebug_small_spaces(tcb_t *current) +{ + switch ( kdebug_get_choice("\nSmall spaces", + "View/make Small/make Large", 'v') ) + { + case 's': + { + dword_t size, s, idx; + tcb_t * tcb = kdebug_get_task(current); + tcb = kdebug_find_task_tcb(tasknum(tcb), current); + if ( tcb == NULL ) + break; + + printf("Size (MB) [64]: "); + size = kdebug_get_dec(64) / SMALL_SPACE_MIN; + printf("Index [0]: "); + idx = kdebug_get_dec(0); + for ( s = 0; ((1 << s) & size) == 0; s++ ) ; + if ( size ) + make_small_space (tcb->space, ((idx << 1) | 1) << s); + break; + } + + case 'l': + { + tcb_t * tcb = kdebug_get_task(current); + tcb = kdebug_find_task_tcb(tasknum(tcb), current); + if (tcb && tcb->space->is_small ()) + small_space_to_large (tcb->space); + break; + } + + case 'v': + { + extern space_t *small_space_owner[]; + space_t *owner; + dword_t i, k, n; + tcb_t *tcb; + + putc('\n'); + for ( i = 0; i < MAX_SMALL_SPACES; i++ ) + { + if ( small_space_owner[i] == NULL ) + continue; + + owner = small_space_owner[i]; + for ( n = 0; i+n < MAX_SMALL_SPACES; n++ ) + if ( small_space_owner[i+n] != owner ) + break; + + for ( tcb = get_idle_tcb()->present_next; + tcb->space != owner && tcb != get_idle_tcb(); + tcb = tcb->present_next ) + ; + + k = printf("%3d-%d", i, i+n-1); + for ( k = 9-k; k--; ) putc(' '); + printf("<%p,%p> size=%3dMB space=%p task=", + SMALL_SPACE_START + (i << SMALL_SPACE_SHIFT), + SMALL_SPACE_START + ((i+n) << SMALL_SPACE_SHIFT), + n * SMALL_SPACE_MIN, owner); + printf(tcb->space == owner ? "%2x\n" : "?\n", + tcb->myself.x0id.task); + + i += n-1; + } + break; + } + } +} +#endif /* CONFIG_SMALL_SPACES */ + +static void kdebug_msrs() +{ + + dword_t msr; + qword_t val; + + switch ( kdebug_get_choice("\nModel Specific Registers", + "Show/Read/Write", 's') ) + { + case 'r': + printf("msr="); + msr = kdebug_get_hex(); + val = rdmsr(msr); + printf("rdmsr(%x)=%x\n", msr, val); + break; + + case 'w': + printf("msr="); + msr = kdebug_get_hex(); + printf("val="); + val = kdebug_get_hex(); + wrmsr(msr, val); + break; + + default: + printf("SYSENTER_CS_MSR: %x\n", rdmsr(IA32_SYSENTER_CS_MSR)); + printf("SYSENTER_EIP_MSR: %x\n", rdmsr(IA32_SYSENTER_EIP_MSR)); + printf("SYSENTER_ESP_MSR: %x\n", rdmsr(IA32_SYSENTER_ESP_MSR)); + +#if defined(CONFIG_ARCH_X86_I686) + printf("LASTBRANCH_FROM_IP: %x\n", rdmsr(IA32_LASTBRANCHFROMIP)); + printf("LASTBRANCH_TO_IP: %x\n", rdmsr(IA32_LASTBRANCHTOIP)); + printf("LASTINT_FROM_IP: %x\n", rdmsr(IA32_LASTINTFROMIP)); + printf("LASTINT_TO_IP: %x\n", rdmsr(IA32_LASTINTTOIP)); +#endif + +#if defined(CONFIG_ARCH_X86_P4) + printf("LER_FROM_IP: %x\n", rdmsr(IA32_LER_FROM_LIP)); + printf("LER_TO_IP: %x\n", rdmsr(IA32_LER_TO_LIP)); + dword_t tos = rdmsr(IA32_LASTBRANCH_TOS); + for ( int i = 0; i < 4; i++ ) + { + qword_t br = rdmsr(IA32_LASTBRANCH_0 + ((i + tos) & 0x03)); + printf("LASTBRANCH_%d: %x -> %x\n", (i + tos) & 0x03, + (dword_t) (br >> 32), (dword_t) br); + } +#endif + break; + }; + +} + + +void kdebug_cpustate(tcb_t *current) +{ + int l; + char c; + dword_t foo; + + printf("\nx86 - "); + l = printf("[Gdt/Crs/Idt/iOapic/Ports/Msr/cpUid" +#if defined(CONFIG_ENABLE_SMALL_AS) + "/Smallspaces" +#endif +#if defined(CONFIG_X86_P4_BTS) + "/Bts" +#endif +#if defined(CONFIG_X86_P4_PEBS) + "/pEbs" +#endif + "]: "); + switch (getc()) + { + case 'c': + + __asm__ ("mov %%cr4,%0": "=r"(foo)); + printf("\nCR4: %x\n", foo); + __asm__ ("mov %%cr3,%0": "=r"(foo)); + printf("CR3: %x\n", foo); + __asm__ ("mov %%cr2,%0": "=r"(foo)); + printf("CR2: %x\n", foo); + __asm__ ("mov %%cr0,%0": "=r"(foo)); + printf("CR0: %x\n", foo); + + break; + + case 'C': + + printf("\nset CR"); + while (1) { c = getc(); if ((c >= '0') && (c <= '4')) break; }; + printf("%d=", c-'0'); + foo = kdebug_get_hex(); + + switch (c) + { + case '0': __asm__ __volatile__ ("mov %0,%%cr0": : "r"(foo)); break; + case '2': __asm__ __volatile__ ("mov %0,%%cr2": : "r"(foo)); break; + case '3': __asm__ __volatile__ ("mov %0,%%cr3": : "r"(foo)); break; + case '4': __asm__ __volatile__ ("mov %0,%%cr4": : "r"(foo)); break; + }; + + break; + + case 'm': + + kdebug_msrs(); + break; + + case 'g': + + extern seg_desc_t gdt[]; + printf("\nGDT-dump: gdt at %x\n", gdt); + for (int i = 0; i < GDT_SIZE; i++) + { + seg_desc_t *ent = gdt+i; + printf("GDT[%d] = %x:%x", i, ent->x.raw[0], ent->x.raw[1]); + if ( (ent->x.raw[0] == 0 && ent->x.raw[1] == 0) || + (! ent->x.d.s) ) + { + printf("\n"); + continue; + } + printf(" <%p,%p> ", + ent->x.d.base_low + (ent->x.d.base_high << 24), + ent->x.d.base_low + (ent->x.d.base_high << 24) + + (ent->x.d.g ? 0xfff | + (ent->x.d.limit_low + (ent->x.d.limit_high << 16)) << 12 : + (ent->x.d.limit_low + (ent->x.d.limit_high << 16)))); + printf("dpl=%d %d-bit ", ent->x.d.dpl, ent->x.d.d ? 32 : 16); + if ( ent->x.d.type & 0x8 ) + printf("code %cC %cR ", + ent->x.d.type & 0x4 ? ' ' : '!', + ent->x.d.type & 0x2 ? ' ' : '!'); + else + printf("data E%c R%c ", + ent->x.d.type & 0x4 ? 'D' : 'U', + ent->x.d.type & 0x2 ? 'W' : 'O'); + printf("%cP %cA\n", + ent->x.d.p ? ' ' : '!', + ent->x.d.type & 0x1 ? ' ' : '!'); + } + break; + + case 'i': + + extern idt_desc_t idt[]; + printf("\nIDT-dump: idt at %x\n", idt); + for (int i = 0; i < (IDT_SIZE) ; i++) + if (idt[i].x.d.p) + printf("%2x -> %4x:%x , dpl=%d, type=%d (%x:%x)\n", i, + idt[i].x.d.sel, + idt[i].x.d.offset_low | (idt[i].x.d.offset_high << 16), + idt[i].x.d.dpl, idt[i].x.d.type, + idt[i].x.raw[0], idt[i].x.raw[1]); + break; + + case 'o': + +#if defined(CONFIG_X86_IOAPIC) + printf("\nIO-APIC redirection table\n"); + for (int i = 0; i < 24; i++) + printf("ioredir(%d): %x, %x\n", i, get_io_apic(0x10 + (i*2)), get_io_apic(0x11 + (i*2))); +#endif + break; + + + case 'p': + +#define B(x) do { for (int __i =0; __i < (x); __i++) { putc(8); putc(' '); putc(8); } } while (0) + + word_t port; + B(l); + l = printf("[In/Out]: "); + c = getc(); + switch(c) + { + case 'i': + + B(l); + printf("in "); port = kdebug_get_hex(); + printf(" -> %2x\n", inb(port)); + + break; + + case 'o': + + B(l); + printf("out "); port = kdebug_get_hex(); + printf(", "); outb(port, kdebug_get_hex()); + + break; + }; + break; + +#if defined(CONFIG_ENABLE_SMALL_AS) + case 's': + kdebug_small_spaces(current); + break; +#endif + +#if defined(CONFIG_X86_P4_BTS) + case 'b': + kdebug_x86_bts(); + break; +#endif + +#if defined(CONFIG_X86_P4_PEBS) + case 'e': + kdebug_x86_pebs(); + break; +#endif + + case 'u': + + /* Reference: + + AP-485 + APPLICATION NOTE + Intel Processor Identification and + the CPUID Instruction + + June 2001 + Order Number: 241618-018 + + http://developer.intel.com/design/pentiumII/applnots/241618.htm + */ + + /* from above document, table 5, pages 14-15 */ + const char* features[] = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", + "cx8", "apic", "?", "sep", "mtrr", "pge", "mca", "cmov", + "pat", "pse-36", "psn", "cflsh", "?", "ds", "acpi", "mmx", + "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "?" }; + /* from above document, table 7, page 17 */ + const char* cachecfg[16][16] = + { + { /* 0x00 */ + "", + "ITLB: 32*4K, 4w", "ITLB: 2*4M", + "DTLB: 64*4K, 4w", "DTLB: 8*4M, 4w", 0, + "ICache: 8K, 4w, 32", 0, "ICache: 16K, 4w, 32", 0, + "DCache: 8K, 2w, 32", 0, "DCache: 16K, 4w, 32" }, + { /* 0x10 */ }, { /* 0x20 */ }, { /* 0x30 */ }, + { /* 0x40 */ + "no L2 or L3", + "Cache: 128K, 4w, 32", "Cache: 256K, 4w, 32", + "Cache: 512K, 4w, 32", "Cache: 1M, 4w, 32", + "Cache: 2M, 4w, 32", + }, + { /* 0x50 */ + "ITLB: 64*{4K,2M/4M}", "ITLB: 128*{4K,2M/4M}", + "ITLB: 256*{4K,2M/4M}", 0, 0, 0, 0, 0, 0, 0, 0, + "DTLB: 64*{4K,4M}", "DTLB: 128*{4K,4M}", + "DTLB: 256*{4K,4M}" + }, + { /* 0x60 */ + 0, 0, 0, 0, 0, 0, + "DCache: 8K, 4w, 64", "DCache: 16K, 4w, 64", + "DCache: 32K, 4w, 64" + }, + { /* 0x70 */ + "TC: 12Kuop, 8w", "TC: 16Kuop, 8w", "TC: 32Kuop, 8w", 0, + 0, 0, 0, 0, 0, + "Cache: 128K, 8w, 64", "Cache: 256K, 8w, 64", + "Cache: 512K, 8w, 64", "Cache: 1M, 8w, 64" + }, + { /* 0x80 */ + 0, 0, + "Cache: 256K, 8w, 32", "Cache: 512K, 8w, 32", + "Cache: 1M, 8w, 32", "Cache: 2M, 8w, 32" + } + + + }; + + dword_t id[4][4]; + dword_t i; + printf("\n"); + for (i = 0; i < 4; i++) + cpuid(i, &id[i][0], &id[i][1], &id[i][2], &id[i][3]); + for (i = 0; i <= id[0][0]; i++) + printf("cpuid(%d):%x:%x:%x:%x\n", i, + id[i][0], id[i][1], id[i][2], id[i][3]); + printf("0: max=%d \"", id[0][0]); + for (i = 0; i < 12; i++) putc(((char*) &id[0][1])[i]); + printf("\"\n1: fam=%d, mod=%d, step=%d\n1: ", + (id[1][0] >> 8) & 0xF, + (id[1][0] >> 4) & 0xF, + (id[1][0] >> 0) & 0xF); + for (i = 0; i < 32; i++) + if ((id[1][3] >> i) & 1) printf("%s ", features[i]); + printf("\n"); + /* 2: eax[7:0] determines, how often 2 must be called - noimp */ + for (i = 1; i < 16; i++) + { + int j = ((char*)id[2])[i]; + if (((id[2][i/4] & 0x80000000) == 0) && (j != 0)) + printf("%s\n", cachecfg[0][j]); + }; + break; + } +} + +int kdebug_step_instruction(exception_frame_t * frame) +{ + kdebug_single_stepping(frame, 1); + kdebug_stepping = STEPPING_INSTR; + frame->eflags |= (1 << 16); + putc('s'); putc('\n'); + return 1; +} + +int kdebug_step_block(exception_frame_t * frame) +{ +#if defined(CONFIG_ARCH_X86_I686) || defined(CONFIG_ARCH_X86_P4) + kdebug_single_stepping(frame, 1); + kdebug_stepping = STEPPING_BLOCK; + frame->eflags |= (1 << 16); + wrmsr(IA32_DEBUGCTL, ((1<<0) + (1<<1))); /* LBR + BTF */ + putc('S'); putc('\n'); + return 1; +#else + /* Single stepping on branches is not supported on older CPUs. */ + printf("S - Unsupported\n"); + return 0; +#endif +} + + +void kdebug_disassemble(exception_frame_t * frame) +{ +#if defined(CONFIG_DEBUG_DISAS) + extern int x86_disas(dword_t pc); + char c; + dword_t pc; + restart: + printf("ip [current]: "); + pc = kdebug_get_hex(frame->fault_address, "current"); + do { + printf("%x: ", pc); + pc += x86_disas(pc); + printf("\n"); + c = getc(); + } while ((c != 'q') && (c != 'u')); + if (c == 'u') + goto restart; +#endif +}; + +#if defined(CONFIG_TRACEBUFFER) +void kdebug_dump_tracebuffer() +{ + dword_t count = tracebuffer->current / sizeof(trace_t); + dword_t index, top = 0, bottom = count, chunk = (count<32) ? count : 32; + tracestatus_t old = { 0,0,0 }, sum = { 0,0,0 }; + trace_t *current; + char c; + + if (tracebuffer->magic != TBUF_MAGIC) + { + printf("Bad tracebuffer signature at %x\n",(dword_t)(&tracebuffer->magic)); + return; + } + + c = kdebug_get_choice("Dump tracebuffer", "All/Region/Top/Bottom", 'b'); + switch (c) + { + case 'a' : break; + case 'r' : printf("From record [0]: "); + top = kdebug_get_dec(); + printf("To record [%d]: ", bottom); + bottom = kdebug_get_dec(bottom); + break; + case 't' : printf("Record count [%d]: ", chunk); + bottom = kdebug_get_dec(chunk); + break; + default : printf("Record count [%d]: ", chunk); + top = bottom - kdebug_get_dec(chunk); + break; + } + + if (bottom > count) + bottom = count; + if (top > bottom) + top = bottom; + + printf("\nRecord Cycles UL Ins Event1 Identifier\n"); + for (index = top; indextrace[index]); + if (!old.cycles) + old = current->status; + + printf("%6d%10d%10d%10d ", index, + (current->status.cycles - old.cycles), + (current->status.pmc0 - old.pmc0), + (current->status.pmc1 - old.pmc1)); + + sum.cycles += (current->status.cycles - old.cycles); + sum.pmc0 += (current->status.pmc0 - old.pmc0); + sum.pmc1 += (current->status.pmc1 - old.pmc1); + old = current->status; + + switch (current->identifier) + { +#define DEFINE_TP(x, str) \ + case TP_##x: \ + printf("*KRNL* "); \ + printf(str, current->data[0], current->data[1], \ + current->data[2], current->data[3]); \ + break; +#include +#undef DEFINE_TP + + /* Entries from user level are displayed as plain text */ + + default: + printf("[%c%c%c%c]", (char)((current->identifier>>24)&0xFF), + (char)((current->identifier>>16)&0xFF), + (char)((current->identifier>>8)&0xFF), + (char)(current->identifier&0xFF)); + + c = (current->identifier>>24)&0xFF; + if ((c>='1') && (c<='4')) + { + int i=0; + printf(", par=(%xh", current->data[i++]); + while ((--c)>='1') + printf(",%xh", current->data[i++]); + putc(')'); + } + break; + } + + putc('\n'); + } + + printf("----------------------------------------------------\n"); + printf(" %10d%10d%10d %6d entries\n", sum.cycles, sum.pmc0, sum.pmc1, bottom-top); +} + +void kdebug_flush_tracebuffer() +{ + printf("Tracebuffer flushed\n"); + tracebuffer->current = 0; +} +#endif /* defined(CONFIG_TRACEBUFFER) */ + +#endif /* defined(CONFIG_DEBUGGER_KDB) */ diff --git a/kernel/kdb/x86.o b/kernel/kdb/x86.o new file mode 100644 index 0000000..06fb7ee Binary files /dev/null and b/kernel/kdb/x86.o differ diff --git a/kernel/kdb/x86_dis.c b/kernel/kdb/x86_dis.c new file mode 100644 index 0000000..5a8c758 --- /dev/null +++ b/kernel/kdb/x86_dis.c @@ -0,0 +1,18 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86_dis.c + * Description: Disassembler for x86. + * + * @LICENSE@ + * + * $Id: x86_dis.c,v 1.8 2001/11/22 15:32:00 skoglund Exp $ + * + ********************************************************************/ +#include +#include "kdebug.h" + +#if defined(CONFIG_DEBUG_DISAS) +#include "../contrib/x86_dis.c" +#endif diff --git a/kernel/kdb/x86_dis.o b/kernel/kdb/x86_dis.o new file mode 100644 index 0000000..f7974b8 Binary files /dev/null and b/kernel/kdb/x86_dis.o differ diff --git a/kernel/kdb/x86_input.c b/kernel/kdb/x86_input.c new file mode 100644 index 0000000..2bb2d3f --- /dev/null +++ b/kernel/kdb/x86_input.c @@ -0,0 +1,659 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86_input.c + * Description: x86 specific kdebug input functions. + * + * @LICENSE@ + * + * $Id: x86_input.c,v 1.4 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include "kdebug.h" + +#if defined(CONFIG_ARCH_X86_I686) + +struct perfctr_t { + word_t num; + word_t unit_mask; + char *name; +}; + +static struct perfctr_t perf_counters[] = { + { 0x43, 0, "DCU mem refs" }, + { 0x45, 0, "DCU lines allocated" }, + { 0x46, 0, "DCU M lines allocated" }, + { 0x47, 0, "DCU M lines evicted" }, + { 0x48, 0, "DCU outstanding miss cycles" }, + { 0x80, 0, "IFU inst. fetches" }, + { 0x81, 0, "IFU ITLB misses" }, + { 0x86, 0, "IFU stalls" }, + { 0x28, 1, "L2 instr. fetches" }, + { 0x29, 1, "L2 data loads" }, + { 0x2A, 1, "L2 data stores" }, + { 0x24, 0, "L2 lines allocated" }, + { 0x26, 0, "L2 lines evicted" }, + { 0x25, 0, "L2 M lines allocated" }, + { 0x27, 0, "L2 M lines evicted" }, + { 0x62, 2, "BUS DRDY# clocks" }, + { 0x63, 2, "BUS LOCK# clocks" }, + { 0xC1, 0, "FP floating point ops." }, + { 0xC0, 0, "INST instr. retired" }, + { 0xC2, 0, "INST uops. retired" }, + { 0xD0, 0, "INST instr. decoded" }, + { 0xC8, 0, "INT HW intr. received" }, + { 0xC6, 0, "INT intr. disabled cycles" }, + { 0xC7, 0, "INT intr. pendeing cycles" }, + { 0xC4, 0, "BR branches retired" }, + { 0xC5, 0, "BR mispred. branches" }, + { 0xE2, 0, "BR BTB misses" }, + { 0xA2, 0, "STA Resource stalls" }, + { 0xD2, 0, "STA Partial resource stalls" }, + { 0x06, 0, "SEG Segment reg loads" }, + { 0x79, 0, "CLK CPU clock cycles" }, + { 0xFF, 0, "This help message" } +}; + + +static void print_perfctrs(void) +{ + dword_t tbl_max = sizeof(perf_counters)/sizeof(struct perfctr_t); + dword_t i, n; + + for ( i = 0; i < (tbl_max+1) / 2; i++ ) + { + /* Left column */ + n = printf(" %02x - %s", perf_counters[i].num, perf_counters[i].name); + if ( i + (tbl_max+1)/2 < tbl_max ) + { + /* Right column */ + for ( n = 38-n; n--; ) putc(' '); + printf("%02x - %s\n", perf_counters[i + (tbl_max+1)/2].num, + perf_counters[i + (tbl_max+1)/2].name); + } + else + printf("\n"); + } +} + + +dword_t kdebug_get_perfctr(char *str, dword_t def) +{ + dword_t tbl_max = sizeof(perf_counters)/sizeof(struct perfctr_t); + dword_t ctr, i; + char c; + + do { + if ( def == 0xff ) printf("%s [help]: ", str); + else printf("%s [%02x]: ", str, def); + ctr = kdebug_get_hex(def, def == 0xff ? "help" : NULL); + if ( ctr == 0xff ) + print_perfctrs(); + } while ( ctr == 0xff ); + + /* + * Check if we should specify a unit mask. + */ + for ( i = 0; i < tbl_max; i++ ) + if ( perf_counters[i].num == ctr ) + { + switch (perf_counters[i].unit_mask) + { + case 2: + /* External bus event. */ + if ( kdebug_get_choice("Bus user", "Self/Any", 's') == 'a' ) + ctr |= 0x2000; + return ctr; + case 1: + /* L2 cache event. */ + printf("MESI mask (M/E/S/I) [mesi]: "); + while ( (c = getc()) != '\r' ) + switch (c) + { + case 'm': putc(c); ctr |= 0x800; break; + case 'e': putc(c); ctr |= 0x400; break; + case 's': putc(c); ctr |= 0x200; break; + case 'i': putc(c); ctr |= 0x100; break; + } + if ( (ctr & 0xF00) == 0 ) + { + printf("mesi"); + ctr |= 0xF00; + } + putc('\n'); + + case 0: + /* No mask. */ + return ctr; + } + } + + /* Some other event. Maybe unit mask. */ + printf("Unit mask [00]: "); + ctr |= (kdebug_get_hex(0) << 8); + + return ctr; +} + +#elif defined(CONFIG_ARCH_X86_P4) + +/* + * Specification of the Pentium 4 events, their allowed counters, and + * the valid event masks. + */ + +struct perfctr_t { + byte_t event_select; + byte_t escr_select; + byte_t ctr_low; + byte_t ctr_high; + byte_t special; + char *name; + struct { + byte_t bitnum; + char *desc; + } mask[9]; +} __attribute__ ((packed)); + +static struct perfctr_t perf_counters[] = { + /* + * Non-Retirement events + */ + + { 0x06, 0x05, 12, 17, 0, "Branches", { + { 0, "Predicted NT" }, + { 1, "Mispredicted NT" }, + { 2, "Predicted taken" }, + { 3, "Mispredicted taken" }, + { 0, NULL }} }, + { 0x03, 0x04, 12, 17, 0, "Mispredicted branches", { + { 0, "Not bogus" }, + { 0, NULL }} }, + { 0x01, 0x01, 4, 7, 0, "Trace cache deliver", { + { 2, "Delivering" }, + { 5, "Building" }, + { 0, NULL }} }, + { 0x03, 0x00, 0, 3, 0, "BPU fetch request", { + { 0, "TC lookup miss" }, + { 0, NULL }} }, + { 0x18, 0x03, 0, 3, 0, "ITLB reference", { + { 0, "Hit" }, + { 1, "Miss" }, + { 2, "Uncachable hit" }, + { 0, NULL }} }, + { 0x02, 0x05, 8, 11, 0, "Memory cancel", { + { 2, "Req buffer full" }, + { 7, "Cache miss" }, + { 0, NULL }} }, + { 0x08, 0x02, 8, 11, 0, "Memory complete", { + { 0, "Load split completed" }, + { 1, "Split store completed" }, + { 0, NULL }} }, + { 0x04, 0x02, 8, 11, 0, "Load port replay", { + { 1, "Split load" }, + { 0, NULL }} }, + { 0x05, 0x02, 8, 11, 0, "Store port replay", { + { 1, "Split store" }, + { 0, NULL }} }, + { 0x03, 0x02, 0, 3, 0, "MOB load replay", { + { 1, "Unknown store address" }, + { 3, "Unknown store data" }, + { 4, "Partial overlap" }, + { 5, "Unaligned address" }, + { 0, NULL }} }, + { 0x01, 0x04, 0, 3, 0, "Page walk type", { + { 0, "DTLB miss" }, + { 1, "ITLB miss" }, + { 0, NULL }} }, + { 0x0c, 0x07, 0, 3, 1, "L2 cache reference", { + { 0, "Read hit shared" }, + { 1, "Read hit exclusive" }, + { 2, "Read hit modified" }, + { 8, "Read miss" }, + { 10, "Write miss" }, + { 0, NULL }} }, + { 0x03, 0x06, 0, 1, 1, "Bus transaction", { + { 0, "Req type (SET THIS)" }, + { 5, "Read" }, + { 6, "Write" }, + { 7, "UC access" }, + { 8, "WC access" }, + { 13, "Own CPU stores" }, + { 14, "Non-local access" }, + { 15, "Prefetch" }, + { 0, NULL }} }, + { 0x17, 0x06, 0, 3, 1, "FSB activity", { + { 0, "Ready drive" }, + { 1, "Ready own" }, + { 2, "Ready other" }, + { 3, "Busy drive" }, + { 4, "Busy own" }, + { 5, "Busy other" }, + { 0, NULL }} }, + { 0x05, 0x07, 0, 1, 2, "Bus operation", { + /* Special mask handling. */ + { 0, NULL }} }, + { 0x02, 0x05, 12, 17, 0, "Machine clear", { + { 0, "Any reason" }, + { 2, "Memory ordering" }, + { 0, NULL }} }, + + /* + * At-Retirement events. + */ + + { 0x08, 0x05, 12, 17, 3, "Front end event", { + { 0, "Not bogus" }, + { 1, "Bogus" }, + { 0, NULL }} }, + { 0x0c, 0x05, 12, 17, 4, "Execution event", { + { 0, "Not bogus 0" }, + { 1, "Not bogus 1" }, + { 2, "Not bogus 2" }, + { 3, "Not bogus 3" }, + { 4, "Bogus 0" }, + { 5, "Bogus 1" }, + { 6, "Bogus 2" }, + { 7, "Bogus 3" }, + { 0, NULL }} }, + { 0x09, 0x05, 12, 17, 5, "Replay event", { + { 0, "Not bogus" }, + { 1, "Bogus" }, + { 0, NULL }} }, + { 0x02, 0x04, 12, 17, 6, "Instr retired", { + { 0, "Non bogus untagged" }, + { 1, "Non bogus tagged" }, + { 2, "Bogus untagged" }, + { 3, "Bogus tagged" }, + { 0, NULL }} }, + { 0x01, 0x04, 12, 17, 7, "Uops retired", { + { 0, "Not bogus" }, + { 1, "Bogus" }, + { 0, NULL }} } +}; + +struct replay_tag_t { + uint16 pebs_enable; + uint16 pebs_matrix; + char *desc; +} __attribute__ ((packed)); + +static struct replay_tag_t replay_tags[] = { + { 0x0001, 0x01, "L1 cache load miss" }, + { 0x0002, 0x01, "L2 cache load miss" }, + { 0x0004, 0x01, "DTLB load miss" }, + { 0x0004, 0x02, "DTLB store miss" }, + { 0x0004, 0x03, "DTLB all miss" }, + { 0x0100, 0x01, "MOB load" }, + { 0x0200, 0x01, "Split load" }, + { 0x0200, 0x02, "Split store" } +}; + + +/* + * Helper array for easily keeping track of which ESCR MSRs are in use. + */ + +static word_t escr_msr[18]; + + +/* + * Translation table for ESCR numbers (as specified by cccr_select) to + * ESCR addresses (add 0x300 to get actual address). A zero value + * indicates an invalid ESCR selector. + */ + +static byte_t escr_to_addr[18][8] = { + { 0xa0, 0xb4, 0xaa, 0xb6, 0xac, 0xc8, 0xa2, 0xa0 }, // Ctr 0 + { 0xb2, 0xb4, 0xaa, 0xb6, 0xac, 0xc8, 0xa2, 0xa0 }, // Ctr 1 + { 0xb3, 0xb5, 0xab, 0xb7, 0xad, 0xc9, 0xa3, 0xa1 }, // Ctr 2 + { 0xb3, 0xb5, 0xab, 0xb7, 0xad, 0xc9, 0xa3, 0xa1 }, // Ctr 3 + { 0xc0, 0xc4, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Ctr 4 + { 0xc0, 0xc4, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Ctr 5 + { 0xc1, 0xc5, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Ctr 6 + { 0xc1, 0xc5, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Ctr 7 + { 0xa6, 0xa4, 0xae, 0xb0, 0x00, 0xa8, 0x00, 0x00 }, // Ctr 8 + { 0xa6, 0xa4, 0xae, 0xb0, 0x00, 0xa8, 0x00, 0x00 }, // Ctr 9 + { 0xa7, 0xa5, 0xaf, 0xb1, 0x00, 0xa9, 0x00, 0x00 }, // Ctr 10 + { 0xa7, 0xa5, 0xaf, 0xb1, 0x00, 0xa9, 0x00, 0x00 }, // Ctr 11 + { 0xba, 0xca, 0xbe, 0xbc, 0xb8, 0xcc, 0xe0, 0x00 }, // Ctr 12 + { 0xba, 0xca, 0xbe, 0xbc, 0xb8, 0xcc, 0xe0, 0x00 }, // Ctr 13 + { 0xbb, 0xcb, 0xbd, 0x00, 0xb9, 0xcd, 0xe1, 0x00 }, // Ctr 14 + { 0xbb, 0xcb, 0xbd, 0x00, 0xb9, 0xcd, 0xe1, 0x00 }, // Ctr 15 + { 0xba, 0xca, 0xbe, 0xbc, 0xb8, 0xcc, 0xe0, 0x00 }, // Ctr 16 + { 0xbb, 0xcb, 0xbd, 0x00, 0xb9, 0xcd, 0xe1, 0x00 } // Ctr 17 +}; + +static inline dword_t escr_addr(dword_t ctr, dword_t num) +{ + return escr_to_addr[ctr][num] == 0 ? 0 : escr_to_addr[ctr][num] + 0x300; +} + +static void print_perfctrs(void) +{ + dword_t tbl_max = sizeof(perf_counters)/sizeof(struct perfctr_t) + 2; + dword_t i, n; + + for ( i = 0; i < (tbl_max+1)/2; i++ ) + { + /* Left column */ + if ( i == 0 ) n = printf(" 0 - This help message"); + else n = printf(" %2d - %s", i, perf_counters[i-1].name); + + /* Right column */ + if ( i + (tbl_max+1)/2 < tbl_max ) + { + for ( n = 38-n; n--; ) putc(' '); + if ( i + (tbl_max+1)/2 == tbl_max - 1 ) + printf(" 99 - Other performance counter\n"); + else + printf(" %2d - %s\n", i + (tbl_max+1)/2, + perf_counters[i-1 + (tbl_max+1)/2].name); + } + else + printf("\n"); + } +} + +void kdebug_describe_perfctr(dword_t ctr) +{ + dword_t tbl_max = sizeof(perf_counters)/sizeof(struct perfctr_t); + qword_t cccr = rdmsr(IA32_CCCR_BASE + ctr); + struct perfctr_t *ev = NULL; + + if ( ! (cccr & (1<<12)) ) + /* Counter not enabled. */ + return; + + qword_t escr = 0; + dword_t escr_select = (cccr >> 13) & 0x7; + dword_t escr_msr = escr_addr(ctr, escr_select); + if ( escr_msr != 0 ) + escr = rdmsr(escr_msr); + + dword_t event = (escr >> 25) & 0x3f; + dword_t mask = (escr >> 9) & 0xffff; + + /* Find event description. */ + for ( dword_t i = 0; i < tbl_max; i++ ) + if ( perf_counters[i].event_select == event && + perf_counters[i].escr_select == escr_select && + perf_counters[i].ctr_low <= ctr && + perf_counters[i].ctr_high >= ctr ) + { + ev = perf_counters + i; + break; + } + + /* User/Kernel level state. */ + printf("%c%c ", escr & (1<<2) ? 'U' : ' ', escr & (1<<3) ? 'K' : ' '); + + if ( ev ) + { + dword_t i, bit = 0, first_p = 1; + printf("%s (", ev->name); + + switch ( ev->special ) + { + case 2: + { + /* Special bus operation mask. */ + static char * req_type[] = { + "read", "read invalidate", "write", "writeback"}; + static char * mem_type[] = { + "uncachable", "write combined", NULL, NULL, "write through", + "write p", "write back", NULL }; + static byte_t chunks[] = { 0, 1, 0, 8 }; + printf("%s, %d chunks, %sdemand, %s)", req_type[mask & 0x3], + chunks[(mask >> 2) & 0x3], (mask & (1<<9)) ? "" : "non-", + mem_type[(mask >> 11) & 0x07]); + break; + } + case 5: + { + /* Replay events. */ + dword_t pebs_enable = rdmsr(IA32_PEBS_ENABLE) & ~(3<<24); + dword_t pebs_matrix = rdmsr(IA32_PEBS_MATRIX_VERT); + for ( i = 0; i < sizeof(replay_tags)/sizeof(replay_tags[0]); i++ ) + if ( replay_tags[i].pebs_enable == pebs_enable && + replay_tags[i].pebs_matrix == pebs_matrix ) + { + printf("%s, ", replay_tags[i].desc); + break; + } + } + + default: + /* Normal event mask. */ + while ( mask != 0 ) + { + if ( mask & 0x1 ) + { + char *desc = NULL; + for ( int i = 0; desc == NULL && ev->mask[i].desc; i++ ) + if ( ev->mask[i].bitnum == bit ) + desc = ev->mask[i].desc; + + if ( ! first_p ) printf(", "); + if ( desc ) printf("%s", desc); + else printf("bit%d", bit); + first_p = 0; + } + + mask >>= 1; + bit++; + } + putc(')'); + } + } + else + printf("event=%02x mask=%x", event, mask); +} + + +/* + * Function kdebug_get_perfctr (escrmsr, escr, cccr) + * + * Prompt user for a Pentium 4 performance event, including event + * mask, counter number, and privilege level. Results are not + * written to MSRs, but are returned via output arguments. + * Function returns selected counter number, or -1 upon failure. + * + */ +dword_t kdebug_get_perfctr(dword_t *escrmsr, qword_t *escr, qword_t *cccr) +{ + dword_t tbl_max = sizeof(perf_counters)/sizeof(struct perfctr_t); + dword_t ctr, i, j, k, msr, c_low = 0, c_high = 17; + char c, t; + + do { + printf("Event [help]: "); + ctr = kdebug_get_dec(0, "help"); + if ( ctr == 0 ) + print_perfctrs(); + } while ( (ctr == 0) || (ctr > tbl_max && ctr != 99) ); + ctr--; + + *escr = (1 << 4); + *cccr = (1 << 12) + (3 << 16); + + if ( ctr < tbl_max ) + { + /* Predefined event */ + struct perfctr_t *ev = perf_counters + ctr; + char defmask_str[17]; + dword_t defmask = 0, mask = 0; + + *escr |= ev->event_select << 25; + *cccr |= ev->escr_select << 13; + c_low = ev->ctr_low; + c_high = ev->ctr_high; + + /* Find default mask. */ + for ( j = 0; ev->mask[j].desc; j++ ) + { + defmask_str[j] = ev->mask[j].bitnum < 10 ? + ev->mask[j].bitnum + '0' : ev->mask[j].bitnum-10 + 'a'; + defmask |= (1 << ev->mask[j].bitnum); + } + defmask_str[j] = 0; + + /* Special handling. */ + switch ( ev->special ) + { + case 1: + /* Edge triggered event. */ + *cccr |= (1 << 24); + break; + + case 2: + /* Special handling for bus operations. */ + *cccr |= (1 << 24); + c= kdebug_get_choice("Request type", + "Read/read Invalidate/Write/writeBack", 'r'); + switch (c) + { + case 'r': mask = 0; break; + case 'i': mask = 1; break; + case 'w': mask = 2; break; + case 'b': mask = 3; break; + } + c= kdebug_get_choice("Requested chunks", "0/1/8", '0'); + switch (c) + { + case '0': mask |= (0 << 2); break; + case '1': mask |= (1 << 2); break; + case '8': mask |= (3 << 2); break; + } + c = kdebug_get_choice("Request is a demand", "Yes/No", 'y'); + if ( c == 'y' ) mask |= (1 << 9); + c = kdebug_get_choice("Memory type", "Uncachable/writeCombined/" + "writeThrough/writeP/writeBack", 'b'); + switch (c) + { + case 'u': mask |= (0 << 11); break; + case 'c': mask |= (1 << 11); break; + case 't': mask |= (4 << 11); break; + case 'p': mask |= (5 << 11); break; + case 'b': mask |= (6 << 11); break; + } + break; + + case 5: + /* Replay events. */ + for ( i = 0; i < sizeof(replay_tags)/sizeof(replay_tags[0]); i++ ) + printf("%3d - %s\n", i, replay_tags[i].desc); + do { + printf("Select replay event [0]: "); + k = kdebug_get_dec(); + } while ( k >= sizeof(replay_tags)/sizeof(replay_tags[0]) ); + + wrmsr(IA32_PEBS_ENABLE, replay_tags[k].pebs_enable + (3<<24)); + wrmsr(IA32_PEBS_MATRIX_VERT, replay_tags[k].pebs_matrix); + break; + } + + /* Get event mask. */ + if ( j > 1 ) + { + printf("Valid event masks:\n"); + for ( j = 0; ev->mask[j].desc; j++ ) + printf(" %c - %s\n", + ev->mask[j].bitnum < 10 ? + ev->mask[j].bitnum + '0' : ev->mask[j].bitnum-10 + 'a', + ev->mask[j].desc); + printf("Event mask [%s]: ", defmask_str); + while ( (t = c = getc()) != '\r' ) + { + switch (c) + { + case '0' ... '9': c -= '0'; break; + case 'a' ... 'f': c -= 'a' - 'A'; + case 'A' ... 'F': c = c - 'A' + 10; break; + default: continue; + } + putc(t); + mask |= (1 << c); + } + if ( mask == 0 ) + printf("%s", defmask_str); + putc('\n'); + } + if ( mask == 0 ) + mask = defmask; + + *escr |= (mask & 0xffff) << 9; + } + else + { + /* No predefined event, set manually. */ + printf("Event select [0]: "); + *escr |= (kdebug_get_hex() & 0x3f) << 25; + printf("ESCR select [0]: "); + *cccr |= (kdebug_get_hex() & 0x07) << 13; + printf("Event mask [0]: "); + *escr |= (kdebug_get_hex() & 0xffff) << 9; + } + + /* Get counter number. */ + for (;;) + { + printf("Counter (%d-%d) [%d]: ", c_low, c_high, c_low); + ctr = kdebug_get_dec(c_low); + msr = escr_addr(ctr, (*cccr >> 13) & 0x7); + + if ( ctr >= c_low && ctr <= c_high ) + { + /* Check if ESCR is already in use. */ + for ( i = 0; i < 18; i++ ) + { + if ( escr_msr[i] == 0 || ctr == i ) + continue; + if ( rdmsr(IA32_CCCR_BASE + i) & (1 << 12) ) + { + if ( escr_msr[i] == msr ) + break; + } + else + escr_msr[i] = 0; + } + + if ( i < 18 ) + { + c = kdebug_get_choice("ESCR already in use", + "Overwrite/Try other counter/Cancel", + 't'); + if ( c == 'o' ) break; + else if ( c == 'c' ) return ~0; + } + else + /* ESCR is currently not in use. */ + break; + } + + } + + /* Should only occur if ESCR and event mask is selected manually. */ + if ( msr == 0 ) + { + printf("Invalid perf counter/ESCR selector.\n"); + return ~0; + } + *escrmsr = escr_msr[ctr] = msr; + + /* Select privilege level where counter should be active. */ + c = kdebug_get_choice("Privilege level", "User/Kernel/Both", 'b'); + switch (c) + { + case 'u': *escr |= (1 << 2); break; + case 'b': *escr |= (1 << 2); + case 'k': *escr |= (1 << 3); break; + } + + return ctr; +} + + +#endif /* CONFIG_ARCH_X86_P4 */ diff --git a/kernel/kdb/x86_input.o b/kernel/kdb/x86_input.o new file mode 100644 index 0000000..32909a0 Binary files /dev/null and b/kernel/kdb/x86_input.o differ diff --git a/kernel/kdb/x86_io.c b/kernel/kdb/x86_io.c new file mode 100644 index 0000000..9a104aa --- /dev/null +++ b/kernel/kdb/x86_io.c @@ -0,0 +1,204 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86_io.c + * Description: Various low level I/O functions for x86. + * + * @LICENSE@ + * + * $Id: x86_io.c,v 1.4 2001/12/04 16:56:26 uhlig Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) +#include "kdebug.h" + +/* +** +** Console I/O functions. +** +*/ + +#if defined(CONFIG_DEBUGGER_IO_OUTSCRN) +# if defined(CONFIG_DEBUGGER_IO_SCREEN_VGA) +# define DISPLAY ((char*)KERNEL_VIDEO) +# define NUM_LINES 25 +# else +# define DISPLAY ((char*)KERNEL_VIDEO_HERC) +# define NUM_LINES 24 +# endif +#define COLOR 10 +static unsigned __cursor = 0; + +void putc(char c) +{ + switch(c) { + case '\r': + __cursor -= (__cursor % 160); + break; + case '\n': + __cursor += (160 - (__cursor % 160)); + break; + case '\t': + __cursor += (8 - (__cursor % 8)); + break; + default: + DISPLAY[__cursor++] = c; + DISPLAY[__cursor++] = COLOR; + } + + if ((__cursor / 160) == NUM_LINES) { + for (int i = 40; i < 40*NUM_LINES; i++) + ((dword_t*)DISPLAY)[i - 40] = ((dword_t*)DISPLAY)[i]; + for (int i = 0; i < 40; i++) + ((dword_t*)DISPLAY)[40*(NUM_LINES-1) + i] = 0; + __cursor -= 160; + } +} +#endif /* CONFIG_DEBUGGER_IO_OUTSCRN */ + + +#if defined(CONFIG_DEBUGGER_IO_INKBD) + +#define KBD_STATUS_REG 0x64 +#define KBD_CNTL_REG 0x64 +#define KBD_DATA_REG 0x60 + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ + +#define kbd_read_input() inb(KBD_DATA_REG) +#define kbd_read_status() inb(KBD_STATUS_REG) + +static unsigned char keyb_layout[2][128] = +{ + "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ + "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ + "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ + "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/" /* 0x60 - 0x6f */ + , + "\000\033!@#$%^&*()_+\177\t" /* 0x00 - 0x0f */ + "QWERTYUIOP{}\r\000AS" /* 0x10 - 0x1f */ + "DFGHJKL:\"`\000\\ZXCV" /* 0x20 - 0x2f */ + "BNM<>?\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ + "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ + "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ + "\r\000/" /* 0x60 - 0x6f */ +}; + +char getc() +{ + static byte_t last_key = 0; + static byte_t shift = 0; + char c; + while(1) { + unsigned char status = kbd_read_status(); + while (status & KBD_STAT_OBF) { + byte_t scancode; + scancode = kbd_read_input(); + /* check for SHIFT-keys */ + if (((scancode & 0x7F) == 42) || ((scancode & 0x7F) == 54)) + { + shift = !(scancode & 0x80); + continue; + } + /* ignore all other RELEASED-codes */ + if (scancode & 0x80) + last_key = 0; + else if (last_key != scancode) + { +// printf("kbd: %d, %d, %c\n", scancode, last_key, +// keyb_layout[shift][scancode]); + last_key = scancode; + c = keyb_layout[shift][scancode]; + if (c > 0) return c; + } + } + } +} + +#endif /* CONFIG_DEBUGGER_IO_INKBD */ + +#if !defined(CONFIG_DEBUGGER_IO_INCOM) && defined(CONFIG_DEBUG_BREAKIN) +void kdebug_check_breakin(void) +{ +} +#endif + + + + +/* +** +** Serial port I/O functions. +** +*/ + + +#if defined(CONFIG_DEBUGGER_IO_INCOM) || defined(CONFIG_DEBUGGER_IO_OUTCOM) +#define COMPORT CONFIG_DEBUGGER_COMPORT +#define RATE CONFIG_DEBUGGER_COMSPEED + +void kdebug_init_serial(void) +{ +#define IER (COMPORT+1) +#define EIR (COMPORT+2) +#define LCR (COMPORT+3) +#define MCR (COMPORT+4) +#define LSR (COMPORT+5) +#define MSR (COMPORT+6) +#define DLLO (COMPORT+0) +#define DLHI (COMPORT+1) + + outb(LCR, 0x80); /* select bank 1 */ + for (volatile int i = 10000000; i--; ); + outb(DLLO, (((115200/RATE) >> 0) & 0x00FF)); + outb(DLHI, (((115200/RATE) >> 8) & 0x00FF)); + outb(LCR, 0x03); /* set 8,N,1 */ + outb(IER, 0x00); /* disable interrupts */ + outb(EIR, 0x07); /* enable FIFOs */ + outb(IER, 0x01); /* enable RX interrupts */ + inb(IER); + inb(EIR); + inb(LCR); + inb(MCR); + inb(LSR); + inb(MSR); +} +#endif /* CONFIG_DEBUGGER_IO_INCOM || CONFIG_DEBUGGER_IO_OUTCOM */ + + + +#if defined(CONFIG_DEBUGGER_IO_OUTCOM) +void putc(const char c) +{ + while (!(inb(COMPORT+5) & 0x60)); + outb(COMPORT,c); + if (c == '\n') + putc('\r'); + +} +#endif /* CONFIG_DEBUGGER_IO_OUTCOM */ + + +#if defined(CONFIG_DEBUGGER_IO_INCOM) +char getc(void) +{ + while (!(inb(COMPORT+5) & 0x01)); + return inb(COMPORT); +} + +#if defined(CONFIG_DEBUG_BREAKIN) +void kdebug_check_breakin(void) +{ + if ((inb(COMPORT+5) & 0x01)) + { + if (inb(COMPORT) == 0x1b) + enter_kdebug("breakin"); + } +} +#endif +#endif /* CONFIG_DEBUGGER_IO_INCOM */ diff --git a/kernel/kdb/x86_io.o b/kernel/kdb/x86_io.o new file mode 100644 index 0000000..22ccc9a Binary files /dev/null and b/kernel/kdb/x86_io.o differ diff --git a/kernel/kdb/x86_profiling.c b/kernel/kdb/x86_profiling.c new file mode 100644 index 0000000..d1f3bda --- /dev/null +++ b/kernel/kdb/x86_profiling.c @@ -0,0 +1,745 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86_profiling.c + * Description: Random sampling profiling support for x86. + * + * @LICENSE@ + * + * $Id: x86_profiling.c,v 1.16 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_ENABLE_PROFILING) + +#include +#include +#include "kdebug.h" + + +#define PROF_MIN_SAMPLE_PERIOD 1000 +#define PROF_DEF_SAMPLE_PERIOD 4096 +#define PROF_LOG_WINDOW_SIZE (4096*128) +#define PROF_LOG_MAX (PROF_LOG_WINDOW_SIZE/sizeof(prof_event_t)) +#define PROF_DEF_LOW_DUMPLIMIT 10 +#define PROF_FREQ_COUNTERS 8 +#define PROF_NUM_VALUES CONFIG_PROFILING_MAX_VAL + +#define PROF_LOG_NONE (0) +#define PROF_LOG_USER (1) +#define PROF_LOG_KERNEL (2) +#define PROF_LOG_BOTH (PROF_LOG_USER | PROF_LOG_KERNEL) + + + +typedef struct prof_event_t prof_event_t; +typedef struct prof_freq_t prof_freq_t; + +struct prof_event_t { + l4_threadid_t tid; + dword_t eip; + dword_t value[PROF_NUM_VALUES]; +}; + +struct prof_freq_t { + float prob; + dword_t counter[PROF_FREQ_COUNTERS]; + dword_t value[PROF_FREQ_COUNTERS]; +}; + + + +static int prof_do_sampling; +static prof_event_t *prof_log; +static dword_t prof_pos; +static dword_t prof_sample_period; +static dword_t prof_thread; +static dword_t prof_task; +static dword_t prof_region_beg; +static dword_t prof_region_end; +static dword_t prof_trigger_event; +static dword_t prof_evsel[2]; +static dword_t prof_valuetype[PROF_NUM_VALUES]; +static dword_t prof_restore_single_step; + +/* From x86/init.c */ +extern idt_desc_t idt[]; + + +static void reset_perfctr(void); +static void clear(prof_freq_t *fr); +static void add(prof_freq_t *fr, dword_t val); +static void reduce(prof_freq_t *fr); +static void dump(prof_freq_t *fr); +static void srandom(dword_t seed); +static dword_t random(void); + + +#define TASK_TCB(x) ((dword_t) (x) & (L4_TCB_MASK << L4_X0_THREADID_BITS)) + +void kdebug_setperfctr(dword_t ctrsel, dword_t value, int counter_value) +{ + /* Validate counter selector. */ + if ( ctrsel > 1 ) + return; + + asm volatile ( + " lea %c3(%1), %%ecx \n" + " sub %%edx, %%edx \n" + " wrmsr \n" + " lea %c4(%1), %%ecx \n" + " movl %2, %%eax \n" + " wrmsr \n" + + : /* Outputs */ + "+a"(value) + + : /* Inputs */ + "r"(ctrsel), "r"(counter_value), + "i"(IA32_EVENTSEL0), "i"(IA32_PERFCTR0) + + : /* Clobbers */ + "ecx", "edx"); +} + + +/* +** +** The following pseudo random generator should produce numbers which +** are uniformely distributed between 0 and 0xffffffff. +** +*/ + +static dword_t random_seed = 1; + +static void srandom(dword_t seed) +{ + random_seed = seed; +} + +static dword_t random(void) +{ + long result, div, mod; + + div = random_seed / 127773; + mod = random_seed % 127773; + result = 16807 * mod - 2836 * div; + if ( result <= 0 ) + result += 0x7fffffff; + random_seed = result; + + return result; +} + + + +/* +** +** Code for sorting the profiling log. The log is sorted on ascending +** thread id's, and ascending eip's if thread id's are equal. Sorting +** the log makes it much easier to parse it afterwards. +** +*/ + +static inline void swap(prof_event_t *a, prof_event_t *b) +{ + prof_event_t c = *a; + *a = *b; + *b = c; +} + +static inline int operator == (const prof_event_t a, const prof_event_t b) +{ + return (a.tid.raw == b.tid.raw) && (a.eip == b.eip); +} + +static inline int operator < (const prof_event_t a, const prof_event_t b) +{ + return (a.tid.raw < b.tid.raw) || + ((a.tid.raw == b.tid.raw) && (a.eip < b.eip)); +} + +static inline int operator <= (const prof_event_t a, const prof_event_t b) +{ + return (a < b) || (a == b); +} + +static void kdebug_proflog_sort(void) +{ + dword_t child, parse; + dword_t max_pos = prof_pos; + prof_event_t tmp; + + /* + * The following heaposrt alogorithm assumes that the first + * element in the array has index 1 and the last element has index + * max_pos. + */ + prof_log--; + + /* Create initial heap. */ + for ( dword_t i = max_pos/2; i > 0; i-- ) + { + for ( parse = i; (child = parse * 2) <= max_pos; parse = child) + { + if ( (child < max_pos) && (prof_log[child] < prof_log[child+1]) ) + child++; + + if ( prof_log[child] <= prof_log[parse] ) + break; + + swap(&prof_log[parse], &prof_log[child]); + } + } + + while ( max_pos > 1 ) + { + /* Save largest element into its final slot. */ + tmp = prof_log[max_pos]; + prof_log[max_pos] = prof_log[1]; + max_pos--; + + /* Reheapify. */ + for ( parse = 1; (child = parse * 2) <= max_pos; parse = child ) + { + if ( (child < max_pos) && (prof_log[child] < prof_log[child+1]) ) + child++; + + prof_log[parse] = prof_log[child]; + } + for (;;) + { + child = parse; + parse = child / 2; + if ( (child == 1) || (tmp < prof_log[parse]) ) + { + prof_log[child] = tmp; + break; + } + prof_log[child] = prof_log[parse]; + } + } + + /* Reset first element to have index 0. */ + prof_log++; + + return; +} + + + + +/* +** +** Profile dumping code. +** +*/ + + +void kdebug_profile_dump(tcb_t *current) +{ + static prof_freq_t freq[PROF_NUM_VALUES]; + static x86_fpu_state_t fpu_state; + l4_threadid_t p_tid = L4_NIL_ID; + dword_t dthread = 0, dtask = 0; + dword_t p_eip = ~0UL, eip_cnt = 0; + dword_t low_limit, region_beg, region_end; + char c; + + region_beg = 0; + region_end = 0xffffffff; + + printf("\nLog size = %d (max %d), Sample period = ~%d events\n", + prof_pos, PROF_LOG_MAX, prof_sample_period); + + c = kdebug_get_choice("Dump", prof_thread == 0 ? prof_task == 0 ? + "thRead/All/reGion/Nothing" : + "thRead/taSk/All/reGion/Nothing" : + "All/reGion/Nothing", 'a'); + + switch (c) + { + case 'n': return; + case 'r': dthread = (dword_t) kdebug_get_thread(current); break; + case 's': dtask = (dword_t) kdebug_get_task(current); break; + case 'g': + printf("Region beg. [00000000]: "); + region_beg = kdebug_get_hex(0); + printf("Region end [ffffffff]: "); + region_end = kdebug_get_hex(0xffffffff); + break; + } + + printf("Lower count limit [%d]: ", PROF_DEF_LOW_DUMPLIMIT); + low_limit = kdebug_get_dec(PROF_DEF_LOW_DUMPLIMIT); + + kdebug_proflog_sort(); + + enable_fpu(); + save_fpu_state((byte_t *) &fpu_state); + + for ( dword_t i = 0; i < prof_pos; i++ ) + { + /* Skip unwanted threads or tasks. */ + if ( (dthread && dthread != (dword_t) tid_to_tcb(prof_log[i].tid)) || + (dtask && dtask != TASK_TCB(tid_to_tcb(prof_log[i].tid))) ) + continue; + + /* Skip unwanted regions. */ + if ( prof_log[i].eip < region_beg || prof_log[i].eip > region_end ) + continue; + + if ( (prof_log[i].eip != p_eip) || (prof_log[i].tid != p_tid) ) + { + /* Dump counterd values. */ + if ( p_eip != ~0UL && eip_cnt >= low_limit ) + { + printf(" %p:%6d", p_eip, eip_cnt); + for ( dword_t k = 0; k < PROF_NUM_VALUES; k++ ) + { + if ( prof_valuetype[k] == 0 ) + { + if ( k == 0 ) putc('\n'); + break; + } + printf("%s v%d", k>0 ? " " : "", k); + dump(freq + k); + } + if ( PROF_NUM_VALUES == 0 ) putc('\n'); + } + + /* Reset counters. */ + p_eip = prof_log[i].eip; + eip_cnt = 0; + for ( dword_t k = 0; k < PROF_NUM_VALUES; k++ ) + { + if ( prof_valuetype[k] == 0 ) break; + clear(freq + k); + } + } + + if ( prof_log[i].tid != p_tid ) + { + p_tid = prof_log[i].tid; + printf("Thread %p (%t):\n", p_tid.raw, p_tid); + } + + /* Increase counters. */ + eip_cnt++; + for ( dword_t k = 0; k < PROF_NUM_VALUES; k++ ) + { + if ( prof_valuetype[k] == 0 ) break; + add(freq + k, prof_log[i].value[k]); + } + } + + if ( p_eip != ~0UL && eip_cnt >= low_limit ) + { + /* Dump counted values. */ + printf(" %p:%6d", p_eip, eip_cnt); + for ( dword_t k = 0; k < PROF_NUM_VALUES; k++ ) + { + if ( prof_valuetype[k] == 0 ) + { + if ( k == 0 ) putc('\n'); + break; + } + printf("%s v%d", k>0 ? " " : "", k); + dump(freq + k); + } + if ( PROF_NUM_VALUES == 0 ) putc('\n'); + } + + load_fpu_state((byte_t *) &fpu_state); + disable_fpu(); +} + + + +/* +** +** The prof_freq_t structure is a conatiner which implements the +** Gibbons and Mattias' algorithm for summarizing a stream of data. +** The PROF_FREQ_COUNTERS tells how many different values the +** container can hold. +** +*/ + +void clear(prof_freq_t *fr) +{ + for ( int i = 0; i < PROF_FREQ_COUNTERS; i++ ) + fr->counter[i] = fr->value[i] = 0; + fr->prob = 1.0; +} + +void add(prof_freq_t *fr, dword_t val) +{ + int i; + + /* Search for slot with given value. */ + for ( i = 0; i < PROF_FREQ_COUNTERS; i++ ) + if ( fr->value[i] == val ) + break; + + while ( i == PROF_FREQ_COUNTERS ) + { + /* Search for free slot. */ + for ( i = 0; i < PROF_FREQ_COUNTERS; i++ ) + if ( fr->counter[i] == 0 ) + { + fr->value[i] = val; + break; + } + if ( i == PROF_FREQ_COUNTERS ) + /* No free slots. */ + reduce(fr); + } + + /* Update counter with probability fr->prob. */ + if ( fr->prob == 1.0 || /* Common case */ + random() <= (fr->prob * 0xffffffff) ) + fr->counter[i]++; +} + +void reduce(prof_freq_t *fr) +{ + for ( dword_t i = 0; i < PROF_FREQ_COUNTERS; i++ ) + { + dword_t cnt = 0; + while ( fr->counter[i]-- ) + if ( (random() & (PROF_FREQ_COUNTERS-1)) != 0 ) + cnt++; + fr->counter[i] = cnt; + } + fr->prob *= ((float) (PROF_FREQ_COUNTERS-1)) / PROF_FREQ_COUNTERS; +} + +void dump(prof_freq_t *fr) +{ + dword_t i; + dword_t sum = 0; + + for ( i = 0; i < PROF_FREQ_COUNTERS; i++ ) + { + if ( fr->counter[i] == 0 ) + continue; + printf(" [%4d:%p]", + (dword_t) (((float) fr->counter[i]) / fr->prob), + fr->value[i]); + sum += fr->counter[i]; + } + putc('\n'); +} + + + + +/* +** +** The kdebug interface to the profiling functions. Everything above +** this is only code for processing and presenting the logged profile. +** +*/ + +void kdebug_profiling(tcb_t *current) +{ + char c = 0; + + c = kdebug_get_choice("\nProfile", + "thRead/taSk/reGion/All/Clear log/Nothing", 'a'); + + if ( c != 'c' ) + { + prof_do_sampling = PROF_LOG_NONE; + prof_sample_period = prof_thread = prof_task = 0; + prof_region_beg = 0; + prof_region_end = 0xffffffff; + } + + switch (c) + { + case 'n': + /* Reset NMI interrupts. */ + idt[2].set((void (*)()) int_2, IDT_DESC_TYPE_INT, 0); + return; + case 'r': prof_thread = (dword_t) kdebug_get_thread(current); break; + case 's': prof_task = (dword_t) kdebug_get_task(current); break; + case 'g': + printf("Region beg. [00000000]: "); + prof_region_beg = kdebug_get_hex(0); + printf("Region end [ffffffff]: "); + prof_region_end = kdebug_get_hex(0xffffffff); + break; + case 'c': + goto Clear_log; + } + +#if defined(CONFIG_PROFILING_WITH_NMI) + if ( prof_region_beg >= KERNEL_VIRT ) + { + prof_do_sampling = PROF_LOG_KERNEL; + } + else if ( prof_region_end >= KERNEL_VIRT ) + { + c = kdebug_get_choice("Profile", "Kernel/User/Both", 'u'); + switch (c) + { + case 'k': prof_do_sampling = PROF_LOG_KERNEL; break; + case 'u': prof_do_sampling = PROF_LOG_USER; break; + case 'b': prof_do_sampling = PROF_LOG_BOTH; break; + } + } + + /* Redirect NMI interrupts to the perfctr handler. */ + idt[2].set((void (*)()) apic_perfctr, IDT_DESC_TYPE_INT, 0); +#else + prof_do_sampling = PROF_LOG_USER; +#endif + + prof_trigger_event = kdebug_get_perfctr("Trigger event", 0x79); + + while ( prof_sample_period < PROF_MIN_SAMPLE_PERIOD ) + { + printf("Sample period [%d]: ", PROF_DEF_SAMPLE_PERIOD); + prof_sample_period = kdebug_get_dec(PROF_DEF_SAMPLE_PERIOD); + if ( prof_sample_period < PROF_MIN_SAMPLE_PERIOD ) + printf("Min. period is %d\n", PROF_MIN_SAMPLE_PERIOD); + } + + for ( dword_t vnum = 0; vnum < PROF_NUM_VALUES; vnum++ ) + { + prof_valuetype[vnum] = 0; + if ( vnum > 0 && prof_valuetype[vnum-1] == 0 ) + continue; + + printf("Sample value %d ", vnum); + c = kdebug_get_choice("", vnum < 2 ? "Perfctr/Register/None" : + "Register/None", 'n'); + switch (c) + { + case 'p': + if ( prof_do_sampling & PROF_LOG_KERNEL ) + printf("Note: Can not enable perfctr sampling " + "in kernel.\n"); + prof_valuetype[vnum] = 0xff; + prof_evsel[vnum] = kdebug_get_perfctr("Event selector", 0xff); + break; + case 'r': + c = kdebug_get_choice("Register", + "eAx/eBx/eCx/eDx/Esi/edI/ebP/eSp/eFlags/" + "data seG", 'a'); + switch (c) + { + case 'a': prof_valuetype[vnum] = 10; break; /* eax */ + case 'c': prof_valuetype[vnum] = 9; break; /* ecx */ + case 'd': prof_valuetype[vnum] = 8; break; /* edx */ + case 'b': prof_valuetype[vnum] = 7; break; /* ebx */ + case 'p': prof_valuetype[vnum] = 5; break; /* ebp */ + case 'e': prof_valuetype[vnum] = 4; break; /* esi */ + case 'i': prof_valuetype[vnum] = 3; break; /* edi */ + case 's': prof_valuetype[vnum] = 15; break; /* esp */ + case 'f': prof_valuetype[vnum] = 14; break; /* efl */ + case 'g': prof_valuetype[vnum] = 2; break; /* ds */ + } + break; + case 'n': + break; + } + } + +Clear_log: + + /* Clear log. */ + prof_pos = 0; + for ( dword_t i = 0; i < PROF_LOG_MAX; i++ ) + { + prof_log[i].tid.raw = prof_log[i].eip = 0; + for ( dword_t k = 0; k < PROF_NUM_VALUES; k++ ) + prof_log[i].value[k] = 0; + } + + if ( prof_do_sampling ) + reset_perfctr(); +} + + +/* + * Handler invoked when the instruction following the trigger point + * has been executred. + */ + +void handle_perfctr_bounce_back(exception_frame_t *frame) +{ + for ( dword_t i = 0; i < PROF_NUM_VALUES; i++ ) + { + if ( prof_valuetype[i] == 0x00 ) + break; + if ( prof_valuetype[i] == 0xff ) + { + if ( prof_log[prof_pos].eip < KERNEL_VIRT ) + prof_log[prof_pos].value[i] = rdpmc(i); + } + else + { + prof_log[prof_pos].value[i] = + ((dword_t *) frame)[prof_valuetype[i]]; + if ( prof_valuetype[i] == 2 ) + prof_log[prof_pos].value[i] &= 0xffff;; + } + } + + if ( prof_pos < PROF_LOG_MAX-1 ) + prof_pos++; + + /* Restore single stepping state. */ + idt[1].set((void (*)()) int_1, IDT_DESC_TYPE_INT, 0); + if ( prof_restore_single_step ) + frame->eflags |= (1 << 16); + else + frame->eflags &= ~(1 << 8); + + reset_perfctr(); +} + + +/* + * Handler invoked on every profiling trigger interrupt. + */ + +void apic_handler_perfctr(dword_t eip, dword_t *eflags) +{ + if ( ! prof_do_sampling ) + { + /* Turn off random sampling. */ + kdebug_setperfctr(0, 0, 0); + apic_ack_irq(); + return; + } + + tcb_t *current = get_current_tcb(); + int value; + + /* Skip samples outside our sampling area. */ + if ( ((eip < KERNEL_VIRT) && (~prof_do_sampling & PROF_LOG_USER)) || + ((eip >= KERNEL_VIRT) && (~prof_do_sampling & PROF_LOG_KERNEL)) ) + goto Skip_tick; + if ( (eip < prof_region_beg) || (eip > prof_region_end) ) + goto Skip_tick; + + /* Skip samples in unwanted threads or tasks. */ + if ( (prof_thread && (prof_thread != (dword_t) current)) || + (prof_task && (prof_task != (dword_t) TASK_TCB(current))) ) + goto Skip_tick; + + /* Skip samples in kdebug, but keep samples in the idler. */ + if ( ((dword_t) current > TCB_AREA+TCB_AREA_SIZE) && + (current != get_idle_tcb()) ) + goto Skip_tick; + + prof_log[prof_pos].tid = current->myself; + prof_log[prof_pos].eip = eip; + + if ( (PROF_NUM_VALUES > 0) && prof_valuetype[0] ) + { + /* + * Do value sampling. Single step next instruction. + */ + prof_restore_single_step = *eflags & (1<<8); + *eflags |= (1 << 8) + (1 << 16); + idt[1].set((void (*)()) perfctr_bounce_back, IDT_DESC_TYPE_INT, 0); + + if ( (eip < KERNEL_VIRT) && + (prof_valuetype[0] == 0xff || + ((PROF_NUM_VALUES > 1) && prof_valuetype[1] == 0xff)) ) + { + /* Use performance counters. */ + value = prof_evsel[0]; + value |= (1 << 22); /* Enable counter */ + value |= (1 << 16); /* Count user-level events */ + kdebug_setperfctr(0, value, 0); + + value = prof_evsel[1]; + value |= (1 << 16); /* Count user-level events */ + kdebug_setperfctr(1, value, 0); + } + + apic_ack_irq(); + return; + } + + if ( prof_pos < PROF_LOG_MAX ) + prof_pos++; + +Skip_tick: + + reset_perfctr(); +} + + +static void reset_perfctr(void) +{ + dword_t value; + + value = prof_trigger_event; + value |= (1 << 22); /* Enable counter */ + value |= (1 << 20); /* Generate APIC int */ + value |= (1 << 16); /* Count user-level events */ + if ( prof_do_sampling & PROF_LOG_KERNEL ) + value |= (1 << 17); /* Count kernel-level events */ + + dword_t randvar = (rdtsc() & 0xff); + kdebug_setperfctr(0, value, -(prof_sample_period ^ randvar)); + kdebug_setperfctr(1, 0, 0); + apic_ack_irq(); +} + + +void kdebug_init_profiling(void) +{ + prof_log = (prof_event_t *) kmem_alloc(PROF_LOG_WINDOW_SIZE); + prof_pos = 0; + prof_do_sampling = 0; + srandom(rdtsc()); + + if ( prof_log == NULL ) + printf("*** Failed allocating profiling log.\n"); +} + + + +#endif /* CONFIG_ENABLE_PROFILING */ + +#if defined(CONFIG_DEBUGGER_NEW_KDB) +/* for the new debugger */ + +#include "pmc_values.h" + +//from x86.c +void enable_pmc_of_int(); +void disable_pmc_of_int(); +void clear_perfctr(int counter); +void set_event(int counter, dword_t arg); + + +void init_pmcs() { + set_event(0, 0); + clear_perfctr(0); + set_event(1, 0); + clear_perfctr(1); +} + +void clear_perfctr(int counter) { + int counter_register = PERFCTR0 + counter; + wrmsr(counter_register, 0); +} + +void set_event(int counter, dword_t arg) { + int selection_register = PERFEVENTSEL0 + counter; + clear_perfctr(counter); + wrmsr(selection_register, (qword_t) arg); +} + +/* end of my part */ +#endif /* define(CONFIG_DEBUGGER_NEW_KDB) */ diff --git a/kernel/kdb/x86_profiling.o b/kernel/kdb/x86_profiling.o new file mode 100644 index 0000000..2096454 Binary files /dev/null and b/kernel/kdb/x86_profiling.o differ diff --git a/kernel/kdb/x86_smp.c b/kernel/kdb/x86_smp.c new file mode 100644 index 0000000..f1cbfc6 --- /dev/null +++ b/kernel/kdb/x86_smp.c @@ -0,0 +1,81 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86_smp.c + * Description: kernel-debugger SMP functionality + * + * @LICENSE@ + * + * $Id: x86_smp.c,v 1.1 2001/12/04 21:17:43 uhlig Exp $ + * + ********************************************************************/ +#include +#include "kdebug.h" + +#if defined(CONFIG_SMP) +#include + +INLINE void broadcast_nmi_ipi() +{ + /* send nmi to all cpu's excl. myself */ + set_local_apic(X86_APIC_INTR_CMD2, 0xff << (56 - 32)); + set_local_apic(X86_APIC_INTR_CMD1, 0xc0000 | APIC_DEL_NMI); +} + + +void smp_handler_control_ipi() +{ + //printf("cpu %d: smp control ipi\n", get_cpu_id()); + /* currently only used for enter_kdebug */ + //printf("#cpu %d, ", get_cpu_id()); + asm("int3;nop\n"); + //printf("$CPU %d, ", get_cpu_id()); + + apic_ack_irq(); +} + +static volatile int kdb_first_cpu = 0; +void smp_enter_kdebug() +{ + if (!(kdb_first_cpu++)) + broadcast_nmi_ipi(); + //printf("cpu %d entered kdb\n", get_cpu_id()); + //cpu_mailbox_t * mailbox = get_mailbox(); + //mailbox->broadcast_command(SMP_CMD_ENTER_KDEBUG); +} + +void smp_leave_kdebug() +{ + kdb_first_cpu = 0; +} + +extern cpu_mailbox_t cpu_mailbox[]; +static void kdebug_dump_mailboxes() +{ + for (int i = 0; i < CONFIG_SMP_MAX_CPU; i++) + { + printf("cpu: %d\tpend: %x\n", i, cpu_mailbox[i].pending_requests); + printf("command: %d\tstatus: %d\ttcb: %x\n", + cpu_mailbox[i].get_command(), + cpu_mailbox[i].get_status(), + cpu_mailbox[i].tid); + printf("params:\t"); + for (int j = 0; j < MAX_MAILBOX_PARAM; j++) + printf("%x ", cpu_mailbox[i].param[j]); + printf("\n\n"); + } +} + +void kdebug_smp_info() +{ + switch(kdebug_get_choice("SMP Info: Mailboxes", "m")) + { + case 'm': + kdebug_dump_mailboxes(); + break; + } +} + + +#endif /* CONFIG_SMP */ diff --git a/kernel/kdb/x86_smp.o b/kernel/kdb/x86_smp.o new file mode 100644 index 0000000..3b5f4d0 Binary files /dev/null and b/kernel/kdb/x86_smp.o differ diff --git a/kernel/kdb/x86_tracestore.c b/kernel/kdb/x86_tracestore.c new file mode 100644 index 0000000..e82e4b3 --- /dev/null +++ b/kernel/kdb/x86_tracestore.c @@ -0,0 +1,175 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86_tracestore.c + * Description: Automatic logging of various traces to memory. + * + * @LICENSE@ + * + * $Id: x86_tracestore.c,v 1.2 2001/11/22 12:13:54 skoglund Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_X86_P4_BTS) || defined(CONFIG_X86_P4_PEBS) + +#include "kdebug.h" + + +#define BTS_BUFSIZE (1024*CONFIG_X86_P4_BTS_BUFSIZE) +#define PEBS_BUFSIZE (1024*CONFIG_X86_P4_PEBS_BUFSIZE) +#define BTS_SIZE (BTS_BUFSIZE/sizeof (branch_trace_t)) +#define PEBS_SIZE (PEBS_BUFSIZE/sizeof (pebs_record_t)) + + +typedef struct branch_trace_t branch_trace_t; +typedef struct pebs_record_t pebs_record_t; + +struct branch_trace_t { + dword_t from; + dword_t to; + struct { + unsigned __pad1:4; + unsigned predicted:1; + unsigned __pad2:27; + } flags; +}; + +struct pebs_record_t { + dword_t eflags; + dword_t eip; + dword_t eax; + dword_t ebx; + dword_t ecx; + dword_t edx; + dword_t esi; + dword_t edi; + dword_t ebp; + dword_t esp; +}; + + +/* + * The DS_AREA msr specifies the location in memory where the + * following buffer management pointers are located. + */ + +struct ds_bufmng_area_t { + branch_trace_t *bts_base; + branch_trace_t *bts_index; + branch_trace_t *bts_maximum; + branch_trace_t *bts_intr; + + pebs_record_t *pebs_base; + pebs_record_t *pebs_index; + pebs_record_t *pebs_maximum; + pebs_record_t *pebs_intr; + qword_t pebs_counter; + dword_t __reserved; +}; + +static struct ds_bufmng_area_t bufmng; + + + + +#if defined(CONFIG_X86_P4_BTS) + +/* + * We do not set the DEBUGCTL msr directly since we're not interested + * in keeping track of branches inside the kernel debugger. The + * kernel debugger entry and exit stubs will instead respectively + * disable and enable the tracing feature. This variable is used to + * save the current state of the tracing feature. + */ + +extern dword_t x86_debugctl_state; + +void kdebug_x86_bts (void) +{ + char c; + + c = kdebug_get_choice ("\nBranch Trace Store", "Enable/Disable/Show", 's'); + switch (c) + { + case 'e': + bufmng.bts_base = bufmng.bts_base; + bufmng.bts_index = bufmng.bts_base; + bufmng.bts_maximum = bufmng.bts_base + BTS_SIZE; + zero_memory ((ptr_t) bufmng.bts_base, BTS_BUFSIZE); + x86_debugctl_state |= (1<<3) + (1<<2); /* BTS + TR */ + break; + + case 'd': + x86_debugctl_state &= ~((1<<3) + (1<<2)); + break; + + case 's': + branch_trace_t *bt = bufmng.bts_index; + for (int i = BTS_SIZE-1; i >= 0; i--) + { + if (bt->from != bt->to) + printf ("%4d: %c %p -> %p\n", i, + bt->flags.predicted ? 'P' : ' ', bt->from, bt->to); + if (bt++ == bufmng.bts_maximum) + bt = bufmng.bts_base; + } + break; + } +} + +#endif /* CONFIG_X86_P4_BTS */ + + + + +#if defined(CONFIG_X86_P4_PEBS) + +void kdebug_x86_pebs (void) +{ + char c; + + c = kdebug_get_choice ("\nPrecise Event-Based Sampling", + "Enable/Disable/Show", 's'); + switch (c) + { + case 'e': +// wrmsr (IA32_PEBS_ENABLE, IA32_PEBS_ENABLE_PEBS); + break; + + case 'd': + break; + + case 's': + break; + } +} + +#endif /* CONFIG_X86_P4_PEBS */ + + + + +void init_tracestore (void) +{ +#if defined(CONFIG_X86_P4_BTS) + bufmng.bts_base = (branch_trace_t *) kmem_alloc (BTS_BUFSIZE); + bufmng.bts_index = bufmng.bts_base; + bufmng.bts_maximum = bufmng.bts_base + BTS_SIZE; + bufmng.bts_intr = NULL; +#endif + +#if defined(CONFIG_X86_P4_PEBS) + bufmng.pebs_base = (pebs_record_t *) kmem_alloc (PEBS_BUFSIZE); + bufmng.pebs_index = bufmng.pebs_base; + bufmng.pebs_maximum = bufmng.pebs_base + PEBS_SIZE; + bufmng.pebs_intr = NULL; + bufmng.pebs_counter = 0; +#endif + + wrmsr (IA32_DS_AREA, (dword_t) &bufmng); +} + + +#endif /* CONFIG_X86_P4_BTS || CONFIG_X86_P4_PEBS */ diff --git a/kernel/kdb/x86_tracestore.o b/kernel/kdb/x86_tracestore.o new file mode 100644 index 0000000..e250b45 Binary files /dev/null and b/kernel/kdb/x86_tracestore.o differ diff --git a/kernel/linker/arm.lds b/kernel/linker/arm.lds new file mode 100644 index 0000000..48ee708 --- /dev/null +++ b/kernel/linker/arm.lds @@ -0,0 +1,84 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm.lds + * Description: Common ARM linker script. + * + * @LICENSE@ + * + * $Id: arm.lds,v 1.18 2001/12/13 12:27:26 ud3 Exp $ + * + ********************************************************************/ +ENTRY(_start) + +excp_paddr = KERNEL_PHYS; +text_paddr = excp_paddr; /* We count .excp as text */ + +KERNEL_VIRT = 0xFFFF0000; + +SECTIONS +{ + /* + * Exception vector + fast kernel code (i.e. short ipc). + */ + .excp EXCP_VADDR : AT (KERNEL_PHYS) { + text_vaddr = .; + *(.vect .fiqv .excp) + . = ALIGN(4K); + _end_excp = .; + } + + + /* + * Kernel code and static data. + */ + .text KERNEL_VIRT + SIZEOF(.excp) : AT (KERNEL_PHYS + SIZEOF(.excp)) { + .text = .; + *(.text) + *(.data) + *(.bss) + } + .kdebug . : AT (KERNEL_PHYS + SIZEOF(.excp) + SIZEOF(.text)) { + *(.kdebug) + .rodata = .; + /* all the text strings should go here */ + *(.rodata) + . = ALIGN(4K); + } + + _end_text = .; + KERNEL_SIZE = _end_text - KERNEL_VIRT; + . = KERNEL_PHYS + KERNEL_SIZE; + + . = ALIGN(16K); + kernel_ptdir_p = .; + . = . + 16K; + kernel_pgtable_p = .; + . = . + 1K; + + . = ALIGN(4K); + _end_text_p = .; + + + /* + * Initalization code. Freed after initialization. + * (must reside in a single 1M section) + */ + .init (INIT_PHYS) : AT (INIT_PHYS) { + _start_init = .; + *(.init) + *(.roinit) + . = ALIGN(4K); + _end_init = .; + } + + /DISCARD/ : + { + *(.note) + *(.comment) + *(.glue*) + *(COMMON) + } +} + diff --git a/kernel/linker/brutus.lds b/kernel/linker/brutus.lds new file mode 100644 index 0000000..8459abd --- /dev/null +++ b/kernel/linker/brutus.lds @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: brutus.lds + * Description: Brutus specific includes for linker script. + * + * @LICENSE@ + * + * $Id: brutus.lds,v 1.4 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ + +/* + * Virtual address of exception vector page. REMEMBER TO CHANGE THIS + * IF THE EXCEPTION VECTOR IS NO LONGER RELOCATED! + */ +EXCP_VADDR = 0xFFFF0000; + +/* + * Physical address of all the kernel code+data + * Effectively: physical address of the exception vector. + */ +KERNEL_PHYS = 0xC0000000; + +/* + * Physical address of the init section. + * Should be in a separate 1M section. + */ +INIT_PHYS = 0xC0100000; diff --git a/kernel/linker/dnard.lds b/kernel/linker/dnard.lds new file mode 100644 index 0000000..1a807b4 --- /dev/null +++ b/kernel/linker/dnard.lds @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: dnard.lds + * Description: DNARD specific includes for linker script. + * + * @LICENSE@ + * + * $Id: dnard.lds,v 1.5 2001/12/11 20:19:03 ud3 Exp $ + * + ********************************************************************/ + +/* + * Virtual address of exception vector page. REMEMBER TO CHANGE THIS + * IF THE EXCEPTION VECTOR IS NO LONGER RELOCATED! + */ +EXCP_VADDR = 0x00000000; + +/* + * Physical address of all the kernel code+data + * Effectively: physical address of the exception vector. + */ +KERNEL_PHYS = 0x08000000; + +/* + * Physical address of the init section. + * Should be in a separate 1M section. + */ +INIT_PHYS = 0x0A000000; diff --git a/kernel/linker/ep7211.lds b/kernel/linker/ep7211.lds new file mode 100644 index 0000000..9459c0c --- /dev/null +++ b/kernel/linker/ep7211.lds @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: ep7211.lds + * Description: EP7211 specific includes for linker script. + * + * @LICENSE@ + * + * $Id: ep7211.lds,v 1.5 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ + +/* + * Virtual address of exception vector page. REMEMBER TO CHANGE THIS + * IF THE EXCEPTION VECTOR IS NO LONGER RELOCATED! + */ +EXCP_VADDR = 0xFFFF0000; + +/* + * Physical address of all the kernel code+data + * Effectively: physical address of the exception vector. + */ +KERNEL_PHYS = 0xC0000000; + +/* + * Physical address of the init section. + * Should be in a separate 1M section. + */ +INIT_PHYS = 0xC0100000; diff --git a/kernel/linker/ipaq.lds b/kernel/linker/ipaq.lds new file mode 100644 index 0000000..c4898e9 --- /dev/null +++ b/kernel/linker/ipaq.lds @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: brutus.lds + * Description: Brutus specific includes for linker script. + * + * @LICENSE@ + * + * $Id: ipaq.lds,v 1.1 2002/01/24 07:03:18 uhlig Exp $ + * + ********************************************************************/ + +/* + * Virtual address of exception vector page. REMEMBER TO CHANGE THIS + * IF THE EXCEPTION VECTOR IS NO LONGER RELOCATED! + */ +EXCP_VADDR = 0xFFFF0000; + +/* + * Physical address of all the kernel code+data + * Effectively: physical address of the exception vector. + */ +KERNEL_PHYS = 0xC0000000; + +/* + * Physical address of the init section. + * Should be in a separate 1M section. + */ +INIT_PHYS = 0xC0100000; diff --git a/kernel/linker/mips.lds b/kernel/linker/mips.lds new file mode 100644 index 0000000..93e2565 --- /dev/null +++ b/kernel/linker/mips.lds @@ -0,0 +1,76 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mips.lds + * Description: General MIPS linker script. + * + * @LICENSE@ + * + * $Id: mips.lds,v 1.3 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ +ENTRY(_start) + +tcbs = 0xE0000000; +tcb_start = 0xC0000000; + + +SECTIONS +{ +/* + .init init_addr : AT (init_addr) { + _start_init = .; + *(.init) + *(.roinit) + } > mem_init + . = ALIGN(4K); + _end_init = .; +*/ + .excp excp_vector : AT (excp_vector) + { + *(.excp) + + } + + .text text_vaddr : AT (text_paddr) + { + *(.init) + *(.roinit) + *(.text) + *(.rel.dyn) + *(.reginfo) + *(.mdebug) + } + .data . : AT (text_paddr + SIZEOF(.text)) + { + .data = .; + *(.data) + } + + + .kdebug . : AT (text_paddr + SIZEOF(.text) + SIZEOF(.data)) + { + .rodata = .; + *(.rodata) + .kdebug = .; + *(.kdebug) + } + + .bss . : AT (text_paddr + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.kdebug)) + { + .bss = .; + *(.bss) + } = 0x00000000 + + _end_text = .; + /* . = ALIGN(0x400); */ + _end_text_p = (. - text_vaddr + text_paddr); + + /DISCARD/ : + { + *(.eh_frame) + *(.note) + *(.comment) + } +} diff --git a/kernel/linker/pleb.lds b/kernel/linker/pleb.lds new file mode 100644 index 0000000..b18311c --- /dev/null +++ b/kernel/linker/pleb.lds @@ -0,0 +1,26 @@ +/********************************************************************* + * + * Copyright (C) 2000, University of Karlsruhe + * + * Filename: pleb.lds + * Description: PLEB specific includes for linker script. + * + ********************************************************************/ + +/* + * Virtual address of exception vector page. REMEMBER TO CHANGE THIS + * IF THE EXCEPTION VECTOR IS NO LONGER RELOCATED! + */ +EXCP_VADDR = 0xFFFF0000; + +/* + * Physical address of all the kernel code+data + * Effectively: physical address of the exception vector. + */ +KERNEL_PHYS = 0xC8000000; + +/* + * Physical address of the init section. + * Should be in a separate 1M section. + */ +INIT_PHYS = 0xC8100000; diff --git a/kernel/linker/pr31700.lds b/kernel/linker/pr31700.lds new file mode 100644 index 0000000..ee21b4c --- /dev/null +++ b/kernel/linker/pr31700.lds @@ -0,0 +1,24 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: pr31700.lds + * Description: MIPS pr31700 linker script. + * + * @LICENSE@ + * + * $Id: pr31700.lds,v 1.2 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ + +OUTPUT_FORMAT("elf32-littlemips") + +excp_vector = 0x80000000; +kmem_start = 0x80010000; +kmem_end = 0x80020000; + +text_vaddr = 0x80102000; +text_paddr = text_vaddr; + +init_addr = 0x80020000; + diff --git a/kernel/linker/r4000.lds b/kernel/linker/r4000.lds new file mode 100644 index 0000000..d782e20 --- /dev/null +++ b/kernel/linker/r4000.lds @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: r4000.lds + * Description: MIPS R4000 linker script. + * + * @LICENSE@ + * + * $Id: r4000.lds,v 1.2 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ + +excp_vector = 0x88000000; +kmem_start = 0x88010000; +kmem_end = 0x88020000; + +text_vaddr = 0x88002000; +text_paddr = text_vaddr; + +init_addr = 0x88020000; + + +MEMORY +{ + mem_init : ORIGIN = 0x88020000, LENGTH = 64K + mem_excp : ORIGIN = 0x88000000, LENGTH = 4K + mem_kernel : ORIGIN = 0x88002000, LENGTH = 64K + mem_tcbs : ORIGIN = 0xC0000000, LENGTH = 256M +} diff --git a/kernel/linker/x86.lds b/kernel/linker/x86.lds new file mode 100644 index 0000000..31d7b4b --- /dev/null +++ b/kernel/linker/x86.lds @@ -0,0 +1,80 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86.lds + * Description: Generic linkser script for x86. + * + * @LICENSE@ + * + * $Id: x86.lds,v 1.18 2001/11/22 15:51:36 skoglund Exp $ + * + ********************************************************************/ +ENTRY(_start) + +/* see also include/x86/config.h */ +KERNEL_OFFSET = 0xF0000000; + +text_paddr = 0x00100000 + SIZEOF_HEADERS; +text_vaddr = text_paddr + KERNEL_OFFSET; + +SECTIONS +{ + .text text_vaddr : AT (ADDR(.text) - KERNEL_OFFSET) + { + *(.mb_header) + *(.ipc-s) + *(.ipc-c) + *(.text) + *(.spinlock) + + /* The user-level accessible sysexit trampoline code */ + . = ALIGN(4K); _start_utramp = .; + *(.utramp) + . = ALIGN(4K); _end_utramp = .; + } + .data . : AT (ADDR(.data) - KERNEL_OFFSET) + { + *(.data) + } + .kdebug . : AT (ADDR(.kdebug) - KERNEL_OFFSET) + { + *(.rodata .kdebug) + } + + .bss . : AT (ADDR(.bss) - KERNEL_OFFSET) + { + *(.bss) + } + + /* the .cpulocal section is a per CPU .bss -> NOLOAD */ + .cpulocal ALIGN(4K) (NOLOAD): AT (ADDR(.cpulocal) - KERNEL_OFFSET) + { + _start_cpu_local = .; + *(.cpulocal) + *(.kdebug-bss) + _end_cpu_local = ALIGN(4K); + } + + _end_text = ALIGN(4K); + _end_text_p = (_end_text - KERNEL_OFFSET); + _start_utramp_p = (_start_utramp - KERNEL_OFFSET); + + .init _end_text_p : + { + *(.init .roinit) + } + + /* throw away all other sections */ + + /* + This one also throws away debugging info + /DISCARD/ : { *(*) } + */ + + /DISCARD/ : { + *(.eh_frame) + *(.note) + *(.comment) + } +} diff --git a/kernel/src/.#memory.c.1.20 b/kernel/src/.#memory.c.1.20 new file mode 100644 index 0000000..ff3cb2d --- /dev/null +++ b/kernel/src/.#memory.c.1.20 @@ -0,0 +1,677 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, 2002-2003, Karlsruhe University + * + * File path: memory.c + * Description: Architecture independent multilevel page table + * access functions. + * + * @LICENSE@ + * + * $Id: memory.c,v 1.20 2002/06/07 17:03:41 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#if defined(CONFIG_IO_FLEXPAGES) +#include INC_ARCH(io_mapping.h) +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) +#define USER_LIMIT SMALL_SPACE_START +#else +#define USER_LIMIT TCB_AREA +#endif + + +extern int __kdebug_pf_tracing; + + +/* + * Function sys_fpage_unmap (fpage, mapmask) + * + * The system call interface for fpage_unmap(). + * + */ +void sys_fpage_unmap(fpage_t fpage, dword_t mapmask) +{ + TRACEPOINT_2PAR(SYS_FPAGE_UNMAP, fpage.raw, mapmask); +#if defined(CONFIG_DEBUG_TRACE_SYSCALLS) + printf("%s(%x, %x) - %p\n", __FUNCTION__, fpage.raw, mapmask, + get_current_tcb()); +#endif +#if defined(CONFIG_IO_FLEXPAGES) + + /* Before doing anything related to main memory, check, if send fpage is + * actually a IO-Flexpage + */ + if (EXPECT_FALSE(IOFP_LO_BOUND <= fpage.raw && fpage.raw <= IOFP_HI_BOUND)){ + unmap_io_fpage(get_current_tcb(), fpage, mapmask); + return; + } + +#endif + fpage_unmap(get_current_tcb()->space, fpage, mapmask); +} + + + +/* + * Helper functions. + */ + +static inline dword_t base_mask(fpage_t fp, dword_t num) +{ + return ((~0U) >> (32 - fp.fpage.size)) & ~((~0U) >> (32 - num)); +} + +static inline dword_t address(fpage_t fp, dword_t num) +{ + return fp.raw & ~((~0U) >> (32 - num)); +} + +static inline int is_pgsize_valid (dword_t pgsize) +{ + return (1 << hw_pgshifts[pgsize]) & HW_VALID_PGSIZES; +} + +/* + * the mapping database is made SMP save by a code lock + */ +DEFINE_SPINLOCK(mdb_spinlock); +#define SPIN_LOCK_MDB spin_lock(&mdb_spinlock); +#define SPIN_UNLOCK_MDB spin_unlock(&mdb_spinlock); + + +/* + * Function map_fpage (from, to, base, snd_fp, rcv_fp) + * + * Map/grant a flexpage from one thread to another. + * + */ +int map_fpage(tcb_t *from, tcb_t *to, dword_t base, + fpage_t snd_fp, fpage_t rcv_fp) +{ + dword_t offset, f_addr, t_addr, f_num, t_num; + dword_t pgsize, f_size, t_size; + pgent_t *fpg, *tpg; + mnode_t *newmap, *map; + + pgent_t *r_fpg[HW_NUM_PGSIZES-1], *r_tpg[HW_NUM_PGSIZES-1]; + dword_t r_fnum[HW_NUM_PGSIZES-1], r_tnum[HW_NUM_PGSIZES-1]; +#if defined(CONFIG_SMP) + int tlb_shootdown = 0; +#endif + +#if defined(CONFIG_IO_FLEXPAGES) + + /* + * Before doing anything related to main memory, check, if send fpage is + * actually a IO-Flexpage + */ + if (EXPECT_FALSE(IOFP_LO_BOUND <= snd_fp.raw && snd_fp.raw <= IOFP_HI_BOUND)){ + return map_io_fpage(from, to, snd_fp); + } + +#endif +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("map_fpage(sender=%p, receiver=%p, base=%x, " + "sndfp=%x, rcvfp=%x)\n", from, to, base, + snd_fp.raw, rcv_fp.raw); + } +#endif + + /* + * Calculate the actual send and receive address to use. This is + * almost magic. Please THINK before you consider changing this. + */ + if ( snd_fp.fpage.size <= rcv_fp.fpage.size ) + { + f_num = snd_fp.fpage.size; + base &= base_mask(rcv_fp, f_num); + f_addr = address(snd_fp, f_num); + t_addr = (address(rcv_fp, f_num) & ~base_mask(rcv_fp, f_num)) + base; + } + else + { + enter_kdebug("map_fpage(): Larger send window"); + return 0; + } + + if ( f_num < hw_pgshifts[0] ) + { + enter_kdebug("map_fpage(): Invalid fpage size"); + return 0; + } + + /* + * Setting bit 0 in the from address indicates to mdb_map() that + * we are doing a grant operation. + */ + if ( snd_fp.fpage.grant ) + f_addr |= 0x1; + + + /* + * Find pagesize to use, and number of pages to map. + */ + for (pgsize = HW_NUM_PGSIZES-1; + (hw_pgshifts[pgsize] > f_num) || (!is_pgsize_valid (pgsize)); + pgsize--) {} + f_num = t_num = 1 << (f_num - hw_pgshifts[pgsize]); + f_size = t_size = HW_NUM_PGSIZES-1; + + fpg = from->space->pgent (table_index (f_addr, f_size)); + tpg = to->space->pgent (table_index (t_addr, t_size)); + + SPIN_LOCK_MDB; + + while ( f_num > 0 || t_num > 0 ) + { + if ( (f_addr >= USER_LIMIT && from != sigma0) || t_addr >= USER_LIMIT ) + { + /* Do not mess with the kernel area. */ + break; + } + + if ( from == sigma0 ) + { + /* + * When mapping from sigma0 we bypass the page table lookup. + */ + f_size = pgsize; + } + else + { + if ( !fpg->is_valid(from->space, f_size) ) + { + while ( t_size < f_size ) + { + /* Recurse up. */ + tpg = r_tpg[t_size]; + t_num = r_tnum[t_size]; + t_size++; + } + + if ( t_size == f_size ) + goto Next_receiver_entry; + + /* t_size > f_size */ + goto Next_sender_entry; + } + + if ( (f_size > pgsize) && fpg->is_subtree(from->space, f_size) ) + { + /* + * We are currently working on to large page sizes. + */ + f_size--; + fpg = fpg->subtree (from->space, f_size+1)->next + (from->space, table_index(f_addr, f_size), f_size); + continue; + } + else if ( fpg->is_subtree(from->space, f_size) ) + { + /* + * The mappings in the senders address space are to small. + * We have to map each single entry in the subtree. + */ + f_size--; + r_fpg[f_size] = fpg->next(from->space, 1, f_size+1); + r_fnum[f_size] = f_num - 1; + + fpg = fpg->subtree(from->space, f_size+1); + f_num = table_size(f_size); + continue; + } + else if ( f_size > pgsize ) + { + f_num = 1; + } + } + + /* + * If we get here `fpg' is a valid mapping in the senders + * address space. + */ + + + if ( (t_size > f_size) || ((t_size > pgsize) && (f_size > pgsize)) ) + { + /* + * We are currently working on larger receive pages than + * send pages. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + + if ( !tpg->is_valid(to->space, t_size+1) ) + { + /* + * Subtree does not exist. Create one. + */ + tpg->make_subtree(to->space, t_size+1); + } + else if ( !tpg->is_subtree(to->space, t_size+1) ) + { + /* + * There alredy exists a larger mapping. Just + * continue. BEWARE: This may cause extension of + * access rights to be refused even though they are + * perfectly legal. I.e. if all the mappings in the + * subtree of the sender's address space are valid. + */ + printf("map_fpage(): Larger mapping already exists.\n"); + enter_kdebug(); + goto Next_receiver_entry; + } + + if ( t_size >= pgsize ) + { + tpg = tpg->subtree (to->space, t_size+1)->next + (to->space, table_index(t_addr, t_size), t_size); + continue; + } + else + { + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + } + + /* Adjust destination according to where source is located. */ + tpg = tpg->next(to->space, table_index(f_addr, t_size), t_size); + t_num -= table_index(f_addr, t_size); + t_addr += table_index(f_addr, t_size) << hw_pgshifts[t_size]; + continue; + } + else if ( tpg->is_valid(to->space, t_size) && + tpg->is_subtree(to->space, t_size) ) + { + /* + * Target mappings are of smaller page size. We have to + * map each single entry in the subtree. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + } + else if ( !is_pgsize_valid (t_size) ) + { + /* + * Pagesize is ok but is not a valid hardware pagesize. + * Need to create mappings of smaller size. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + tpg->make_subtree(to->space, t_size+1); + + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + continue; + } + + + /* + * If we get here `tpg' will be the page table entry that we + * are going to change. + */ + + offset = f_addr & page_mask(f_size) & ~page_mask(t_size); + + if ( tpg->is_valid(to->space, t_size) ) + { + /* + * If a mapping already exists, it might be that we are + * just extending the current access rights. + */ + if ( (from == sigma0) ? (tpg->address(to->space, t_size) != f_addr) : + (tpg->address(to->space, t_size) != + fpg->address(from->space, f_size) + offset) ) + { + printf("map_fpage(sender=%p, receiver=%p, base=%x, " + "sndfp=%x, rcvfp=%x)\n", from, to, base, + snd_fp.raw, rcv_fp.raw); + enter_kdebug("map_fpage(): Mapping already exists."); + goto Next_receiver_entry; + } + + /* Extent access rights. */ + if ( (fpg->is_writable(from->space, t_size) || from == sigma0) && + snd_fp.fpage.write ) + { + tpg->set_writable(to->space, t_size); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (to->space->is_small ()) + flush_tlbent ((ptr_t) (t_addr + + to->space->smallid ().offset ())); + else if (from->space->is_small ()) + flush_tlbent((ptr_t) t_addr); +#endif +#if defined(CONFIG_SMP) + tlb_shootdown = 1; +#endif + } + } + else + { + /* + * This is where the real work is done. + */ + + if ( from == sigma0 ) + { + /* + * If mapping from sigma0, fpg will not be a valid + * page table entry. + */ +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("paddr=%p mdb_map(from=sigma0,4G,%p, " + "to=%p,%dk,%p)\n", + f_addr, f_addr, (dword_t) to->space, + 1 << (hw_pgshifts[t_size] - 10), t_addr); + if ( __kdebug_mdb_tracing > 1 ) + enter_kdebug("mdb_map"); + } +#endif + + newmap = mdb_map(sigma0_mapnode, fpg, HW_NUM_PGSIZES, + f_addr + offset, tpg, t_size, + to->space); + + tpg->set_entry(to->space, f_addr, snd_fp.fpage.write, t_size); + tpg->set_mapnode(to->space, t_size, newmap, t_addr); + +#if defined(CONFIG_CACHEABILITY_BITS) + if (snd_fp.fpage.uncacheable) + tpg->set_uncacheable(to->space, t_size); + if (snd_fp.fpage.unbufferable) + tpg->set_unbufferable(to->space, t_size); +#endif + } + else + { +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("mdb_map(paddr=%p, from=%p,%dK,%p, to=%p,%dk,%p)\n", + fpg->address(from->space, f_size) + offset, + (dword_t) from->space, + 1 << (hw_pgshifts[f_size] - 10), + f_addr, to->space, + 1 << (hw_pgshifts[t_size] - 10), t_addr); + if ( __kdebug_mdb_tracing > 1 ) + enter_kdebug("mdb_map"); + } +#endif + + map = fpg->mapnode(from->space, f_size, + f_addr & ~page_mask(f_size)); + + // Make sure that we are not flushed. + while ( ! map->up_trylock() ) + if ( ! fpg->is_valid(from->space, f_size) ) + goto Next_receiver_entry; + else + enter_kdebug("map_fpage: waiting for uplock"); + + newmap = mdb_map(map, fpg, f_size, f_addr, tpg, t_size, + to->space); + + tpg->set_entry(to->space, + fpg->address(from->space, f_size) + offset, + fpg->is_writable(from->space, f_size) && + snd_fp.fpage.write, + t_size); + tpg->set_mapnode(to->space, t_size, newmap, t_addr); + +#if defined(CONFIG_CACHEABILITY_BITS) + if (snd_fp.fpage.uncacheable) + tpg->set_uncacheable(to->space, t_size); + if (snd_fp.fpage.unbufferable) + tpg->set_unbufferable(to->space, t_size); +#endif + + if ( f_addr & 0x1 ) + { + /* Grant operation. Remove mapping from current space. */ + fpg->clear(from->space, f_size); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (from->space->is_small ()) + flush_tlbent ((ptr_t) (f_addr + from->space->smallid + ().offset ())); + else +#endif + flush_tlbent((ptr_t) f_addr); + } + newmap->up_unlock(); + map->up_unlock(); + } + } + + Next_receiver_entry: + + t_addr += page_size(t_size); + t_num--; + + if ( t_num > 0 ) + { + /* Go to next entry */ + tpg = tpg->next(to->space, 1, t_size); + if ( t_size < f_size ) + continue; + } + else if ( t_size < f_size && f_size < pgsize ) + { + /* Recurse up */ + tpg = r_tpg[t_size]; + t_num = r_tnum[t_size]; + t_size++; + continue; + } + else if ( t_size > f_size ) + { + /* Skip to next fpg entry. Happens if tpg is already mapped. */ + f_addr += page_size(t_size) - page_size(f_size); + f_num = 1; + } + + Next_sender_entry: + + f_addr += page_size(f_size); + f_num--; + + if ( f_num > 0 ) + { + /* Go to next entry */ + if ( from != sigma0 ) + fpg = fpg->next(from->space, 1, f_size); + continue; + } + else if ( f_size < pgsize ) + { + /* Recurse up */ + fpg = r_fpg[f_size]; + f_num = r_fnum[f_size]; + f_size++; + } + else + { + /* Finished */ + t_num = 0; + } + } + SPIN_UNLOCK_MDB; +#if defined (CONFIG_SMP) + if (tlb_shootdown) + smp_flush_tlb(); +#endif + return 1; +} + + +/* + * Function fpage_unmap (space, fpage, mapmask) + * + * Unmap FPAGE from SPACE. MAPMASK indicates whether to flush or + * remap, and if current pgdir should also be flushed. + * + */ +void fpage_unmap(space_t *space, fpage_t fpage, dword_t mapmask) +{ + dword_t vaddr, num, size, pgsize; + pgent_t *pg; + mnode_t *map; + int r; + + pgent_t *r_pg[HW_NUM_PGSIZES-1]; + dword_t r_num[HW_NUM_PGSIZES-1]; +#if defined(CONFIG_SMP) + int tlb_shootdown = 0; +#endif + +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("fpage_unmap(%x, %x, %x)\n", space, fpage.raw, mapmask); + } +#endif + + num = fpage.fpage.size; + vaddr = address(fpage, num); + + if ( num < hw_pgshifts[0] ) + { + printf("map_fpage(): Invalid fpage size (%d).\n", num); + enter_kdebug(); + return; + } + + /* + * Find pagesize to use, and number of pages to map. + */ + for (pgsize = HW_NUM_PGSIZES-1; + (hw_pgshifts[pgsize] > num) || (!is_pgsize_valid (pgsize)); + pgsize-- ) {} + num = 1 << (num - hw_pgshifts[pgsize]); + + size = HW_NUM_PGSIZES-1; + pg = space->pgent (table_index (vaddr, size)); + + SPIN_LOCK_MDB; + + while ( num ) + { + if ( vaddr >= USER_LIMIT ) + /* Do not mess with the kernel area. */ + break; + + if ( size > pgsize ) + { + /* We are operating on to large page sizes. */ + if ( ! pg->is_valid(space, size) ) + break; + else if ( pg->is_subtree(space, size) ) + { + size--; + pg = pg->subtree(space, size+1)->next + (space, table_index(vaddr, size), size); + continue; + } + else if ( mapmask & MDB_ALL_SPACES ) + { + printf("fpage_unmap(%x, %x, %x)\n", space, fpage.raw, mapmask); + enter_kdebug("fpage_unmap: page is to large"); + break; + } + } + + if ( ! pg->is_valid(space, size) ) + goto Next_entry; + + if ( pg->is_subtree(space, size) ) + { + /* We have to flush each single page in the subtree. */ + size--; + r_pg[size] = pg; + r_num[size] = num - 1; + + pg = pg->subtree(space, size+1); + num = table_size(size); + continue; + } + +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("mdb_flush(space=%p, vaddr=%p, %dK:%p, %dk:%p, mode=%p)\n", + space, vaddr, + 1 << (hw_pgshifts[size] - 10), + pg->address(space, size), + 1 << (hw_pgshifts[pgsize] - 10), + pg->address(space, size) + (vaddr & page_mask(size)), + mapmask); + if ( __kdebug_mdb_tracing > 1) + enter_kdebug("mdb_flush"); + } +#endif + map = pg->mapnode(space, size, vaddr & ~page_mask(size)); + + // Make sure that we are not flushed. + while ( ! map->up_trylock() ) + if ( ! pg->is_valid(space, size) ) + goto Next_entry; + else + enter_kdebug("fpage_unmap: waiting for uplock"); + + r = mdb_flush(pg->mapnode(space, size, vaddr & ~page_mask(size)), + pg, size, vaddr, pgsize, mapmask); + if ( r == -1 ) + enter_kdebug("fpage_unmap: page already flushed"); +#if defined(CONFIG_SMP) + else + tlb_shootdown |= r; +#endif + Next_entry: + + pg = pg->next(space, 1, size); + vaddr += page_size(size); + num--; + + if ( num == 0 && size < pgsize ) + { + /* Recurse up */ + pg = r_pg[size]; + num = r_num[size]; + size++; + + if ( (mapmask & MDB_ALL_SPACES) && (mapmask & MDB_FLUSH) ) + pg->remove_subtree(space, size); + pg = pg->next(space, 1, size); + } + } + SPIN_UNLOCK_MDB; +#if defined(CONFIG_SMP) + smp_flush_tlb(); +#endif +} + + + + + + + + + + + diff --git a/kernel/src/.cvsignore b/kernel/src/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/.depend b/kernel/src/.depend new file mode 100644 index 0000000..bdeb27e --- /dev/null +++ b/kernel/src/.depend @@ -0,0 +1,99 @@ +mapping.o: mapping.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/mapping.h ../include/init.h +mapping_alloc.o: mapping_alloc.c ../include/universe.h \ + ../include/config.h ../include/macros.h ../include/types.h \ + ../include/kernel.h ../include/x86/config.h ../include/x86/cpu.h \ + ../include/lib.h ../include/sync.h ../include/x86/notify.h \ + ../include/kmemory.h ../include/thread.h ../include/ipc.h \ + ../include/tcb.h ../include/x86/tcb.h ../include/schedule.h \ + ../include/interrupt.h ../include/x86/memory.h ../include/x86/mapping.h \ + ../include/x86/space.h ../include/x86/thread.h ../include/tcb_layout.h \ + ../include/kdebug.h ../include/x86/kdebug.h ../include/mapping.h \ + ../include/init.h +init.o: init.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/init.h +kmemory.o: kmemory.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/init.h +thread.o: thread.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/init.h ../include/tracepoints.h \ + ../include/tracebuffer.h ../include/tracepoint_list.h \ + ../include/x86/syscalls.h ../include/x86/io_mapping.h +schedule.o: schedule.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/init.h ../include/tracepoints.h \ + ../include/tracebuffer.h ../include/tracepoint_list.h \ + ../include/x86/syscalls.h +ipc.o: ipc.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/init.h ../include/tracepoints.h \ + ../include/tracebuffer.h ../include/tracepoint_list.h \ + ../include/x86/syscalls.h +memory.o: memory.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h ../include/mapping.h ../include/tracepoints.h \ + ../include/tracebuffer.h ../include/tracepoint_list.h \ + ../include/x86/io_mapping.h +global.o: global.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h +lib.o: lib.c ../include/universe.h ../include/config.h \ + ../include/macros.h ../include/types.h ../include/kernel.h \ + ../include/x86/config.h ../include/x86/cpu.h ../include/lib.h \ + ../include/sync.h ../include/x86/notify.h ../include/kmemory.h \ + ../include/thread.h ../include/ipc.h ../include/tcb.h \ + ../include/x86/tcb.h ../include/schedule.h ../include/interrupt.h \ + ../include/x86/memory.h ../include/x86/mapping.h ../include/x86/space.h \ + ../include/x86/thread.h ../include/tcb_layout.h ../include/kdebug.h \ + ../include/x86/kdebug.h diff --git a/kernel/src/Makefile b/kernel/src/Makefile new file mode 100644 index 0000000..bec6a8a --- /dev/null +++ b/kernel/src/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.18 2001/11/22 13:40:29 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +OBJ_SRC = +LIB_SRC = mapping.c mapping_alloc.c init.c kmemory.c thread.c schedule.c ipc.c \ + memory.c global.c lib.c +LIB = libkernel.a + +###################################################################### +# includes +include ../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/.cvsignore b/kernel/src/arm/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/arm/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/arm/.depend b/kernel/src/arm/.depend new file mode 100644 index 0000000..1e55819 --- /dev/null +++ b/kernel/src/arm/.depend @@ -0,0 +1,75 @@ +farcalls.o: farcalls.c ../../include/universe.h ../../include/config.h \ + ../../include/macros.h ../../include/types.h ../../include/kernel.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/lib.h ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h +init.o: init.c ../../include/universe.h ../../include/config.h \ + ../../include/macros.h ../../include/types.h ../../include/kernel.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/lib.h ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h ../../include/arm/farcalls.h +memory.o: memory.c ../../include/universe.h ../../include/config.h \ + ../../include/macros.h ../../include/types.h ../../include/kernel.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/lib.h ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h ../../include/mapping.h \ + ../../include/arm/syscalls.h ../../include/arm/farcalls.h \ + ../../include/tracepoints.h ../../include/tracebuffer.h \ + ../../include/tracepoint_list.h +exception.o: exception.S ../../include/config.h ../../include/macros.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/arm/syscalls.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h +kmemory.o: kmemory.c ../../include/universe.h ../../include/config.h \ + ../../include/macros.h ../../include/types.h ../../include/kernel.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/lib.h ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h +mapping.o: mapping.c ../../include/universe.h ../../include/config.h \ + ../../include/macros.h ../../include/types.h ../../include/kernel.h \ + ../../include/arm/config.h ../../include/arm/dnard/platform.h \ + ../../include/lib.h ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h ../../include/mapping.h +resources.o: resources.c ../../include/universe.h \ + ../../include/config.h ../../include/macros.h ../../include/types.h \ + ../../include/kernel.h ../../include/arm/config.h \ + ../../include/arm/dnard/platform.h ../../include/lib.h \ + ../../include/sync.h ../../include/arm/notify.h \ + ../../include/kmemory.h ../../include/thread.h ../../include/ipc.h \ + ../../include/tcb.h ../../include/arm/tcb.h ../../include/schedule.h \ + ../../include/interrupt.h ../../include/arm/cpu.h \ + ../../include/arm/dnard/cpu.h ../../include/arm/memory.h \ + ../../include/arm/mapping.h ../../include/arm/thread.h \ + ../../include/arm/space.h ../../include/kdebug.h \ + ../../include/arm/kdebug.h ../../include/tracepoints.h \ + ../../include/tracebuffer.h ../../include/tracepoint_list.h diff --git a/kernel/src/arm/Makefile b/kernel/src/arm/Makefile new file mode 100644 index 0000000..bbb9ad5 --- /dev/null +++ b/kernel/src/arm/Makefile @@ -0,0 +1,31 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arm/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.10 2001/12/07 19:09:18 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libarch.a +OBJ_SRC = +LIB_SRC = farcalls.c init.c memory.c exception.S kmemory.c mapping.c \ + resources.c + + +###################################################################### +# includes +include ../../Makeconf $(wildcard .depend) + + + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/brutus/.cvsignore b/kernel/src/arm/brutus/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/arm/brutus/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/arm/brutus/Makefile b/kernel/src/arm/brutus/Makefile new file mode 100644 index 0000000..f43b4bb --- /dev/null +++ b/kernel/src/arm/brutus/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arm/brutus/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.11 2001/11/22 13:18:49 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c interrupt.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/brutus/init.c b/kernel/src/arm/brutus/init.c new file mode 100644 index 0000000..78c87a9 --- /dev/null +++ b/kernel/src/arm/brutus/init.c @@ -0,0 +1,154 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/init.c + * Description: Brutus specific initalization functions. + * + * @LICENSE@ + * + * $Id: init.c,v 1.12 2001/12/13 00:11:00 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(memory.h) +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + +void setup_kernel_pgtable(void) L4_SECT_INIT; +void init_platform(void) L4_SECT_INIT; +void init_timer(void) L4_SECT_INIT; +void init_irqs(void) L4_SECT_INIT; + + +extern dword_t _start_init[]; +extern dword_t text_paddr[]; +extern dword_t text_vaddr[]; + + +/* + * Function setup_kernel_pgtable () + * + * Create initial pagetable. This should contain everything we + * need in order to run the kernel. When the function returns, it + * should be safe to enable the MMU. + * + */ +void setup_kernel_pgtable(void) +{ + dword_t i; + fld_section_t *segment; + fld_page_t *page; + sld_largepage_t *large_page; + sld_smallpage_t *small_page; + + /* Zero out 1st Level Array */ + for(i = 0; i < FLD_MAX; i++) + kernel_ptdir_p[i].init = 0; + + /* + * Map in Init segment + */ + segment = (fld_section_t *) kernel_ptdir_p + + vaddr_to_fld((dword_t) _start_init); + segment->type = FLD_SECTION; /* 1st level segment entry */ + segment->ap = AP_NOACCESS; /* Kernel access only */ + segment->sba = paddr_to_sba((dword_t) _start_init); /* Address of 1MB Fr */ + + /* + * Map in Text segment + */ + + /* Add 1st level entry */ + page = (fld_page_t *) kernel_ptdir_p + vaddr_to_fld((dword_t) text_vaddr); + page->type = FLD_PAGE; + page->ptba = paddr_to_ptba((dword_t) kernel_pgtable_p); + + /* Zero out 2nd level array */ + for(i = 0; i < SLD_MAX; i++) + kernel_pgtable_p[i].init = 0; + + /* Add 2nd level entry */ + large_page = (sld_largepage_t *) kernel_pgtable_p + + vaddr_to_sld(0xFFFF0000 & (dword_t) text_vaddr); + large_page->type = SLD_LARGE; + large_page->buf = TRUE; + large_page->cache = TRUE; + large_page->ap0 = AP_NOACCESS; + large_page->ap1 = AP_NOACCESS; + large_page->ap2 = AP_NOACCESS; + large_page->ap3 = AP_NOACCESS; + large_page->lpba = paddr_to_lpba(0xFFFF0000 & (dword_t) text_paddr); + + /* Copy entry (required for large pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + /* + * Map in Interrupt Controller registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(INTCTRL_VBASE); + small_page->type = SLD_SMALL; + small_page->ap0 = AP_NOACCESS; + small_page->ap1 = AP_NOACCESS; + small_page->ap2 = AP_NOACCESS; + small_page->ap3 = AP_NOACCESS; + small_page->spba = paddr_to_spba(INTCTRL_PBASE); + + /* + * Map in OS Timer registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(OSTIMER_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(OSTIMER_PBASE); + + /* + * Map in UART Serial Port registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(UART_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(UART_PBASE); + small_page->ap0 = AP_ALLACCESS; + small_page->ap1 = AP_ALLACCESS; + small_page->ap2 = AP_ALLACCESS; + small_page->ap3 = AP_ALLACCESS; + + /* + * Map in GPIO registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(GPIO_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(GPIO_PBASE); + + /* + * Map Reset Controller Registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(RSTCTL_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(RSTCTL_PBASE); + + /* Map in Contiguous RAM */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld(cpaddr); +#if ((cpaddr + PHYS_DRAMSIZE) < cpaddr) +#error: Too much memory +#endif + for (i = cpaddr; i < cpaddr+DRAM_SIZE; i+=0x100000) /* in steps of 1M */ + { + segment->sba = paddr_to_sba(virt_to_phys(i)); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment++; + }; +} + + +void init_platform() +{ + init_irqs(); + init_timer(); +} diff --git a/kernel/src/arm/brutus/interrupt.c b/kernel/src/arm/brutus/interrupt.c new file mode 100644 index 0000000..35b31ee --- /dev/null +++ b/kernel/src/arm/brutus/interrupt.c @@ -0,0 +1,122 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/interrupt.c + * Description: Brutus specific interrupt/timer stuff. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.9 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include + +#include +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + + +void init_irqs(void) L4_SECT_INIT; +void init_timer() L4_SECT_INIT; + + +/* + * Function init_irqs () + * + * Initialize interrupt handling for the SA-1100. + * + */ +void init_irqs(void) +{ + /* + * Set all interrupts to generate IRQs rather than FIQs. + */ + ICLR = 0x00000000; + + /* + * Only enabled and unmasked interrupts will bring CPU out of idle + * mode. + */ + ICCR = 1; + + /* + * Acknowledge any pending interrupts. + */ + ICIP = 0xffffffff; + ICFP = 0xffffffff; + + /* + * Enable interrupts from ostimer0. + */ + ICMR = INTR_OSTIMER0; +} + + +/* + * Function init_timer () + * + * Initialize the SA-1100 operating system timer. + * + */ +void init_timer(void) +{ + /* Clear all OS-timer matches */ + OSSR = 0x0f; + + /* Acknowledge pending OS Timer 0 interrupt */ + ICIP = INTR_OSTIMER0; + + /* Enable OS Timer 0 */ + OIER = 0x01; + + OSMR0 = OSCR + (18432000 >> 2); /* Wait 5/4 sec */ +} + + +void irq_handler(dword_t spsr) +{ + dword_t m, i, icip = ICIP; + + if ( icip & INTR_OSTIMER0 ) + { +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('T'); +#endif + + OSMR0 = OSCR + (CLOCK_FREQUENCY/1024) * (TIME_QUANTUM/1024); + + OSSR = 0x01; + ICIP = INTR_OSTIMER0; + + handle_timer_interrupt(); + return; + } + + for ( i = 31, m = 0x8000000U; (~icip & m) && m; m >>= 1, i-- ) + ; + +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('0'+i); +#endif + + if ( m == 0 ) + { + printf("No interrupt pending\n"); + enter_kdebug(); + return; + } + + handle_interrupt(i); +} + + +void mask_interrupt(dword_t num) +{ + ICMR = ICMR & ~(1 << num); +} + +void unmask_interrupt(unsigned int number) +{ + // do nothing - no automatic irq acking??? +} diff --git a/kernel/src/arm/brutus/startup.S b/kernel/src/arm/brutus/startup.S new file mode 100644 index 0000000..e2a1bd4 --- /dev/null +++ b/kernel/src/arm/brutus/startup.S @@ -0,0 +1,61 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/brutus/startup.S + * Description: Startup code for the Brutus. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.10 2001/12/13 12:23:36 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_PLATFORM(platform.h) +#include INC_ARCH(cpu.h) + + .globl _start + .section .init,"xa" +_start: + /* Switch to abort mode */ + mov r0, #(IRQ_MASK|FIQ_MASK|KERNEL_MODE) + msr cpsr, r0 + + /* reset spsr */ + mov r0, #0xd3 + msr spsr, r0 + + /* Initialize stack pointer */ + ldr sp, 5f + + /* Build the initial page table */ + bl setup_kernel_pgtable__Fv + + /* Enable the MMU */ + ldr r0, 1f + mcr p15, 0, r0, c2, c0 @ Set Translation Table Base + mov r0, #0x00000005 + mcr p15, 0, r0, c3, c0 @ Access checking for Domain 1 + ldr r0, 2f + mcr p15, 0, r0, c1, c0 @ Enable the MMU + nop + nop + nop + + /* Call init() */ + ldr pc, 4f + +1: .word kernel_ptdir_p +#ifdef EXCEPTION_VECTOR_RELOCATED +2: .word (CTL_MMU_ENABLED | CTL_ICACHE | CTL_DCACHE | CTL_WRITE_BUF | CTL_SYS_PROT | CTL_IVECTOR) +#else +2: .word (CTL_MMU_ENABLED | CTL_SYS_PROT) +#endif +3: .word kernel_ptdir +4: .word init__Fv +5: .word _stack_top + + /* Initializtation stack */ +_stack_bottom: + .space 4096 +_stack_top: diff --git a/kernel/src/arm/dnard/.cvsignore b/kernel/src/arm/dnard/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/arm/dnard/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/arm/dnard/.depend b/kernel/src/arm/dnard/.depend new file mode 100644 index 0000000..6a119b9 --- /dev/null +++ b/kernel/src/arm/dnard/.depend @@ -0,0 +1,29 @@ +startup.o: startup.S ../../../include/macros.h \ + ../../../include/arm/cpu.h ../../../include/arm/dnard/cpu.h +init.o: init.c ../../../include/universe.h ../../../include/config.h \ + ../../../include/macros.h ../../../include/types.h \ + ../../../include/kernel.h ../../../include/arm/config.h \ + ../../../include/arm/dnard/platform.h ../../../include/lib.h \ + ../../../include/sync.h ../../../include/arm/notify.h \ + ../../../include/kmemory.h ../../../include/thread.h \ + ../../../include/ipc.h ../../../include/tcb.h \ + ../../../include/arm/tcb.h ../../../include/schedule.h \ + ../../../include/interrupt.h ../../../include/arm/cpu.h \ + ../../../include/arm/dnard/cpu.h ../../../include/arm/memory.h \ + ../../../include/arm/mapping.h ../../../include/arm/thread.h \ + ../../../include/arm/space.h ../../../include/kdebug.h \ + ../../../include/arm/kdebug.h ../../../include/arm/farcalls.h +interrupt.o: interrupt.c ../../../include/universe.h \ + ../../../include/config.h ../../../include/macros.h \ + ../../../include/types.h ../../../include/kernel.h \ + ../../../include/arm/config.h ../../../include/arm/dnard/platform.h \ + ../../../include/lib.h ../../../include/sync.h \ + ../../../include/arm/notify.h ../../../include/kmemory.h \ + ../../../include/thread.h ../../../include/ipc.h \ + ../../../include/tcb.h ../../../include/arm/tcb.h \ + ../../../include/schedule.h ../../../include/interrupt.h \ + ../../../include/arm/cpu.h ../../../include/arm/dnard/cpu.h \ + ../../../include/arm/memory.h ../../../include/arm/mapping.h \ + ../../../include/arm/thread.h ../../../include/arm/space.h \ + ../../../include/kdebug.h ../../../include/arm/kdebug.h \ + ../../../include/arm/farcalls.h diff --git a/kernel/src/arm/dnard/Makefile b/kernel/src/arm/dnard/Makefile new file mode 100644 index 0000000..77ae6e1 --- /dev/null +++ b/kernel/src/arm/dnard/Makefile @@ -0,0 +1,29 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arm/dnard/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.8 2001/11/22 13:18:49 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c interrupt.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/dnard/init.c b/kernel/src/arm/dnard/init.c new file mode 100644 index 0000000..6119d63 --- /dev/null +++ b/kernel/src/arm/dnard/init.c @@ -0,0 +1,167 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/dnard/init.c + * Description: Dnard specific initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.17 2001/12/11 23:38:28 ud3 Exp $ + * + ********************************************************************/ +#include + +#include INC_ARCH(cpu.h) +#include INC_ARCH(memory.h) +#include INC_ARCH(farcalls.h) + +#include INC_PLATFORM(platform.h) + +void setup_kernel_pgtable(void) L4_SECT_INIT; + +void init_platform() L4_SECT_INIT; +void init_timer() L4_SECT_INIT; +/* from arm/dnard/interrupt.c */ +void init_irqs() L4_SECT_INIT; + +extern word_t _start_init[]; + +extern word_t text_vaddr[]; +extern word_t text_paddr[]; +extern word_t excp_vaddr[]; +extern word_t excp_paddr[]; + + +void setup_kernel_pgtable() +{ + Flush_ID_Cache(); + + dword_t i; + fld_section_t *segment; + fld_page_t *page; + sld_largepage_t *large_page; + sld_smallpage_t *small_page; + + /* Zero out 1st Level Array */ + for(i = 0; i < FLD_MAX; i++) + kernel_ptdir_p[i].init = 0; + + /* Map in Init Segment */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld((dword_t)_start_init); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment->sba = paddr_to_sba((dword_t)_start_init); /* Address of 1MB Frame */ + + /* Map in Text Segment */ + /* Add 1st Level Entry */ + page = (fld_page_t *)kernel_ptdir_p + vaddr_to_fld(KERNEL_VIRT); + page->type = FLD_PAGE; + page->ptba = paddr_to_ptba((dword_t)kernel_pgtable_p); + + /* Zero out 2nd Level Array */ + for(i = 0; i < SLD_MAX; i++) + kernel_pgtable_p[i].init = 0; + + /* Add 2nd Level Entry */ + large_page = (sld_largepage_t *)kernel_pgtable_p + + vaddr_to_sld(KERNEL_VIRT); + large_page->type = SLD_LARGE; + large_page->buf = TRUE; + large_page->cache = TRUE; + large_page->ap0 = AP_NOACCESS; + large_page->ap1 = AP_NOACCESS; + large_page->ap2 = AP_NOACCESS; + large_page->ap3 = AP_NOACCESS; + large_page->lpba = paddr_to_lpba((dword_t) excp_paddr); + + /* Copy Entry (Required for Large Pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + /* Map in I/O */ + small_page = (sld_smallpage_t *)kernel_pgtable_p + + vaddr_to_sld(IO_VBASE); + small_page->type = SLD_SMALL; + small_page->ap0 = AP_ALLACCESS; /* THIS IS ACCESSIBLE FROM USER MODE TOO */ + small_page->ap1 = AP_NOACCESS; + small_page->ap2 = AP_NOACCESS; + small_page->ap3 = AP_NOACCESS; + small_page->spba = paddr_to_spba(IO_PBASE); + + /* Map in Contiguous RAM */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld(cpaddr); +#if ((cpaddr + PHYS_DRAMSIZE) < cpaddr) +#error: Too much memory +#endif + for (i = cpaddr; i < cpaddr+DRAM_SIZE; i+=0x100000) /* in steps of 1M */ + { + segment->sba = paddr_to_sba(virt_to_phys(i)); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment++; + }; + Flush_ID_Cache(); +} + + +#warning REVIEWME + + +void init_timer() +{ + /* wait while update in progress */ + while(in_rtc(0x0a) & 0x80); + + out_rtc(0x0a, (in_rtc(0x0a) & 0xF0) | 0x07); + out_rtc(0x0b, in_rtc(0x0b) | 0x48); + + /* reset timer intr line */ + in_rtc(0x0c); + + printf("%s\n", __FUNCTION__); +} + + + + +void init_platform() +{ + printf("%s\n", __FUNCTION__); + init_irqs(); + init_timer(); + printf("%s done\n", __FUNCTION__); +}; + + + + +#if 0 + +/* Map in Sigma0's one-one Address Space */ +void +setup_sigma0_mappings() +{ + dword_t i; + fld_section_t *segment; + + /* Map in DRAM Banks (less kernel regions, First 2MB), + 0x08200000 - 0x0E7FFFFF */ + segment = (fld_section_t *)kernel_ptdir + vaddr_to_fld(0x08200000); + for(i = 0x08200000; + i < 0x0E800000; + i += 0x00100000, segment++) { + segment->type = FLD_SECTION; + segment->domain = USER_DOMAIN; + segment->ap = AP_ALLACCESS; + segment->sba = vaddr_to_fld(i); + } + /* Map in I/O Registers at 0x40000000 - 0x40FFFFFF */ + segment = (fld_section_t *)kernel_ptdir + vaddr_to_fld(0x40000000); + segment->type = FLD_SECTION; + segment->domain = USER_DOMAIN; + segment->ap = AP_ALLACCESS; + segment->sba = vaddr_to_fld(0x40000000); +} + +#endif diff --git a/kernel/src/arm/dnard/init.o b/kernel/src/arm/dnard/init.o new file mode 100644 index 0000000..6aa5f25 Binary files /dev/null and b/kernel/src/arm/dnard/init.o differ diff --git a/kernel/src/arm/dnard/interrupt.c b/kernel/src/arm/dnard/interrupt.c new file mode 100644 index 0000000..5315b4c --- /dev/null +++ b/kernel/src/arm/dnard/interrupt.c @@ -0,0 +1,156 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/dnard/interrupt.c + * Description: Interruppt handling code for the Dnard. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.8 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include + +#include INC_ARCH(farcalls.h) + +#include INC_PLATFORM(platform.h) + + +void init_irqs() L4_SECT_INIT; + +/* + * This contains the irq mask for both 8259A irq controllers, + */ +static unsigned int cached_irq_mask = 0x0000; + +#define __byte(x,y) (((unsigned char *)&(y))[x]) +#if 1 +#define cached_21 (__byte(0,cached_irq_mask)) +#define cached_A1 (__byte(1,cached_irq_mask)) +#else +#define cached_21 inb(0x21) +#define cached_A1 inb(0xA1) +#endif +static void disable_8259A_irq(unsigned int irq) +{ + unsigned int mask = 1 << irq; + cached_irq_mask |= mask; + if (irq & 8) { + outb(0xA1, cached_A1); + } else { + outb(0x21, cached_21); + } +} + +static void enable_8259A_irq(unsigned int irq) +{ + unsigned int mask = ~(1 << irq); + cached_irq_mask &= mask; + if (irq & 8) { + outb(0xA1, cached_A1); + } else { + outb(0x21, cached_21); + } +} + +static int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1<> 8)); +} + +/* + * Careful! The 8259A is a fragile beast, it pretty + * much _has_ to be done exactly like this (mask it + * first, _then_ send the EOI, and the order of EOI + * to the two 8259s is important! + */ +static void mask_and_ack_8259A(unsigned int irq) +{ + cached_irq_mask |= 1 << irq; + if (irq & 8) { + inb(0xA1); /* DUMMY */ + outb(0xA1, cached_A1); + outb(0x20, 0x62); /* Specific EOI to cascade */ + outb(0xA0, 0x20); + } else { + inb(0x21); /* DUMMY */ + outb(0x21, cached_21); + outb(0x20, 0x20); + } +} + +void mask_interrupt(dword_t irq) +{ +#warning: HACK + mask_and_ack_8259A(irq); +} + +void unmask_interrupt(unsigned int number) +{ + // do nothing - no automatic irq acking in pic mode +} + + + + + + +void init_irqs() +{ + printf("%s\n", __FUNCTION__); + + volatile char* x; + +#if 1 /* enable all irqs */ + x = (char*) 0xFFF00021; *x = cached_21; + x = (char*) 0xFFF000A1; *x = cached_A1; +#endif + x = (char*) 0xFFF00020; *x = 0x0A; + x = (char*) 0xFFF000A0; *x = 0x0A; + +} + + + +void irq_handler(dword_t spsr) +{ +// printf("%s - spsr=%x tcb=%p\n", __FUNCTION__, spsr, get_current_tcb()); + + for (int i=0; i < 16; i++) + if ((i != 2) && !(cached_irq_mask & (1 << i)) && i8259A_irq_pending(i)) + { +// printf(" IRQ %d pending ", i); +#warning REVIEWME: we should not ack here, should we? + mask_and_ack_8259A(i); +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('0'+i); +#endif + //printf(" masked and ack'd\n"); + + +#if 0 + printf("\nIER=%x EIR=%x, DATA=%c MSR=%x PIC %x%x ", + inb(0x3F9), inb(0x3FA), inb(0x3F8), inb(0x3FE), + inb(0xA0), inb(0x20)); +#endif + if (i == 8) /* timer interrupt ??? */ + { + /* reset timer intr line */ + in_rtc(0x0c); + /* enable the irq here before we eventually + loose the CPU in handle_timer_interrupt */ + enable_8259A_irq(i); + handle_timer_interrupt(); +// printf("irq: cached=%x, current %x:%x\n", cached_irq_mask, inb(0x21), inb(0xA1)); + }; + + }; + +// panic("foofoo"); + return; +} diff --git a/kernel/src/arm/dnard/interrupt.o b/kernel/src/arm/dnard/interrupt.o new file mode 100644 index 0000000..80f70ca Binary files /dev/null and b/kernel/src/arm/dnard/interrupt.o differ diff --git a/kernel/src/arm/dnard/libplatform.a b/kernel/src/arm/dnard/libplatform.a new file mode 100644 index 0000000..abb170a Binary files /dev/null and b/kernel/src/arm/dnard/libplatform.a differ diff --git a/kernel/src/arm/dnard/startup.S b/kernel/src/arm/dnard/startup.S new file mode 100644 index 0000000..ce3728d --- /dev/null +++ b/kernel/src/arm/dnard/startup.S @@ -0,0 +1,64 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/dnard/startup.S + * Description: Dnard startup code. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.11 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) + + .globl _start + + .section .init + +_start: + /* Switch to abort mode */ + mov r0, #(IRQ_MASK|FIQ_MASK|KERNEL_MODE) + msr cpsr, r0 + + /* reset spsr */ + mov r0, #0xd3 + msr spsr, r0 + + mcr p15, 0, r0, c7, c7 /* flush ID cache */ + mcr p15, 0, r0, c8, c7 /* flush I,D TLBs on v4 */ + + /* Initialize Stack Pointer */ + ldr sp, 1f + + /* Build the initial Page Table */ + bl setup_kernel_pgtable__Fv + + /* Enable the MMU */ + ldr r1, 3f /* jump there after mmu on */ + + ldr r0, 6f /* set domain register */ + mcr p15, 0, r0, c3, c0 + ldr r0, 4f /* install page table */ + mcr p15, 0, r0, c2, c0 + + mcr p15, 0, r0, c8, c7 /* flush I,D TLBs on v4 */ + mcr p15, 0, r0, c7, c7, 0 /* flush ID cache */ + + ldr r0, 5f /* switch on mmu */ + mcr p15, 0, r0, c1, c0 + + mov pc, r1 /* jump to init() */ + + +1: .word _init_stack_top +3: .word init__Fv +4: .word kernel_ptdir_p +5: .word (CTL_MMU_ENABLED | CTL_ICACHE | CTL_DCACHE | CTL_WRITE_BUF | CTL_SYS_PROT) +6: .word 0x00000005 +7: .word 0x400003f8 + +_init_stack_bottom: + .space 512 +_init_stack_top: diff --git a/kernel/src/arm/dnard/startup.o b/kernel/src/arm/dnard/startup.o new file mode 100644 index 0000000..a076d83 Binary files /dev/null and b/kernel/src/arm/dnard/startup.o differ diff --git a/kernel/src/arm/ep7211/.cvsignore b/kernel/src/arm/ep7211/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/arm/ep7211/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/arm/ep7211/Makefile b/kernel/src/arm/ep7211/Makefile new file mode 100644 index 0000000..b6ee4c7 --- /dev/null +++ b/kernel/src/arm/ep7211/Makefile @@ -0,0 +1,29 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arm/ep7211/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.5 2001/11/22 13:18:49 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c interrupt.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/ep7211/init.c b/kernel/src/arm/ep7211/init.c new file mode 100644 index 0000000..872099e --- /dev/null +++ b/kernel/src/arm/ep7211/init.c @@ -0,0 +1,116 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ep7211/init.c + * Description: EP7211 specific initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.10 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include + +#include INC_ARCH(cpu.h) +#include INC_ARCH(memory.h) +#include INC_ARCH(farcalls.h) + +#include INC_PLATFORM(platform.h) + +void setup_kernel_pgtable(void) L4_SECT_INIT; + +void init_platform() L4_SECT_INIT; +//void init_timer() L4_SECT_INIT; +void init_serial() L4_SECT_INIT; +/* from arm/dnard/interrupt.c */ +void init_irqs() L4_SECT_INIT; + +extern word_t _start_init[]; + +extern word_t excp_vaddr[]; +extern word_t excp_paddr[]; + + +void setup_kernel_pgtable() +{ + dword_t i; + fld_section_t *segment; + fld_page_t *page; + sld_largepage_t *large_page; + sld_smallpage_t *small_page; + + /* Zero out 1st Level Array */ + for(i = 0; i < FLD_MAX; i++) + kernel_ptdir_p[i].init = 0; + + /* Map in Init Segment - this first entry might + be replaced when installing the kernel text entry */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld((dword_t)_start_init); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment->sba = paddr_to_sba((dword_t)_start_init); /* Address of 1MB Frame */ + + /* Map in Text Segment */ + /* Add 1st Level Entry */ + page = (fld_page_t *)kernel_ptdir_p + vaddr_to_fld(KERNEL_VIRT); + page->type = FLD_PAGE; + page->ptba = paddr_to_ptba((dword_t)kernel_pgtable_p); + + /* Zero out 2nd Level Array */ + for(i = 0; i < SLD_MAX; i++) + kernel_pgtable_p[i].init = 0; + + /* Add 2nd Level Entry */ + large_page = (sld_largepage_t *)kernel_pgtable_p + + vaddr_to_sld(KERNEL_VIRT); + large_page->type = SLD_LARGE; + large_page->buf = TRUE; + large_page->cache = TRUE; + large_page->ap0 = AP_NOACCESS; + large_page->ap1 = AP_NOACCESS; + large_page->ap2 = AP_NOACCESS; + large_page->ap3 = AP_NOACCESS; + large_page->lpba = paddr_to_lpba((dword_t) excp_paddr); + /* Copy Entry (Required for Large Pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + *(volatile dword_t*) 0x800022c0 = ((1 << 6) | (0x7 << 2) | 0); + + /* Map in I/O */ + large_page = (sld_largepage_t *)kernel_pgtable_p + + vaddr_to_sld(IO_VBASE); + large_page->type = SLD_LARGE; + large_page->ap0 = AP_ALLACCESS; /* THIS IS ACCESSIBLE FROM USER MODE TOO */ + large_page->ap1 = AP_ALLACCESS; + large_page->ap2 = AP_ALLACCESS; + large_page->ap3 = AP_ALLACCESS; + large_page->cache = FALSE; + large_page->buf = FALSE; + large_page->lpba = paddr_to_lpba(IO_PBASE); + /* Copy Entry (Required for Large Pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + /* Map in Contiguous RAM */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld(cpaddr); +#if ((cpaddr + PHYS_DRAMSIZE) < cpaddr) +#error: Too much memory +#endif + for (i = cpaddr; i < cpaddr+DRAM_SIZE; i+=0x100000) /* in steps of 1M */ + { + segment->sba = paddr_to_sba(virt_to_phys(i)); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment++; + }; +} + +void init_platform() +{ + printf("%s\n", __FUNCTION__); + init_irqs(); + printf("%s done\n", __FUNCTION__); +}; + diff --git a/kernel/src/arm/ep7211/interrupt.c b/kernel/src/arm/ep7211/interrupt.c new file mode 100644 index 0000000..b7ba73e --- /dev/null +++ b/kernel/src/arm/ep7211/interrupt.c @@ -0,0 +1,76 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ep7211/interrupt.c + * Description: EP7211 specific interrupt handling code. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.9 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include + +#include INC_ARCH(farcalls.h) + +#include INC_PLATFORM(platform.h) + + +void init_irqs() L4_SECT_INIT; + +void init_irqs() +{ + printf("%s\n", __FUNCTION__); + volatile ptr_t x; + + /* Enable IRQ11, the 64Hz timer */ + x = (ptr_t) 0xFFF00280; *x = *x | (1 << 11); +} + +void mask_interrupt(dword_t number) +{ + volatile ptr_t x = (ptr_t) ((IO_VBASE + 0x0240) | ((number >> 4) * 0x1000)); + *x &= ~(1 << number); +} + +void unmask_interrupt(dword_t number) +{ + volatile ptr_t x = (ptr_t) ((IO_VBASE + 0x0240) | ((number >> 4) * 0x1000)); + *x |= (1 << number); +} + + +void irq_handler(dword_t spsr) +{ + /* INTSR3 has been omitted */ + dword_t irqs = ((((*(volatile ptr_t) 0xFFF00240) & (*(volatile ptr_t) 0xFFF00280) & 0xFFFF) << 0) | /* INTSR1 */ + (((*(volatile ptr_t) 0xFFF01240) & (*(volatile ptr_t) 0xFFF01280) & 0x3007) << 16)); /* INTSR2 */ + + for (int i=0; i < 32; i++) + if (irqs & (1 << i)) + { + mask_interrupt(i); + + if (i == 11) /* timer interrupt ??? */ + { +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('T'); +#endif + /* reset timer intr line */ + (*(volatile ptr_t) 0xFFF00680) = 7; + /* enable the irq here before we eventually + loose the CPU in handle_timer_interrupt */ + unmask_interrupt(i); + handle_timer_interrupt(); + } + else + { +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('0'+i); +#endif + handle_interrupt(i); + } + }; + return; +} diff --git a/kernel/src/arm/ep7211/startup.S b/kernel/src/arm/ep7211/startup.S new file mode 100644 index 0000000..141232d --- /dev/null +++ b/kernel/src/arm/ep7211/startup.S @@ -0,0 +1,92 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ep7211/startup.S + * Description: EP7211 startup code. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.5 2001/11/22 13:18:49 skoglund Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(cpu.h) + + .globl _start + + .section .init + +_start: + /* Switch to abort mode */ + mov r0, #(IRQ_MASK|FIQ_MASK|KERNEL_MODE) + msr cpsr, r0 + + /* reset spsr */ + mov r0, #0xd3 + msr spsr, r0 + + /* Initialize Stack Pointer */ + ldr sp, 1f + + /* Build the initial Page Table */ + bl setup_kernel_pgtable__Fv + + /* Enable the MMU */ +#if 1 + ldr r1, 3f /* jump there after mmu on */ +#else + ldr r1, 8f +#endif + ldr r0, 6f /* set domain register */ + MCR p15, 0, r0, c3, c0 + LDR r0, 4f /* install page table */ + MCR p15, 0, r0, c2, c0 + + MCR p15, 0, r0, c7, c7, 0 /* flush ID cache */ + + LDR r0, 5f /* switch on mmu */ + MCR p15, 0, r0, c1, c0 + + mov pc, r1 /* jump to init() */ + + + nop + nop + nop + + +#if 1 +flash: + /* LED Flasher */ + ldr r0, 7f + mov r1, #((1 << 6) | (0x7 << 2) | 0) + str r1, [r0] +0: b 0b +#endif + + +1: .word _init_stack_top +3: .word init__Fv +4: .word kernel_ptdir_p +#if defined(EXCEPTION_VECTOR_RELOCATED) +5: .word (CTL_MMU_ENABLED | CTL_IVECTOR | CTL_SYS_PROT | CTL_ICACHE | CTL_DCACHE | CTL_WRITE_BUF) +#else +5: .word (CTL_MMU_ENABLED | CTL_SYS_PROT | CTL_ICACHE | CTL_DCACHE | CTL_WRITE_BUF) +#endif + + +6: .word 0x00000005 +#if 0 +7: .word 0x800022c0 +#else +7: .word 0xFFF022c0 +#endif +8: .word flash + + + + +_init_stack_bottom: + .space 512 +_init_stack_top: diff --git a/kernel/src/arm/exception.S b/kernel/src/arm/exception.S new file mode 100644 index 0000000..5c3fa8a --- /dev/null +++ b/kernel/src/arm/exception.S @@ -0,0 +1,781 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/exception.S + * Description: Kernel entry points and interrupt/exception stubs + * for ARM. + * + * @LICENSE@ + * + * $Id: exception.S,v 1.36 2001/12/13 12:28:43 ud3 Exp $ + * + ********************************************************************/ +#include +#include +#include INC_ARCH(config.h) +#include INC_ARCH(syscalls.h) +#include INC_ARCH(cpu.h) + + + +#define SWITCH_TO_SVC \ + str lr, saved_lr ; \ + mrs lr, spsr ; \ + str lr, saved_spsr ; \ + mov lr, $(IRQ_MASK|FIQ_MASK|KERNEL_MODE) ; \ + msr cpsr, lr ; \ + nop ; \ + nop ; \ + nop ; \ + str lr, [sp, #-8]! ; \ + ldr lr, saved_spsr ; \ + msr spsr, lr ; \ + ldr lr, saved_lr + + + + + + + + + + + +/* + * Stack layout: + * + * after SWITCH_TO_SVC !!!! + * + * | | + * +-------+ + * | lr' | (pc after syscall) + * +-------+ + * old sp -> | km_lr | + * +-------+ + * | lr^ | (user lr) + * +-------+ + * | sp^ | (user sp) + * +-------+ + * sp -> | spsr | + * +-------+ + * | | + * + sub lr, lr, $adjust @ adjust lr + str lr, [sp, #4] @ Stack adjusted lr + mrs lr, spsr @ load SPSR into kernel_lr + str lr, [sp, #-12]! @ Stack SPSR + stmib sp, {sp,lr}^ @ Stack users sp and lr + + */ + + + +#define createexceptionframe(adjust) \ + sub lr, lr, $adjust ; \ + str lr, [sp, $4] ; \ + mrs lr, spsr ; \ + str lr, [sp, $-12]! ; \ + stmib sp, {sp,lr}^ ; \ + nop + + + + + + + +/* + * Stack layout: + * + * after SWITCH_TO_SVC !!!! + * + * | | + * +-------+ + * | lr^ | (pc after syscall) + * +-------+ + * old sp -> | km_lr | + * +-------+ + * | xx | + * +-------+ + * | sp^ | (user sp) + * +-------+ + * sp -> | spsr | + * +-------+ + * | | + * + stmib sp, {lr}^ @ Stack user lr as return address + mrs lr, spsr @ load SPSR into kernel_lr + str lr, [sp, #-12]! @ Stack SPSR + stmib sp, {sp}^ @ Stack user sp + + */ + + + +#define createsyscallframe \ + stmib sp, {lr}^ ; \ + nop ; \ + mrs lr, spsr ; \ + str lr, [sp, #-12]! ; \ + stmib sp, {sp}^ ; \ + nop + + + + + + +/* +** +** Exception vector (located on either 0x00000000 or 0xffff0000). +** +*/ + .section .vect,"a" + + .globl exception_vector +exception_vector: + nop /* RESET */ + b undef_entry /* UNDEF */ + b swi_entry /* SWI */ + b inst_abort_entry /* IABORT */ + b data_abort_entry /* DABORT */ + nop /* reserved */ + b irq_entry /* IRQ */ + b fiq_entry /* FIQ */ + + +/* locations to pass lr and spsr from one mode to the other + these are globally shared !!! */ + .section .excp,"xa" +saved_lr: .word 0 +saved_spsr: .word 0 + +/* +** +** Exception entry points. +** +*/ + +/* + * Exception undef () + * + * Exception is an undefined instruction. + * + */ +undef_entry: + SWITCH_TO_SVC + mov r0,#0xFE + b kern_kdebug_entry + + + + +/* + * Exception swi () + * + * Exception is a software interrupt (typically a syscall in normal + * OSes). + * + */ +swi_entry: + SWITCH_TO_SVC + mov r0,#0xFD + b kern_kdebug_entry + + + +/* + * Exception inst_abort () + * + * Exception is a prefetch (instruction) abort. This exception is also + * used for L4 syscalls. If the exception address is in the range 0x00 + * to 0x24 (in the exception vector page), this is interpreted as a + * syscall number. Some platforms allow the exception vector to be + * relocated to the beginning of the last 64K of memory. For these + * platforms, we use a negative (i.e. end of address space) value to + * indicate the syscall number. If exception is not within the syscall + * range, generate a pager IPC (or panic if within the kernel). + * + */ +inst_abort_entry: + + SWITCH_TO_SVC + +#ifdef EXCEPTION_VECTOR_RELOCATED + cmn lr, #SYSCALL_LIMIT @ Range Check !!! UNSIGNED !!! + bls prefetch_abort @ no syscall + sub pc, pc, lr @ Jump to relevant syscall +#else + cmp lr, #SYSCALL_LIMIT @ Range Check !!! UNSIGNED !!! + bhi prefetch_abort @ no syscall + add pc, pc, lr @ Jump to relevant syscall +#endif + nop + nop + b prefetch_abort @ NULL pointer access ? + b ipc_entry @ abort_lr = 0x08 + b id_nearest_entry @ abort_lr = 0x0C + b fpage_unmap_entry @ abort_lr = 0x10 + b thread_switch_entry @ abort_lr = 0x14 + b thread_schedule_entry @ abort_lr = 0x18 + b lthread_ex_regs_entry @ abort_lr = 0x1C + b create_thread_entry @ abort_lr = 0x20 + b user_kdebug_entry @ abort_lr = 0x24 + +prefetch_abort: + createexceptionframe(4) + + stmdb sp, {r0 - r12}^ @ Stack rest of user state + nop + sub sp, sp, #(13*4) + + ands lr, lr, #MODE_MASK @ Mask all but relevant mode bits + bne kernel_prefetch_abort @ Kernel abort? + /* user prefetch abort */ + mrc p15, 0, r0, c5, c0, 0 @ Load FSR into r0 + ldr r1, [sp, #68] + mov r2, r1 + + adr lr, exception_return +#ifdef EXCEPTION_VECTOR_RELOCATED + b user_pagefault__FUiUiUi +#else + ldr pc, 1f @ Jump to C code +#endif + +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word user_pagefault__FUiUiUi +#endif + +kernel_prefetch_abort: @ Kernel generated IAbort + @ Should not get IAborts in kernel + @ Kernel Panic + SWITCH_TO_SVC + mov r0,#0xFC + b kern_kdebug_entry + +/* + * Exception data_abort () + * + * Exception is a data abort. If exception happened in user mode, + * generate pager IPC. If exception happened in kernel mode, it is + * probably due to a non-mapped TCB (or else we panic). + * + * + * Stack layout: + * + * old sp-> | | + * +-------+ + * | lr' | +68 + * +-------+ + * | km_lr | +64 + * +-------+ + * | ulr | +60 + * +-------+ + * | usp | +56 + * +-------+ + * | spsr | +52 + * +-------+ + * | r12 | +48 + * +-------+ + * : : + * +-------+ + * sp -> | r0 | +0 + * +-------+ + * | | + * + * + * + */ + +data_abort_entry: + + SWITCH_TO_SVC + + createexceptionframe(8) + stmdb sp, {r0 - r12}^ @ Stack rest of user state + nop + sub sp, sp, #(13*4) + + ands lr, lr, #MODE_MASK @ Mask all but relevant mode bits + @ NE -> kernel + /* user data abort */ + mrc p15, 0, r0, c5, c0, 0 @ Load FSR into r0 + mrc p15, 0, r1, c6, c0, 0 @ Load FAR into r1 + ldr r2, [sp, #68] + + adr lr, exception_return @ set return address +#ifdef EXCEPTION_VECTOR_RELOCATED + bne kernel_pagefault__FUiUiUi + b user_pagefault__FUiUiUi +#else + ldrne pc, 1f @ kernel pagefault + ldr pc, 2f @ user pagefault +#endif + b kern_kdebug_entry + +1: .word kernel_pagefault__FUiUiUi +2: .word user_pagefault__FUiUiUi + + +/* + * Generic return code for restoring the thread state after exceptions. + * + * Stack layout: + * + * sp-> | | + * +-------+ + * | lr' | +68 + * +-------+ + * | km_lr | +64 + * +-------+ + * | ulr | +60 + * +-------+ + * | usp | +56 + * +-------+ + * | spsr | +52 + * +-------+ + * | r12 | +48 + * +-------+ + * : : + * +-------+ + * old sp -> | r0 | +0 + * +-------+ + * | | + * + * + */ +exception_return: + ldmia sp, {r0 - r12}^ @ Restore user state + nop + add sp, sp, #(13*4) + + ldr lr, [sp], #12 @ Unstack SPSR + msr spsr, lr @ Load SPSR from kernel_lr + ands lr, lr, #MODE_MASK @ Mask all but relevant mode bits + @ NE -> kernel + ldmeqdb sp, {sp,lr}^ @ restore user sp and lr + nop + add sp, sp, #8 @ Read return address + ldr lr, [sp, #-4] @ Read return address + moveqs pc, lr @ return and switch mode + + ldmdb sp, {pc}^ @ switches mode - doesnt do anything + nop + + bl kern_kdebug_entry +/* + * Exception irq () + * + * Exception is an interrupt. Generate interrupt IPC. + * + */ +irq_entry: + SWITCH_TO_SVC + createexceptionframe(4) + + stmdb sp, {r0 - r12}^ @ Stack rest of user state + nop + sub sp, sp, #(13*4) + + mov r0, lr +#ifdef EXCEPTION_VECTOR_RELOCATED + bl irq_handler__FUi +#else + mov lr, pc + ldr pc, 1f +#endif + b exception_return +1: .word irq_handler__FUi + + + +/* + * Exception fiq () + * + * Exception is a fast interrupt. Generate interrupt IPC. + * + */ +fiq_entry: + SWITCH_TO_SVC + mov r0,#0xFD + b kern_kdebug_entry + + + +/* +** +** Syscall entry points +** +*/ + + + + + + + + + + +/* + * Syscall ipc () + * + * Pre: r0 = destination thread id + * r1 = Snd descriptor, + * r2 = Rcv descriptor, + * r3 = timeout + * r4 - r12 = 9 msg words to send + * Post: r0 = Msg dope + cc, + * r1 = Source thread ID, + * r4 - r12 = 9 msg words received (or undefined). + * + */ +ipc_entry: + createsyscallframe + +#if (L4_NUMBITS_TCBS > 10) +# error TCB is too large for get_current_tcb()! +#endif + /* get current tcb */ + and lr, sp, #(L4_TCB_MASK | 0x03) + + /* Stack non register arguments for C call */ +#warning HACK + stmia lr, {r4 - r6} @ Stack some ipc_args + str r3, [lr, #12] @ Store timeout + /* Call ipc() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_ipc__FG13l4_threadid_tUiUi +#else + mov lr, pc + ldr pc, 1f +#endif + and lr, sp, #(L4_TCB_MASK | 0x03) + /* Load registers with ipc return values */ + ldmia lr, {r4 - r6} @ Load return values pointer in r0 + /* Return */ + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_ipc__FG13l4_threadid_tUiUi +#endif + + + +/* + * Syscall id_nearest () + * + * Pre: r0 = Destination thread ID. + * Post: r0 = Type, + * r1 = Nearest thread ID. + * + */ +id_nearest_entry: + createsyscallframe + /* Call id_nearest() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_id_nearest__FG13l4_threadid_t +#else + mov lr, pc + ldr pc, 1f +#endif + /* Load registers with lthread_ex_regs return values */ + /* Return */ + b syscall_return + + b kern_kdebug_entry +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_id_nearest__FG13l4_threadid_t +#endif + + + +/* + * Syscall fpage_unmap () + * + * Pre: r0 = Fpage to unmap, + * r1 = Map mask. + * + */ +fpage_unmap_entry: + createsyscallframe + /* Stack SPSR */ + mrs lr, spsr @ Load SPSR into abort_lr + str lr, [sp, #12] @ Stack SPSR + /* Call fpage_unmap() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_fpage_unmap__FG7fpage_tUi +#else + mov lr, pc + ldr pc, 1f +#endif + /* Return */ + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_fpage_unmap__FG7fpage_tUi +#endif + + + +/* + * Syscall thread_switch () + * + * Pre: r0 = Destination thread ID. + * Post: switch to destination ID if ready or just schedule. + * + */ +thread_switch_entry: + createsyscallframe + /* Call thread_switch() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_thread_switch__FG13l4_threadid_t +#else + mov lr, pc + ldr pc, 1f +#endif + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_thread_switch__FG13l4_threadid_t +#endif + + + +/* + * Syscall thread_schedule () + * + * Pre: r0 = Destination thread ID, + * r1 = Parameter word. + * Post: r0 = Time high, + * r1 = Time low, + * r2 = Old parameter word, + * r3 = Partner. + * + */ +thread_schedule_entry: + createsyscallframe + /* Stack SPSR */ + mrs lr, spsr @ Load SPSR into abort_lr + str lr, [sp, #12] @ Stack SPSR + /* Call thread_schedule() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_schedule__FG16schedule_param_tG13l4_threadid_t +#else + mov lr, pc + ldr pc, 1f +#endif + /* Return */ + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_schedule__FG16schedule_param_tG13l4_threadid_t +#endif + + + +/* + * Syscall lthread_ex_regs () + * + * Pre: r0 = thread_id, + * r1 = instruction pointer, + * r2 = stack pointer, + * r3 = pager + * Post: r0 = Old CPSR, + * r1 = Old program pointer, + * r2 = Old stack counter, + * r4 = Old pager + * r3 = Old preempter + * + */ +lthread_ex_regs_entry: + createsyscallframe + /* Stack Non register arguments for C call */ + str r4, [sp, #-4]! @ Stack r4 + + /* Call lthread_ex_regs() */ +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_lthread_ex_regs__FUiUiUiG13l4_threadid_t +#else + mov lr, pc + ldr pc, 1f +#endif + add sp, sp, #4 @ Ajust stack to remove arguments + /* Return */ + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_lthread_ex_regs__FUiUiUiG13l4_threadid_t +#endif + + + +/* + * Syscall create_thread () + * + * Pre: r0 = thread ID, + * r1 = template thread ID, + * r2 = pager thread ID, + * r3 = instruction pointer, + * r4 = stack pointer, + * Post: nothing + * + */ +create_thread_entry: + createsyscallframe + /* Stack Non register arguments for C call */ + stmfd sp!, {r4} @ Stack r4 + /* Call create_thread() */ + +#ifdef EXCEPTION_VECTOR_RELOCATED + bl sys_task_new__FG13l4_threadid_tUiT0UiUi +#else + mov lr, pc + ldr pc, 1f +#endif + add sp, sp, #4 @ Ajust stack to remove arguments + /* Return */ + b syscall_return +#ifndef EXCEPTION_VECTOR_RELOCATED +1: .word sys_task_new__FG13l4_threadid_tUiT0UiUi +#endif + + + + + + +user_kdebug_entry: + createsyscallframe + bl kern_kdebug_entry + b syscall_return + + + + + + + + + + + +/* Both "functions" return the value from the stack to the user, + but obviously for different reasons. */ + .globl switch_to_roottask__Fv +switch_to_roottask__Fv: + .globl abort_ipc__Fv +abort_ipc__Fv: + ldr r0, [sp] @ load the error code + b switch_to_user__Fv + + + +1: .word KERNEL_VIRT +2: .word KERNEL_PHYS + .globl switch_to_sigma0__Fv +switch_to_sigma0__Fv: + ldr r0, 1b + ldr r1, 2b + sub r1, r0, r1 @ d=v-p + ldr r0, [sp] @ virt addr of kernel_info_page + sub r0, r0, r1 @ v-d + b switch_to_user__Fv + + + + + .globl switch_to_user__Fv +switch_to_user__Fv: + add sp, sp, #4 @ throw away parameter + @ fall thru to syscall_return + + +/* + * Generic code for restoring the thread state after syscalls. Upon + * entry registers should contain the syscall return values. + * + * Stack layout: + * + * new sp -> | | + * +-------+ + * | lr^ | (pc after syscall) + * +-------+ + * | km_lr | + * +-------+ + * | xx | <- we could use the ulr as a return param + * +-------+ + * | sp^ | (user sp) + * +-------+ + * old sp -> | spsr | + * +-------+ + * | | + * + */ + .globl syscall_return +syscall_return: + ldr lr, [sp] @ Unstack SPSR + msr spsr, lr @ Load SPSR from abort_lr + ldmib sp, {sp,lr}^ @ restore user sp and lr + nop + add sp, sp, #20 + ldr lr, [sp, #-4] @ Read return address + movs pc, lr @ return and switch mode + + + + + + + + +/********************************************************************** + kdebug entry + **********************************************************************/ + + + +3: .word kdebug_entry__FP17exception_frame_t + + .globl kern_kdebug_entry +kern_kdebug_entry: + sub sp, sp, #12 + str sp, [sp, #-0x10] + str lr, [sp, #-0x0C] + mrs lr, cpsr + str lr, [sp, #-0x08] +// str lr, [sp, #-0x04] /* Store cpsr in frame->spsr ??? */ + mrs lr, spsr + str lr, [sp, #-0x04] /* Store spsr in frame->spsr */ + str lr, [sp, # 0x04] /* Store spsr on stack */ + sub sp, sp, #(15*4 + 16) + stmia sp, {r0-r14}^ + nop + mov r0, sp + + /* use kdebug's own stack */ + ldr sp, _kdebug_stack_top + stmdb sp!, {r0} + adr lr, 1f + ldr pc, 3b +1: + ldr sp, _kdebug_stack_top + ldr sp, [sp, #-4] + ldmia sp, {r0-r14}^ + nop + add sp, sp, #(15*4 + 16) + ldr lr, [sp, #-0x08] + msr cpsr, lr + ldr lr, [sp, # 0x04] /* Restore spsr from stack */ + msr spsr, lr + ldr lr, [sp, #-0x0C] + ldr sp, [sp, #-0x10] + add sp, sp, #12 + mov pc, lr + + .globl _kdebug_stack_bottom +_kdebug_stack_bottom: + .space 1024 + + .globl _kdebug_stack_top +_kdebug_stack_top: + .word _kdebug_stack_top + diff --git a/kernel/src/arm/exception.o b/kernel/src/arm/exception.o new file mode 100644 index 0000000..d19bc6e Binary files /dev/null and b/kernel/src/arm/exception.o differ diff --git a/kernel/src/arm/farcalls.c b/kernel/src/arm/farcalls.c new file mode 100644 index 0000000..f7421aa --- /dev/null +++ b/kernel/src/arm/farcalls.c @@ -0,0 +1,17 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/farcalls.c + * Description: Hooks for doing farcalls on ARM. + * + * @LICENSE@ + * + * $Id: farcalls.c,v 1.9 2001/11/22 13:18:48 skoglund Exp $ + * + ********************************************************************/ +#include + +const int (*__farcall_printf)(const char *, ...) = printf; +const void (*__farcall_panic)(const char*) = panic; +const void (*__farcall_kmem_free)(ptr_t address, dword_t size) = kmem_free; diff --git a/kernel/src/arm/farcalls.o b/kernel/src/arm/farcalls.o new file mode 100644 index 0000000..a9210d1 Binary files /dev/null and b/kernel/src/arm/farcalls.o differ diff --git a/kernel/src/arm/init.c b/kernel/src/arm/init.c new file mode 100644 index 0000000..8eba1e1 --- /dev/null +++ b/kernel/src/arm/init.c @@ -0,0 +1,144 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/init.c + * Description: ARM specifuc initalization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.26 2001/12/07 19:09:50 skoglund Exp $ + * + ********************************************************************/ +#include + +#include INC_ARCH(cpu.h) +#include INC_ARCH(memory.h) +#include INC_PLATFORM(platform.h) + +/* relocate to init section */ +void init_arch_1() L4_SECT_INIT; +void init_arch_2() L4_SECT_INIT; +void init_paging() L4_SECT_INIT; +void setup_excp_vector() L4_SECT_INIT; +void zero_memory(void * address, int size); + +void init_platform() L4_SECT_INIT; + +void init_arch_2() +{ +} + +/* post processing (e.g., flushing page-table entries) */ +void init_arch_3() +{ + extern dword_t _start_init[]; + + /* kmem is initialized now */ + __zero_page = kmem_alloc(PAGE_SIZE); + zero_memory(__zero_page, PAGE_SIZE); + + /* remove init area from pagetable */ + ((fld_t *) kernel_ptdir)[vaddr_to_fld((dword_t) _start_init)].page.type = FLD_INVALID; + + flush_tlb(); + Flush_ID_Cache(); +} + + + +void zero_memory(void * address, int size) +{ + dword_t *tmp = (dword_t*)address; + size /= 4; + while(size--) + *tmp++ = 0; +} + + +#include INC_ARCH(farcalls.h) + +/* architecture specific initialization + * invoked by /init.c before anything is done + * but running on virtual addresses + */ +void init_arch_1() +{ + extern dword_t kmem_start; + extern dword_t kmem_end; + dword_t cpsr; + dword_t cp15_0; + + kernel_ptdir = phys_to_virt((dword_t*) kernel_ptdir_p); + + init_platform(); + + /* set the range of memory for the kernel memory allocator */ + kmem_start = phys_to_virt(kernel_info_page.main_mem_high-256*1024); + kmem_end = phys_to_virt(kernel_info_page.main_mem_high-1); + + __asm__ __volatile__( + "mrs %0, cpsr \n" + "mrc p15, 0, %1, c0, c0, 0 @ Load CPUID into %1 \n" + :"=r"(cpsr), "=r"(cp15_0)); + printf("Hello, I'm your kernel. Running on %x, CPSR is %x\n", cp15_0, cpsr); + +} + + +#if !defined(HAVE_ARCH_KMEMORY) +#if !defined(EXCEPTION_VECTOR_RELOCATED) +static const ptr_t (*__farcall_kmem_alloc)(dword_t) L4_SECT_INIT = kmem_alloc; +#define kmem_alloc __farcall_kmem_alloc +#endif +#else +static const ptr_t (*__farcall_kmem_alloc_1k)() L4_SECT_INIT = kmem_alloc_1k; +#define kmem_alloc_1k __farcall_kmem_alloc_1k +#endif + +/* architecture initialization - before everything else */ +extern word_t excp_vaddr[]; +extern word_t excp_paddr[]; + +/* + * Function setup_excp_vector () + * + * Map the page containing the exception vector. + * + */ +void setup_excp_vector(void) +{ +#if !defined(EXCEPTION_VECTOR_RELOCATED) + int i; + sld_t *excp_pgtable; + fld_page_t *page; + sld_smallpage_t *small_page; + + /* Allocate 1KB page for holding the page table */ + excp_pgtable = (sld_t *) kmem_alloc(SLD_SIZE); + + /* Add 1st Level Entry */ +#warning REVIEWME: ptdir[excp_vaddr] ? + page = (fld_page_t *) kernel_ptdir; + page->type = FLD_PAGE; + page->domain = USER_DOMAIN; + page->ptba = + paddr_to_ptba(virt_to_phys((dword_t) excp_pgtable)); + + /* Zero out 2nd Level Array */ + for(i = 0; i < SLD_MAX; i++) + excp_pgtable[i].init = 0; + + /* Add 2nd Level Entry */ + small_page = (sld_smallpage_t *) excp_pgtable; + small_page->type = SLD_SMALL; + small_page->buf = TRUE; + small_page->cache = TRUE; + small_page->ap0 = AP_NOACCESS; + small_page->ap1 = AP_NOACCESS; + small_page->ap2 = AP_NOACCESS; + small_page->ap3 = AP_NOACCESS; + small_page->spba = paddr_to_spba((dword_t) excp_paddr); +#endif +} + diff --git a/kernel/src/arm/init.o b/kernel/src/arm/init.o new file mode 100644 index 0000000..00d8799 Binary files /dev/null and b/kernel/src/arm/init.o differ diff --git a/kernel/src/arm/ipaq/Makefile b/kernel/src/arm/ipaq/Makefile new file mode 100644 index 0000000..6afcdf2 --- /dev/null +++ b/kernel/src/arm/ipaq/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arm/ipaq/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.1 2002/01/24 07:13:13 uhlig Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c interrupt.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/ipaq/init.c b/kernel/src/arm/ipaq/init.c new file mode 100644 index 0000000..67e16ad --- /dev/null +++ b/kernel/src/arm/ipaq/init.c @@ -0,0 +1,155 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/init.c + * Description: IPaq specific initalization functions. + * Based on Brutus implementation + * + * @LICENSE@ + * + * $Id: init.c,v 1.1 2002/01/24 07:13:13 uhlig Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(memory.h) +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + +void setup_kernel_pgtable(void) L4_SECT_INIT; +void init_platform(void) L4_SECT_INIT; +void init_timer(void) L4_SECT_INIT; +void init_irqs(void) L4_SECT_INIT; + + +extern dword_t _start_init[]; +extern dword_t text_paddr[]; +extern dword_t text_vaddr[]; + + +/* + * Function setup_kernel_pgtable () + * + * Create initial pagetable. This should contain everything we + * need in order to run the kernel. When the function returns, it + * should be safe to enable the MMU. + * + */ +void setup_kernel_pgtable(void) +{ + dword_t i; + fld_section_t *segment; + fld_page_t *page; + sld_largepage_t *large_page; + sld_smallpage_t *small_page; + + /* Zero out 1st Level Array */ + for(i = 0; i < FLD_MAX; i++) + kernel_ptdir_p[i].init = 0; + + /* + * Map in Init segment + */ + segment = (fld_section_t *) kernel_ptdir_p + + vaddr_to_fld((dword_t) _start_init); + segment->type = FLD_SECTION; /* 1st level segment entry */ + segment->ap = AP_NOACCESS; /* Kernel access only */ + segment->sba = paddr_to_sba((dword_t) _start_init); /* Address of 1MB Fr */ + + /* + * Map in Text segment + */ + + /* Add 1st level entry */ + page = (fld_page_t *) kernel_ptdir_p + vaddr_to_fld((dword_t) text_vaddr); + page->type = FLD_PAGE; + page->ptba = paddr_to_ptba((dword_t) kernel_pgtable_p); + + /* Zero out 2nd level array */ + for(i = 0; i < SLD_MAX; i++) + kernel_pgtable_p[i].init = 0; + + /* Add 2nd level entry */ + large_page = (sld_largepage_t *) kernel_pgtable_p + + vaddr_to_sld(0xFFFF0000 & (dword_t) text_vaddr); + large_page->type = SLD_LARGE; + large_page->buf = TRUE; + large_page->cache = TRUE; + large_page->ap0 = AP_NOACCESS; + large_page->ap1 = AP_NOACCESS; + large_page->ap2 = AP_NOACCESS; + large_page->ap3 = AP_NOACCESS; + large_page->lpba = paddr_to_lpba(0xFFFF0000 & (dword_t) text_paddr); + + /* Copy entry (required for large pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + /* + * Map in Interrupt Controller registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(INTCTRL_VBASE); + small_page->type = SLD_SMALL; + small_page->ap0 = AP_NOACCESS; + small_page->ap1 = AP_NOACCESS; + small_page->ap2 = AP_NOACCESS; + small_page->ap3 = AP_NOACCESS; + small_page->spba = paddr_to_spba(INTCTRL_PBASE); + + /* + * Map in OS Timer registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(OSTIMER_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(OSTIMER_PBASE); + + /* + * Map in UART Serial Port registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(UART_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(UART_PBASE); + small_page->ap0 = AP_ALLACCESS; + small_page->ap1 = AP_ALLACCESS; + small_page->ap2 = AP_ALLACCESS; + small_page->ap3 = AP_ALLACCESS; + + /* + * Map in GPIO registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(GPIO_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(GPIO_PBASE); + + /* + * Map Reset Controller Registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(RSTCTL_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(RSTCTL_PBASE); + + /* Map in Contiguous RAM */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld(cpaddr); +#if ((cpaddr + PHYS_DRAMSIZE) < cpaddr) +#error: Too much memory +#endif + for (i = cpaddr; i < cpaddr+DRAM_SIZE; i+=0x100000) /* in steps of 1M */ + { + segment->sba = paddr_to_sba(virt_to_phys(i)); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment++; + }; +} + + +void init_platform() +{ + init_irqs(); + init_timer(); +} diff --git a/kernel/src/arm/ipaq/interrupt.c b/kernel/src/arm/ipaq/interrupt.c new file mode 100644 index 0000000..7f29343 --- /dev/null +++ b/kernel/src/arm/ipaq/interrupt.c @@ -0,0 +1,123 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/interrupt.c + * Description: IPaq specific interrupt/timer stuff. + * based on Brutus code + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.1 2002/01/24 07:13:13 uhlig Exp $ + * + ********************************************************************/ +#include + +#include +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + + +void init_irqs(void) L4_SECT_INIT; +void init_timer() L4_SECT_INIT; + + +/* + * Function init_irqs () + * + * Initialize interrupt handling for the SA-1100. + * + */ +void init_irqs(void) +{ + /* + * Set all interrupts to generate IRQs rather than FIQs. + */ + ICLR = 0x00000000; + + /* + * Only enabled and unmasked interrupts will bring CPU out of idle + * mode. + */ + ICCR = 1; + + /* + * Acknowledge any pending interrupts. + */ + ICIP = 0xffffffff; + ICFP = 0xffffffff; + + /* + * Enable interrupts from ostimer0. + */ + ICMR = INTR_OSTIMER0; +} + + +/* + * Function init_timer () + * + * Initialize the SA-1100 operating system timer. + * + */ +void init_timer(void) +{ + /* Clear all OS-timer matches */ + OSSR = 0x0f; + + /* Acknowledge pending OS Timer 0 interrupt */ + ICIP = INTR_OSTIMER0; + + /* Enable OS Timer 0 */ + OIER = 0x01; + + OSMR0 = OSCR + (18432000 >> 2); /* Wait 5/4 sec */ +} + + +void irq_handler(dword_t spsr) +{ + dword_t m, i, icip = ICIP; + + if ( icip & INTR_OSTIMER0 ) + { +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('T'); +#endif + + OSMR0 = OSCR + (CLOCK_FREQUENCY/1024) * (TIME_QUANTUM/1024); + + OSSR = 0x01; + ICIP = INTR_OSTIMER0; + + handle_timer_interrupt(); + return; + } + + for ( i = 31, m = 0x8000000U; (~icip & m) && m; m >>= 1, i-- ) + ; + +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('0'+i); +#endif + + if ( m == 0 ) + { + printf("No interrupt pending\n"); + enter_kdebug(); + return; + } + + handle_interrupt(i); +} + + +void mask_interrupt(dword_t num) +{ + ICMR = ICMR & ~(1 << num); +} + +void unmask_interrupt(unsigned int number) +{ + // do nothing - no automatic irq acking??? +} diff --git a/kernel/src/arm/ipaq/startup.S b/kernel/src/arm/ipaq/startup.S new file mode 100644 index 0000000..b223825 --- /dev/null +++ b/kernel/src/arm/ipaq/startup.S @@ -0,0 +1,61 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/ipaq/startup.S + * Description: Startup code for the IPaq. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.1 2002/01/24 07:13:13 uhlig Exp $ + * + ********************************************************************/ +#include +#include INC_PLATFORM(platform.h) +#include INC_ARCH(cpu.h) + + .globl _start + .section .init,"xa" +_start: + /* Switch to abort mode */ + mov r0, #(IRQ_MASK|FIQ_MASK|KERNEL_MODE) + msr cpsr, r0 + + /* reset spsr */ + mov r0, #0xd3 + msr spsr, r0 + + /* Initialize stack pointer */ + ldr sp, 5f + + /* Build the initial page table */ + bl setup_kernel_pgtable__Fv + + /* Enable the MMU */ + ldr r0, 1f + mcr p15, 0, r0, c2, c0 @ Set Translation Table Base + mov r0, #0x00000005 + mcr p15, 0, r0, c3, c0 @ Access checking for Domain 1 + ldr r0, 2f + mcr p15, 0, r0, c1, c0 @ Enable the MMU + nop + nop + nop + + /* Call init() */ + ldr pc, 4f + +1: .word kernel_ptdir_p +#ifdef EXCEPTION_VECTOR_RELOCATED +2: .word (CTL_MMU_ENABLED | CTL_ICACHE | CTL_DCACHE | CTL_WRITE_BUF | CTL_SYS_PROT | CTL_IVECTOR) +#else +2: .word (CTL_MMU_ENABLED | CTL_SYS_PROT) +#endif +3: .word kernel_ptdir +4: .word init__Fv +5: .word _stack_top + + /* Initializtation stack */ +_stack_bottom: + .space 4096 +_stack_top: diff --git a/kernel/src/arm/kmemory.c b/kernel/src/arm/kmemory.c new file mode 100644 index 0000000..62bac4e --- /dev/null +++ b/kernel/src/arm/kmemory.c @@ -0,0 +1,1019 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/kmemory.c + * Description: ARM specific kernel memory allocator + * + * @LICENSE@ + * + * $Id: kmemory.c,v 1.16 2001/11/22 13:18:48 skoglund Exp $ + * + ********************************************************************/ +#include + +/* Just in case someone wants to use the generic allocator. */ +#ifdef CONFIG_HAVE_ARCH_KMEM + +#include +#include INC_PLATFORM(platform.h) +#include INC_ARCH(farcalls.h) + + +/* + * From linker scripts. + */ +extern dword_t kmem_start[]; +extern dword_t kmem_end[]; +extern dword_t cpaddr[]; + + +/* + * The layout of the first words in free pages. + */ +typedef struct pglink_t pglink_t; +struct pglink_t { + pglink_t *next; /* This MUST be the first field */ + pglink_t *prev; + pglink_t *next_cluster; +}; + + +/* + * Keep one freelists for each of the page sizes. + */ +static pglink_t *freelist_16k; +static dword_t numfree_16k; + +static pglink_t *freelist_4k; +static pglink_t *cluster_4k; +static dword_t numfree_4k; + +static pglink_t *freelist_1k; +static pglink_t *cluster_1k; +static dword_t numfree_1k; + + + +/* + * Bitarray indicating which pages are allocated. Granularity is 1KB. + */ +static byte_t alloc_array[PHYS_MEMSIZE/1024/8]; + + + +/* + * Uncomment to turn on debugging output. + */ +//#define DEBUG_KMEM 1 + +#ifdef DEBUG_KMEM +# define DBG_PRINTF(fmt, args...) printf(fmt , ## args) +# define PRINT_STATUS() \ +({ \ + DBG_PRINTF("Kmem status: 16k(%d,%p)", numfree_16k, freelist_16k); \ + DBG_PRINTF(" 4k(%d,%p,%p)", numfree_4k, freelist_4k, cluster_4k); \ + DBG_PRINTF(" 1k(%d,%p,%p)\n", numfree_1k, freelist_1k, cluster_1k); \ +}) +#else +# define DBG_PRINTF(fmt, args...) +# define PRINT_STATUS() +#endif + + +/* + * Uncomment to turn on tracing output. + */ +//#define TRACE_KMEM 1 + +#ifdef TRACE_KMEM +# define TRACE_ALLOC() \ +({ \ + dword_t lr; \ + __asm__ ("mov %0,lr\n":"=r"(lr)); \ + printf("0x%x: %s() -> 0x%x\n", lr, __FUNCTION__, pg); \ +}) +# define TRACE_FREE() \ +({ \ + dword_t lr; \ + __asm__ ("mov %0,lr\n":"=r"(lr)); \ + printf("0x%x: %s(0x%x)\n", lr, __FUNCTION__, addr); \ +}) +#else +# define TRACE_ALLOC() +# define TRACE_FREE() +#endif + + + +/* + * KERNEL MEMORY ALLOCATOR DESIGN + * + * BASICS + * + * The kernel memory allocator works as follows: Have one freelist + * each for page sizes of 16k, 4k, and 1k. The freelists are doubly + * linked, with the next and prev pointers within freelists residing + * in the beginning of the page memory (see pglink_t structure). When + * allocating a page of a given size, the head of the corresponding + * freelist is popped off. This is all peachy keen. However, if + * there are no pages available in the freelist, things get a little + * bit messier. For allocating 1k and 4k pages, there is a + * possibility of splitting up a 4k page, or a 16k page respectively. + * This will make more and more smaller pages though, eventually + * leaving only 1k pages left. + * + * DEALING WITH SPLIT PAGES + * + * We must be able to cluster several small pages to make a larger + * page. So, in addition to the freelist pointers, we also keep + * cluster pointers for the 1k and 4k freelists. These pointers will + * always point to a position in the freelist where we can find 4 + * consecutive pages (ie. four 1K pages making up a 4K page, or four + * 4K pages making up a 16K page). When we need to concatenete + * smaller pages to make a larger one, we may simply retrieve 4 pages + * from where the cluster pointer is pointing. + * + * KEEPING CLUSTER POINTERS VALID + * + * Ensuring that cluster pointers are valid is the responsibility of + * the free functions (we assume that freeing pages is less time + * critical than allocating pages). This is accomplished in the + * following manner: The page which is freed will fall into one of + * four locations in a larger page. Eg. a 4K page may be located in + * the beginning of a 16K page (page 0 in the figure below), it might + * be located in the middle (page 1 or 2), or in the end (page 3). + * + * +-----+-----+-----+-----+ + * | 0 | 1 | 2 | 3 | (four 4K pages) + * +-----+-----+-----+-----+ + * + * +-----------------------+ + * | | (one 16K page) + * +-----------------------+ + * + * If it is the case that the page was in the beginning (ie. page 0), + * we inspect the memory location for the next page (page 1). If this + * page is NOT allocated, we insert the freed page in front of this + * page, and also checks to see if the next pointer in this page + * points to page 2. If this is the case, we check the next pointer + * of page 2 to see if it points to page 3. If all test turn out + * positive, we have discovered that we have 4 consecutive pages. + * These 4 pages are referred to as a cluster, which is inserted into + * the end of the freelist (see below). If some of the tests above + * did not turn out positive, we have at least started to build a + * cluster (by inserting the freed page 0 in front of page 1). Of + * course, the example above is just valid when we a freeing page 0. + * If the freed page was not page 0, the steps taken above would be + * somewhat different (the basic concept would remain the same). + * + * In order to prevent clustered pages to be split up unnecessarily, + * we move clustered pages to the end of the freelist rather than + * keeping them in arbitrary positions. A cluster pointer is + * associated with both the 4K and 1K freelists, pointing to the first + * page belonging to a cluster. The invariant is that all pages + * following the cluster pointer will belong to a cluster, and the 4 + * pages within each cluster will be ordered. + * + * Using cluster pointers, moving four 1K or four 4K pages to the 4K + * or 16K freelists should prove efficient. The policy for when to + * move pages between freelists need to be investigated though. + * Currently, the alloc functions tries to move pages in between + * freelists if they find that there are no available pages in their + * respective freelist. + * + */ + + +/* + * The allocator is a bit large (codewise). The first 230 lines of + * code however (700 bytes or so), is just for the initalization. It + * will as such be removed from the kernel image once the + * initialization has completed. + */ + + +/* + * Function is not needed after initialization. + */ +void kmem_init(void) L4_SECT_INIT; + + +/* + * Function kmem_init () + * + * Initialize freelists for 16K, 4K, and 1K pages. + * + */ +void kmem_init(void) +{ + pglink_t *pg, *pgn, *pgp; + dword_t *p, num16, num4, num1, i, j; + dword_t start16k, end16k, addr; + + /* + * Calculate where to start and stop allocating 16K pages. + */ + start16k = (dword_t) kmem_start - ((dword_t) kmem_start & KMEM_16K_MASK); + + (((dword_t) kmem_start & KMEM_16K_MASK) ? KMEM_16K_MASK+1 : 0); + end16k = (dword_t) kmem_end - ((dword_t) kmem_end & KMEM_16K_MASK); + + /* + * First, put all kmem into 16K pages. + */ + pgp = (pglink_t *) &freelist_16k; + freelist_16k = (pglink_t *) start16k; + + for (pg = (pglink_t *) start16k, num16 = 0; + pg < (pglink_t *) end16k; + pg = pgn) + { + pgn = (pglink_t *) ((dword_t) pg + 16384); + + /* Zero out pages */ + for (p = (dword_t *) pg; p < (dword_t *) pgn; p++) + *p = 0; + + pg->next = pgn; + pg->prev = pgp; + pgp = pg; + + /* Count pages */ + num16++; + } + pgp->next = (pglink_t *) NULL; + + + /* + * Calculate number of pages to put into other freelists. + */ + num4 = num16 * KMEM_INIT_4K_RATIO; + num1 = num16 * KMEM_INIT_1K_RATIO; + num16 -= (num4 + num1); + + /* + * Move pages from 16K freelist to 4K freelist. + */ + if ( num4 ) { + pgp = (pglink_t *) &freelist_4k; + freelist_4k = freelist_16k; + + for (i = 0, pg = (pglink_t *) freelist_4k; + i < num4; + i++) + { + /* Check for clustering */ + if ( i+1 < num4 ) + pg->next_cluster = (pglink_t *) ((dword_t) pg + 16384); + + for (j = 0; j < 4; j++, pg = pgn) { + pgn = (pglink_t *) ((dword_t) pg + 4096); + + pg->next = pgn; + pg->prev = pgp; + pgp = pg; + } + } + num4 *= 4; + pgp->next = (pglink_t *) NULL; + cluster_4k = freelist_4k; + + /* Cleanup 16K freelist */ + if ( (dword_t) pg < end16k ) { + freelist_16k = pg; + pg->prev = (pglink_t *) &freelist_16k; + } else { + freelist_16k = NULL; + } + } else { + freelist_4k = NULL; + numfree_4k = 0; + } + + + /* + * Move pages from 16K freelist to 1K freelist. + */ + if ( num1 ) { + pgp = (pglink_t *) &freelist_1k; + freelist_1k = freelist_16k; + + for (i = 0, pg = (pglink_t *) freelist_1k; + i < num1; + i++) + { + for (j = 0; j < 16; j++, pg = pgn) { + pgn = (pglink_t *) ((dword_t) pg + 1024); + + /* Check for clustering */ + if ( !(j%4) && (j < 12 || i+1 < num1) ) + pg->next_cluster = (pglink_t *) ((dword_t) pg + 4096); + + pg->next = pgn; + pg->prev = pgp; + pgp = pg; + } + } + num1 *= 16; + pgp->next = (pglink_t *) NULL; + cluster_1k = freelist_1k; + + /* Cleanup 16K freelist */ + if ( (dword_t) pg < end16k ) { + freelist_16k = pg; + pg->prev = (pglink_t *) &freelist_16k; + } else { + freelist_16k = NULL; + } + } else { + freelist_1k = NULL; + numfree_1k = 0; + } + + + /* + * If kmem_start was not aligned on a 16K boundary, put all memory + * from kmem_start to the first 16K boundary into the 1K freelist + * (ie. max 15 pages). + */ + if ( (dword_t) kmem_start < start16k ) { + pgp = (pglink_t *) &freelist_1k; + + for (pg = (pglink_t *) kmem_start; + pg < (pglink_t *) start16k; + pg = pgn) + { + pgn = (pglink_t *) ((dword_t) pg + 1024); + + /* Zero out page */ + for (p = (dword_t *) pg; p < (dword_t *) pgn; p++) + *p = 0; + + pg->next = pgn; + pg->prev = pgp; + pgp = pg; + + num1++; + } + + /* Insert into start of freelist (before clusters) */ + pgp->next = (pglink_t *) freelist_1k; + if ( pgp->next ) + pgp->next->prev = pgp; + pgp->prev = (pglink_t *) &freelist_1k; + freelist_1k = (pglink_t *) kmem_start; + } + + + /* + * If kmem_end was not aligned on a 16K boundary, put all memory + * from the previous 16K boundary upto kmem_end into the 1K + * freelist (ie. max 15 pages). + */ + if ( end16k < (dword_t) kmem_end ) { + pgp = (pglink_t *) &freelist_1k; + + for (pg = (pglink_t *) end16k; + pg < (pglink_t *) kmem_end; + pg = pgn) + { + pgn = (pglink_t *) ((dword_t) pg + 1024); + + /* Zero out page */ + for (p = (dword_t *) pg; p < (dword_t *) pgn; p++) + *p = 0; + + pg->next = pgn; + pg->prev = pgp; + pgp = pg; + + num1++; + } + + /* Insert into start of freelist (before clusters) */ + pgp->next = (pglink_t *) freelist_1k; + if ( pgp->next ) + pgp->next->prev = pgp; + pgp->prev = (pglink_t *) &freelist_1k; + freelist_1k = (pglink_t *) end16k; + } + + + /* + * Initialize accounting info + */ + numfree_16k = num16; + numfree_4k = num4; + numfree_1k = num1; + + /* + * Mark all memory as allocated. + */ + for ( i = 0; i < sizeof(alloc_array); i++ ) + { + alloc_array[i] = 0xff; + } + + /* + * Mark kernel memory as free. + */ + addr = ((dword_t) kmem_start + KMEM_1K_MASK) & ~KMEM_1K_MASK; + for ( i = (addr - ((dword_t) cpaddr & ~KMEM_1K_MASK)) >> KMEM_1K_SHIFT; + addr < ((dword_t) kmem_end & ~KMEM_1K_MASK); + addr += KMEM_1K_MASK+1, i++ ) + { + alloc_array[i>>3] &= ~(0x80 >> (i&3)); + } + + printf("Freelists initialized: %d*16K, %d*4K, %d*1K\n", + num16, num4, num1); +} + + +/* + * Function kmem_move_by_splitting (num, smaller_size, + * freelist_bigger, clusters_bigger, numfree_bigger, + * freelist_smaller, clusters_smaller, numfree_smaller) + * + * Move `num' frames from framelist of bigger frames into framelist + * of smaller frames. `smaller_size' is the size of the smaller + * frames. + * + */ +static int kmem_move_by_splitting(dword_t num, dword_t smaller_size, + pglink_t **freelist_bigger, + pglink_t **clusters_bigger, + dword_t *numfree_bigger, + pglink_t **freelist_smaller, + pglink_t **clusters_smaller, + dword_t *numfree_smaller) +{ + pglink_t *pg, *op, *pp; + int i, ret = 0; + + /* + * Loop until we have move `num' new pages of smaller size. + */ + while (num-- > 0) + { + pg = *freelist_bigger; + if ( pg ) { + /* Update freelist for bigger frames */ + *freelist_bigger = pg->next; + if ( pg->next ) + pg->next->prev = (pglink_t *) freelist_bigger; + + /* Update clusterlists */ + if ( clusters_bigger ) { + if ( *clusters_bigger == pg ) + *clusters_bigger = pg->next_cluster; + } + pg->next_cluster = *clusters_smaller; + *clusters_smaller = pg; + + /* Update freelist for smaller frames */ + op = *freelist_smaller; + pp = (pglink_t *) freelist_smaller; + for (i = 0; i < 4; i++, pg = pg->next) { + pg->next = (pglink_t *) ((dword_t) pg + smaller_size); + pg->prev = pp; + pp->next = pg; + pp = pg; + } + pp->next = op; + if ( op ) + op->prev = pp; + + /* Do accounting */ + *numfree_bigger -= 1; + *numfree_smaller += 4; + + ret++; + + } else { + /* + * No more free pages. Return number of new pages. + */ + return ret*4; + } + } + + return ret*4; +} + +#define kmem_move_16k_to_4k(num) \ + kmem_move_by_splitting((num), 4096, \ + (pglink_t **) &freelist_16k, \ + (pglink_t **) NULL, \ + (dword_t *) &numfree_16k, \ + (pglink_t **) &freelist_4k, \ + (pglink_t **) &cluster_4k, \ + (dword_t *) &numfree_4k) + +#define kmem_move_4k_to_1k(num) \ + kmem_move_by_splitting((num), 1024, \ + (pglink_t **) &freelist_4k, \ + (pglink_t **) &cluster_4k, \ + (dword_t *) &numfree_4k, \ + (pglink_t **) &freelist_1k, \ + (pglink_t **) &cluster_1k, \ + (dword_t *) &numfree_1k) + + + +/* + * Function kmem_move_by_concatenating (num, + * freelist_bigger, numfree_bigger, + * freelist_smaller, clusters_smaller, numfree_smaller) + * + * Move frames from freelist of smaller frames into freelist of + * bigger frames until we have `num' new bigger frames. + * + */ +static int kmem_move_by_concatenating(dword_t num, + pglink_t **freelist_bigger, + dword_t *numfree_bigger, + pglink_t **freelist_smaller, + pglink_t **clusters_smaller, + dword_t *numfree_smaller) +{ + pglink_t *pg, *pgn; + int ret = 0; + + /* + * Loop until we have moved `num' larger pages. + */ + while (num-- > 0) + { + pg = *clusters_smaller; + if ( pg ) { + /* Update smaller clusterlist */ + *clusters_smaller = pg->next_cluster; + + /* Update smaller freelist */ + if ( pg == *freelist_smaller ) + *freelist_smaller = *clusters_smaller; + pgn = pg->next_cluster; + if ( pgn ) + pgn->prev = pg->prev; + pg->prev->next = pgn; + + /* Update bigger freelist */ + pg->next = *freelist_bigger; + pg->prev = (pglink_t *) freelist_bigger; + *freelist_bigger = pg; + if ( pg->next ) + pg->next->prev = pg; + pg->next_cluster = (pglink_t *) NULL; + + /* Do accounting */ + *numfree_smaller -= 4; + *numfree_bigger += 1; + + ret++; + + } else { + /* + * No more clusters. Return number of new 16k pages. + */ + return ret; + } + } + + return ret; +} + +#define kmem_move_4k_to_16k(num) \ + kmem_move_by_concatenating((num), \ + (pglink_t **) &freelist_16k, \ + (dword_t *) &numfree_16k, \ + (pglink_t **) &freelist_4k, \ + (pglink_t **) &cluster_4k, \ + (dword_t *) &numfree_4k) + +#define kmem_move_1k_to_4k(num) \ + kmem_move_by_concatenating((num), \ + (pglink_t **) &freelist_4k, \ + (dword_t *) &numfree_4k, \ + (pglink_t **) &freelist_1k, \ + (pglink_t **) &cluster_1k, \ + (dword_t *) &numfree_1k) + + +/* + * Function kmem_alloc_16k () + * + * Allocate a 16 page and return it. + * + */ +ptr_t kmem_alloc_16k(void) +{ + pglink_t *pg, *np; + dword_t cpsr; + + cpsr = DISABLE_INTERRUPTS(); + + DBG_PRINTF("Allocated 16k\nE-"); + PRINT_STATUS(); + + /* + * Grab head of freelist. + */ + pg = (pglink_t *) freelist_16k; + if ( pg == NULL ) { + /* + * Ooops. No more free pages. Try to grab some pages from + * the 4k freelist. + */ + int num = numfree_4k > 20 ? 2 : 1; + + if ( kmem_move_4k_to_16k(num) == 0 ) { + panic("AIEEE! Unable to allocate 16k page.\n"); + } + + pg = (pglink_t *) freelist_16k; + } + np = pg->next; + freelist_16k = np; + if ( np != NULL ) + np->prev = (pglink_t *) &freelist_16k; + + /* + * Accounting. + */ + numfree_16k--; + + /* + * Mark page as allocated. + */ + ((uint16 *) alloc_array) + [ ((dword_t) pg - (dword_t)cpaddr) >> KMEM_16K_SHIFT ] = 0xffff; + + ENABLE_INTERRUPTS(cpsr); + + DBG_PRINTF("L-"); + PRINT_STATUS(); + + TRACE_ALLOC(); + return (ptr_t) pg; +} + + +/* + * Function kmem_free_16k (addr) + * + * Free the 16k page given in `addr'. + * + */ +void kmem_free_16k(dword_t addr) +{ + pglink_t *pg; + dword_t cpsr; + + cpsr = DISABLE_INTERRUPTS(); + + TRACE_FREE(); + DBG_PRINTF("Freed 16k\n"); + + /* + * Get addresses of the 16k frame. + */ + pg = (pglink_t *) (addr & KMEM_16K_MASK); + + /* + * Mark page as not allocated. + */ + ((uint16 *) alloc_array) + [ ((dword_t) pg - (dword_t) cpaddr) >> KMEM_16K_SHIFT ] = 0x0000; + + /* + * Insert into head of freelist. + */ + pg->next = (pglink_t *) freelist_16k; + pg->prev = (pglink_t *) &freelist_16k; + if ( pg->next ) + pg->next->prev = pg; + freelist_16k = pg; + + /* + * Accounting. + */ + numfree_4k++; + + ENABLE_INTERRUPTS(cpsr); +} + + +/* + * Function kmem_alloc_4k () + * + * Allocate a 4k page and return it. + * + */ +ptr_t kmem_alloc_4k(void) +{ + pglink_t *pg, *np; + dword_t cpsr; + + cpsr = DISABLE_INTERRUPTS(); + + DBG_PRINTF("Allocated 4k\nE-"); + PRINT_STATUS(); + + /* + * Grab head of freelist. + */ + pg = (pglink_t *) freelist_4k; + if ( pg == NULL ) { + /* + * Ooops. No more free pages. Try to grab some pages from + * the 16k or 1k freelists. + */ + int ok = 0; + + /* + * We prefer to split a 16k page (if the number of 1k pages is + * not extremely high, that is). + */ + if ( numfree_16k > 20*numfree_1k ) { + int num = numfree_16k > 5 ? 2 : 1; + ok = kmem_move_16k_to_4k(num); + } + + /* + * Did not split a 16k page. Grab some from the 1k freelist. + */ + if ( !ok ) { + int num = numfree_1k > 12 ? 2 : 1; + ok = kmem_move_1k_to_4k(num); + } + + /* + * As a last resort, we try to split a single 16k page. + */ + if ( !ok ) { + ok = kmem_move_16k_to_4k(1); + } + + if ( !ok ) { + panic("AIEEE! Unable to allocate 4k page.\n"); + } + + pg = (pglink_t *) freelist_4k; + } + np = pg->next; + freelist_4k = np; + if ( np != NULL ) + np->prev = (pglink_t *) &freelist_4k; + + /* + * Check if we have split a cluster. + */ + if ( cluster_4k == pg ) + cluster_4k = pg->next_cluster; + + /* + * Accounting. + */ + numfree_4k--; + + /* + * Mark page as allocated. + */ + alloc_array[ ((dword_t) pg - (dword_t) cpaddr) >> (KMEM_16K_SHIFT-1) ] |= + (dword_t) pg & (1 << KMEM_4K_SHIFT) ? 0xf0 : 0x0f; + + ENABLE_INTERRUPTS(cpsr); + + DBG_PRINTF("L-"); + PRINT_STATUS(); + printf("\n"); + + TRACE_ALLOC(); + return (ptr_t) pg; +} + + +/* + * Function kmem_free_4k (addr) + * + * Free the 4k page given in `addr'. Try to cluster consecutive 4k + * pages into a cluster of 16k. It is an error to free a 4k page + * within a page that was allocated using kmem_alloc_16k(). + * + */ +void kmem_free_4k(dword_t addr) +{ + pglink_t *pg, *np, *pp, *cp; + dword_t pg16, cpsr; + uint16 allocs; + + cpsr = DISABLE_INTERRUPTS(); + + TRACE_FREE(); + DBG_PRINTF("Freed 4k\n"); + + /* + * Get addresses of the 4k frame, and the 16k frame which the page + * might belong to (when clustered). + */ + pg = (pglink_t *) (addr & KMEM_4K_MASK); + pg16 = addr & KMEM_16K_MASK; + + /* + * Mark page as not allocated. + */ + alloc_array[ ((dword_t) pg - (dword_t) cpaddr) >> (KMEM_16K_SHIFT-1) ] &= + (dword_t) pg & (1 << KMEM_4K_SHIFT) ? ~0xf0 : ~0x0f; + + allocs = ((uint16 *) alloc_array) + [ ((dword_t) pg - (dword_t) cpaddr) >> KMEM_16K_SHIFT ]; + + + /* + * Check if we have 4 consecutive pages (i.e. a 16k page). + */ + switch (((dword_t) pg >> KMEM_16K_SHIFT) & 0x02) { + default: + case 0: + /* + * Page is first in cluster. + */ + np = (pglink_t *) (pg16 + 4096); + if ( ~allocs & 0x0f00 ) + goto Hook_before_next; + goto Hook_into_head; + + case 1: + /* + * Page is second in cluster. + */ + pp = (pglink_t *) pg16; + if ( ~allocs & 0xf000 ) + goto Hook_after_previous; + np = (pglink_t *) (pg16 + 2*4096); + if ( ~allocs & 0x00f0 ) { + goto Hook_before_next; + } + goto Hook_into_head; + + case 2: + /* + * Page is third in cluster. + */ + pp = (pglink_t *) (pg16 + 4096); + if ( ~allocs & 0x0f00 ) + goto Hook_after_previous; + np = (pglink_t *) (pg16 + 3*4096); + if ( ~allocs & 0x000f ) + goto Hook_before_next; + goto Hook_into_head; + + case 3: + /* + * Page is last in cluster. + */ + pp = (pglink_t *) (pg16 + 2*4096); + if ( ~allocs & 0x00f0 ) + goto Hook_after_previous; + goto Hook_into_head; + + Hook_after_previous: + pg->next = pp->next; + pg->prev = pp; + if ( pg->next ) + pg->next->prev = pg; + pp->next = pg; + break; + + Hook_before_next: + pg->next = np; + pg->prev = np->prev; + np->prev = pg; + if ( freelist_4k == np ) + freelist_4k = pg; + else + pg->prev->next = pg; + break; + + Hook_into_head: + pg->next = (pglink_t *) freelist_4k; + pg->prev = (pglink_t *) &freelist_4k; + if ( pg->next ) + pg->next->prev = pg; + freelist_4k = pg; + break; + } + + /* + * Update cluster (if all four frames in cluster has been freed). + */ + if ( allocs == 0x0000 ) { + cp = (pglink_t *) pg16; + cp->next_cluster = (pglink_t *) cluster_4k; + cluster_4k = cp; + } + + /* + * Accounting. + */ + numfree_4k++; + + ENABLE_INTERRUPTS(cpsr); +} + + +/* + * Function kmem_alloc_1k () + * + * Allocate a 1k page and return it. + * + */ +ptr_t kmem_alloc_1k(void) +{ + pglink_t *pg, *np; + dword_t cpsr; + + cpsr = DISABLE_INTERRUPTS(); + + DBG_PRINTF("Allocated 1k\nE-"); + PRINT_STATUS(); + + /* + * Grab head of freelist. + */ + pg = (pglink_t *) freelist_1k; + if ( pg == NULL ) { + /* + * Ooops. No more free pages. Try to grab some pages from + * the 4k freelists. + */ + int num = numfree_4k > 15 ? 2 : 1; + + if ( kmem_move_4k_to_1k(num) == 0 ) { + /* + * It might be that there are some free 16k pages. + */ + kmem_move_16k_to_4k(2); + if ( kmem_move_4k_to_1k(2) == 0 ) { + panic("AIEEE! Unable to allocate 1k page.\n"); + } + } + + pg = (pglink_t *) freelist_1k; + } + np = pg->next; + freelist_1k = np; + if ( np != NULL ) + np->prev = (pglink_t *) &freelist_1k; + + /* + * Check if we have split a cluster. + */ + if ( cluster_1k == pg ) + cluster_1k = pg->next_cluster; + + /* + * Accounting. + */ + numfree_1k--; + + /* + * Mark page as allocated. + */ + alloc_array[ ((dword_t) pg - (dword_t) cpaddr) >> (KMEM_16K_SHIFT-1) ] |= + 0x80 >> (((dword_t) pg >> KMEM_1K_SHIFT) & 0x03); + + ENABLE_INTERRUPTS(cpsr); + + DBG_PRINTF("L-"); + PRINT_STATUS(); + + TRACE_ALLOC(); + return (ptr_t) pg; +} + + +/* + * Delay this implementation until 4k free function has been sanity + * checked. + */ +void kmem_free_1k(dword_t addr) +{ + pglink_t *pg; + + TRACE_FREE(); + + pg = (pglink_t *) (addr & KMEM_1K_MASK); + + /* + * Mark page as not allocated. + */ + alloc_array[ ((dword_t) pg - (dword_t) cpaddr) >> (KMEM_16K_SHIFT-1) ] |= + ~(0x80 >> (((dword_t) pg >> KMEM_1K_SHIFT) & 0x03)); + + printf("Freeing 1k page at 0x%x [Not implemented yet]\n", (int) addr); +} + + +#endif /* CONFIG_HAVE_ARCH_KMEM */ diff --git a/kernel/src/arm/kmemory.o b/kernel/src/arm/kmemory.o new file mode 100644 index 0000000..e765c8f Binary files /dev/null and b/kernel/src/arm/kmemory.o differ diff --git a/kernel/src/arm/libarch.a b/kernel/src/arm/libarch.a new file mode 100644 index 0000000..317a3d6 Binary files /dev/null and b/kernel/src/arm/libarch.a differ diff --git a/kernel/src/arm/mapping.c b/kernel/src/arm/mapping.c new file mode 100644 index 0000000..78ad1a8 --- /dev/null +++ b/kernel/src/arm/mapping.c @@ -0,0 +1,32 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: arm/mapping.c + * Description: Mapping specifications for the ARM. + * + * @LICENSE@ + * + * $Id: mapping.c,v 1.3 2001/11/22 13:18:48 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +dword_t mdb_pgshifts[5] = { + 10, // 1KB + 12, // 4KB + 16, // 64KB + 20, // 1MB + 32 // 4GB (whole address space) +}; + +mdb_buflist_t mdb_buflists[6] = { + { 12 }, // Mapping nodes + { 8 }, // ptrnode_t + { 64 }, // 64KB array, 4KB array + { 16 }, // 1KB array + { 16384 }, // 1MB array + { 0 } +}; + diff --git a/kernel/src/arm/mapping.o b/kernel/src/arm/mapping.o new file mode 100644 index 0000000..8f152b3 Binary files /dev/null and b/kernel/src/arm/mapping.o differ diff --git a/kernel/src/arm/memory.c b/kernel/src/arm/memory.c new file mode 100644 index 0000000..756dbef --- /dev/null +++ b/kernel/src/arm/memory.c @@ -0,0 +1,425 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: arm/memory.c + * Description: ARM specific memory management. + * + * @LICENSE@ + * + * $Id: memory.c,v 1.37 2001/12/12 23:47:06 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(memory.h) +#include INC_PLATFORM(platform.h) +#include +#include INC_ARCH(syscalls.h) +#include INC_ARCH(farcalls.h) +#include + +//#define DOUBLE_PF_CHECK + +dword_t* kernel_ptdir = NULL; + +dword_t hw_pgshifts[HW_NUM_PGSIZES+1] = { 12, 16, 20, 32 }; + + +#ifdef DOUBLE_PF_CHECK +static dword_t last_pf = ~0; +#endif + + +void arm_map_page (space_t * space, dword_t vaddr, dword_t paddr, + dword_t ap, dword_t pgsize) +{ +// printf("arm_map_page(space=%p, vaddr=%p, paddr=%p, ap=%x, pgsize=%x)\n", +// space, vaddr, paddr, ap, pgsize); + + dword_t remap = 0; + dword_t pgsz = HW_NUM_PGSIZES-1; + pgent_t *pg = space->pgent (vaddr >> PAGE_SECTION_BITS); + + while (pgsz > pgsize) + { + if (!pg->is_valid (space, pgsz)) + pg->make_subtree (space, pgsz); + else if (!pg->is_subtree (space, pgsz)) + panic("arm_map_page(): Mapping is no subtree.\n"); + + pgsz--; + pg = pg->subtree (space, pgsz+1)->next (space, table_index (vaddr, pgsz), pgsz); + } + + remap = pg->is_valid (space, pgsize); + pg->set_entry (space, paddr, 0, pgsize); + pg->set_access_bits (space, pgsize, ap, 1, 1); + + if (remap) + flush_tlbent ((ptr_t) vaddr); +} + +space_t * create_space (void) +{ + // allocate root ptab + fld_t* new_ptdir = (fld_t*) kmem_alloc(FLD_SIZE*2); + + /* copy kernel area (TCBs, cont. phys mem, kernel code/data */ + for (dword_t i = vaddr_to_fld(TCB_AREA); + i <= vaddr_to_fld(0xFFFFFFFF); + i++) + new_ptdir[i] = ((fld_t *) kernel_ptdir)[i]; + +#ifndef EXCEPTION_VECTOR_RELOCATED +#warning HACK + + /* allocate second level pagetable */ + sld_t* ptbl = (sld_t*) kmem_alloc(SLD_SIZE); + /* copy section entry from kernel pagetable */ + new_ptdir[0] = ((fld_t *) kernel_ptdir)[0]; + /* install second level pagetable instead */ + new_ptdir[0].page.ptba = paddr_to_ptba(virt_to_phys((dword_t)ptbl)); + /* copy entry for exception vector page */ + *((sld_t*) phys_to_virt(ptba_to_paddr(new_ptdir[0].page.ptba))) = *((sld_t*) phys_to_virt(ptba_to_paddr(((fld_t *) kernel_ptdir)[0].page.ptba))); +#endif + + +// printf("%s: new ptgable at %p\n", __FUNCTION__, new_ptdir); + return (space_t *) virt_to_phys(new_ptdir); +} + + +void delete_space (space_t * space) +{ + printf(" %s: %p\n", __FUNCTION__, space); + + fpage_unmap (space, FPAGE_WHOLE_SPACE, (FPAGE_OWN_SPACE|FPAGE_FLUSH)); + + fld_t* pd = (fld_t*) space->pagedir (); + + /* kmem_free all 2nd level pagetables */ + for (dword_t i = 0; i < TCB_AREA; i += (1 << FLD_SHIFT)) + if (fld_type (&pd[vaddr_to_fld (i)]) == FLD_PAGE) + kmem_free ((dword_t *) phys_to_virt + (ptba_to_paddr (pd[vaddr_to_fld (i)].page.ptba)), + SLD_SIZE); + + /* kmem_free the page table directory */ + kmem_free ((ptr_t) pd, FLD_SIZE*2); +} + + + +/* + * Function kernel_data_abort (fault_status, fault_address) + * + * Handle data aborts within the kernel. Usually this means that + * we have to handle some TLB mapping. If this is not the case, we + * should panic big time. + * + */ +void kernel_pagefault(dword_t fault_status, dword_t fault_address, dword_t ip) +{ +#ifdef CONFIG_DEBUG_TRACE_KPF + if (__kdebug_pf_tracing) + { + printf("kpf: thread: %x @ %x ip: %x, fsr: %x, ptab: %x\n", + get_current_tcb(), fault_address, ip, + fault_status, get_current_pagetable()); + if (__kdebug_pf_tracing > 1) + enter_kdebug("kpf"); + } +#endif +#ifdef DOUBLE_PF_CHECK + if (last_pf == fault_address) { + enter_kdebug("double pagefault"); + } + last_pf = fault_address; +#endif + + space_t * kspace = get_kernel_space (); + + /* Only by reading the instruction and checking for the L-bit (20) + we can find out whether we had a read or a write pagefault. + Inside the kernel we'll never have instruction fetch faults. */ + dword_t read_fault = *((ptr_t) ip) & (1 << 20); + + /* Keep only the interesting bits. */ + fault_status &= STATUS_MASK; + + if ( (fault_address >= TCB_AREA) && + (fault_address < (TCB_AREA + TCB_AREA_SIZE)) ) + { + /* + * Fault_address is in TCB region. + */ + if ( fault_status == TRANSLATION_FAULT_S ) + { + pgent_t *kpg = (pgent_t *) kernel_ptdir; + pgent_t *cpg = (pgent_t *) phys_to_virt(get_current_pagetable()); + pgent_t *pg; + + kpg += fault_address >> PAGE_SECTION_BITS; + cpg += fault_address >> PAGE_SECTION_BITS; + + /* First level fault - lookup in kernel pagetable. */ + if ( kpg->is_valid (kspace, PGSIZE_1MB) ) + { + /* Found in kernel pagetable. */ + cpg->x.raw = kpg->x.raw; + + /* If a 4K mapping exists, just return. */ + pg = (pgent_t *) phys_to_virt(kpg->x.raw & PAGE_TABLE_MASK); + pg += (fault_address & ~PAGE_SECTION_MASK) >> PAGE_SMALL_BITS; + + if ( (pg->x.raw & PAGE_TYPE_MASK) == 2 ) + return; + } + else + { + /* Have to allocate 2nd level array. */ + pg = (pgent_t *) kmem_alloc(1024); + + cpg->x.raw = (dword_t) virt_to_phys(pg) | 0x01; + for( int i = 0; i < 256; i++ ) + pg[i].x.raw = PAGE_64K_VALID; + + /* Update kernel pagetable. */ + kpg->x.raw = cpg->x.raw; + } + } + + if (read_fault) + { + TRACEPOINT (MAP_ZERO_PAGE, + printf ("map zero page (%p @ %p)\n", + fault_address, ip)); + + /* Map in the zero page READ-ONLY */ + arm_map_page (kspace, fault_address, + (dword_t) virt_to_phys (__zero_page), + PAGE_AP_RESTRICTED, PGSIZE_4KB); + return; + } + else + { + TRACEPOINT (MAP_NEW_TCB, + printf ("map TCB page (%p @ %p)\n", + fault_address, ip)); + + /* Map in a fresh tcb page. */ + arm_map_page (kspace, fault_address, + (dword_t) virt_to_phys(kmem_alloc(PAGE_SMALL_SIZE)), + PAGE_AP_NOACCESS, PGSIZE_4KB); + + /* Get rid of zero-page entries. */ + flush_tlbent ((ptr_t) fault_address); +#warning Avoid Flush_ID_Cache + Flush_ID_Cache(); + return; + } + + } + + if (fault_address >= MEM_COPYAREA1 && fault_address < MEM_COPYAREA_END) + { + tcb_t* current = get_current_tcb(); + tcb_t * partner = tid_to_tcb(current->partner); + ptr_t pdir_from = current->space->pagedir (); + ptr_t pdir_to = partner->space->pagedir (); + + dword_t *saved_stack; + + printf("fault in copy area %x @ %x\n", current, fault_address); + + if (fault_address < MEM_COPYAREA2) + { + if (current->resources & TR_IPC_MEM1) + { + /* pagefault */ + //printf("tunneled pf ipc1\n"); + //enter_kdebug(); + + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area1 + (fault_address - MEM_COPYAREA1), + (dword_t)current); + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + /* xxx: should we: thread_enqueue_ready(partner); */ + dispatch_thread(partner); + //printf("tunneled pf done\n"); + partner->stack = saved_stack; + + /* we did an IPC here with a thread switch - the pagetable + * entries of the copy area are gone -> we would directly + * pagefault -> so run into the pagedir update... + */ + } + + pdir_from[MEM_COPYAREA1 >> PAGEDIR_BITS] = pdir_to[current->copy_area1 >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA1 >> PAGEDIR_BITS) + 1] = pdir_to[(current->copy_area1 >> PAGEDIR_BITS) + 1]; + current->resources |= TR_IPC_MEM1; + return; + } + else + { + printf("fault in copy area %x @ %x\n", current, fault_address); + + if (current->resources & TR_IPC_MEM2) + { + /* pagefault */ + //printf("tunneled pf ipc2\n"); + //enter_kdebug(); + + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area2 + (fault_address - MEM_COPYAREA2), + (dword_t)current); + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + /* xxx: should we: thread_enqueue_ready(partner); */ + dispatch_thread(partner); + //printf("tunneled pf2 done\n"); + partner->stack = saved_stack; + } + + /* see comment above */ + pdir_from[MEM_COPYAREA2 >> PAGEDIR_BITS] = pdir_to[current->copy_area2 >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = pdir_to[(current->copy_area2 >> PAGEDIR_BITS) + 1]; + current->resources |= TR_IPC_MEM2; + return; + } + } + panic( "Whooiips. Data abort within kernel.\n" ); +} + + +/* + * Function user_pagefault (fault_status, fault_address, ip) + * + * Handle data aborts within user level. This will usually + * generate a pagefault IPC. The exception is pagefaults within + * sigma0 which will cause a 1MB page to be mapped. + * + */ +void user_pagefault(dword_t fault_status, dword_t fault_address, dword_t ip) +{ + tcb_t *current = get_current_tcb(); + +#ifdef CONFIG_DEBUG_TRACE_UPF + if (__kdebug_pf_tracing) + { + printf("upf: thread: %x @ %x ip: %x, fsr: %x, ptab: %x\n", + current, fault_address, ip, + fault_status, get_current_pagetable()); + if (__kdebug_pf_tracing > 1) + enter_kdebug("upf"); + } +#endif + + TRACEPOINT_2PAR(KERNEL_USER_PF, fault, ip, + printf("upf: thread: %x @ %x ip: %x, fsr: %x, ptab: %x\n", + current, fault_address, ip, + fault_status, get_current_pagetable())); + +#ifdef DOUBLE_PF_CHECK + if (last_pf == fault_address) { + enter_kdebug("double pagefault"); + } + last_pf = fault_address; +#endif + + /* Figure out whether we're dealing with a write fault or not. */ + fault_status &= STATUS_MASK; + fault_address &= ~3; + fault_address |= ((fault_status == PERMISSION_FAULT_S) || + (fault_status == PERMISSION_FAULT_P)) ? 2 : 0; + + if ( !IN_KERNEL_AREA(fault_address) ) + { + if ( same_address_space(sigma0, current) ) + { + /* + * Sigma0 pagefaults will just cause the page tables to be + * populated with 1MB pages. We bypass the mdb_map() + * because sigma0 is already defined to own the whole + * address space. + */ + arm_map_page (current->space, fault_address, fault_address, + PAGE_AP_WRITABLE, PGSIZE_1MB); + return; + } + + /* Other tasks will generate a pagefault IPC to their pager. */ + current->ipc_timeout = TIMEOUT_NEVER; + do_pagefault_ipc(current, fault_address, ip); + return; + } + + panic(__FUNCTION__); +} + + + + + + + +/********************************************************************** + * temporary mapping for IPC + * the resource bits are set in the pagefault handler!!! + */ + +ptr_t get_copy_area(tcb_t * from, tcb_t * to, ptr_t addr) +{ + //printf("%s: %x->%x, %x\n", __FUNCTION__, from, to, addr); + //enter_kdebug(); + + if (from->copy_area1 == COPYAREA_INVALID) + { + /* nothing mapped yet */ + from->copy_area1 = ((dword_t)addr & PAGEDIR_MASK); + return (ptr_t)(((dword_t)addr & ~PAGEDIR_MASK) + MEM_COPYAREA1); + } + else { + if (from->copy_area1 == ((dword_t)addr & PAGEDIR_MASK)) + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA1); + else if (from->copy_area2 == ((dword_t)addr & PAGEDIR_MASK)) + { + /* works for invalid too :) */ + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + else + { + if (from->resources & TR_IPC_MEM2) + { + /* resource area 2 in use -> worst case + * we have to manipulate the pagetable + */ + enter_kdebug("remap copy_area2"); + + ptr_t pdir_from = from->space->pagedir (); + ptr_t pdir_to = tid_to_tcb (from->partner)->space->pagedir (); + pdir_from[MEM_COPYAREA2 >> PAGEDIR_BITS] = pdir_to[(dword_t)addr >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = pdir_to[((dword_t)addr >> PAGEDIR_BITS) + 1]; + + flush_tlb(); + } + + from->copy_area2 = ((dword_t)addr) & PAGEDIR_MASK; + //printf("copy_area2: %x\n",from->copy_area2); + //from->resources |= TR_IPC_MEM2; + + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + } + + return 0; +} + +void free_copy_area(tcb_t * tcb) +{ + tcb->copy_area1 = COPYAREA_INVALID; + tcb->copy_area2 = COPYAREA_INVALID; +} diff --git a/kernel/src/arm/memory.o b/kernel/src/arm/memory.o new file mode 100644 index 0000000..00e0df3 Binary files /dev/null and b/kernel/src/arm/memory.o differ diff --git a/kernel/src/arm/pleb/.cvsignore b/kernel/src/arm/pleb/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/arm/pleb/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/arm/pleb/Makefile b/kernel/src/arm/pleb/Makefile new file mode 100644 index 0000000..d90266f --- /dev/null +++ b/kernel/src/arm/pleb/Makefile @@ -0,0 +1,29 @@ +###################################################################### +## +## Copyright (C) 2002, Karlsruhe University +## +## File path: arm/pleb/Makefile +## Description: +## +## @LICENSE@ +## +## $Id: Makefile,v 1.1 2002/01/24 20:20:06 ud3 Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c interrupt.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/arm/pleb/init.c b/kernel/src/arm/pleb/init.c new file mode 100644 index 0000000..201c7bd --- /dev/null +++ b/kernel/src/arm/pleb/init.c @@ -0,0 +1,154 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/init.c + * Description: PLEB-specific initialization + * + * @LICENSE@ + * + * $Id: init.c,v 1.2 2002/01/24 20:24:25 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_ARCH(memory.h) +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + +void setup_kernel_pgtable(void) L4_SECT_INIT; +void init_platform(void) L4_SECT_INIT; +void init_timer(void) L4_SECT_INIT; +void init_irqs(void) L4_SECT_INIT; + + +extern dword_t _start_init[]; +extern dword_t text_paddr[]; +extern dword_t text_vaddr[]; + + +/* + * Function setup_kernel_pgtable () + * + * Create initial pagetable. This should contain everything we + * need in order to run the kernel. When the function returns, it + * should be safe to enable the MMU. + * + */ +void setup_kernel_pgtable(void) +{ + dword_t i; + fld_section_t *segment; + fld_page_t *page; + sld_largepage_t *large_page; + sld_smallpage_t *small_page; + + /* Zero out 1st Level Array */ + for(i = 0; i < FLD_MAX; i++) + kernel_ptdir_p[i].init = 0; + + /* + * Map in Init segment + */ + segment = (fld_section_t *) kernel_ptdir_p + + vaddr_to_fld((dword_t) _start_init); + segment->type = FLD_SECTION; /* 1st level segment entry */ + segment->ap = AP_NOACCESS; /* Kernel access only */ + segment->sba = paddr_to_sba((dword_t) _start_init); /* Address of 1MB Fr */ + + /* + * Map in Text segment + */ + + /* Add 1st level entry */ + page = (fld_page_t *) kernel_ptdir_p + vaddr_to_fld((dword_t) text_vaddr); + page->type = FLD_PAGE; + page->ptba = paddr_to_ptba((dword_t) kernel_pgtable_p); + + /* Zero out 2nd level array */ + for(i = 0; i < SLD_MAX; i++) + kernel_pgtable_p[i].init = 0; + + /* Add 2nd level entry */ + large_page = (sld_largepage_t *) kernel_pgtable_p + + vaddr_to_sld(0xFFFF0000 & (dword_t) text_vaddr); + large_page->type = SLD_LARGE; + large_page->buf = TRUE; + large_page->cache = TRUE; + large_page->ap0 = AP_NOACCESS; + large_page->ap1 = AP_NOACCESS; + large_page->ap2 = AP_NOACCESS; + large_page->ap3 = AP_NOACCESS; + large_page->lpba = paddr_to_lpba(0xFFFF0000 & (dword_t) text_paddr); + + /* Copy entry (required for large pages) */ + for(i = 1; i < LRG_ENTS; i++) + *(large_page + i) = *large_page; + + /* + * Map in Interrupt Controller registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(INTCTRL_VBASE); + small_page->type = SLD_SMALL; + small_page->ap0 = AP_NOACCESS; + small_page->ap1 = AP_NOACCESS; + small_page->ap2 = AP_NOACCESS; + small_page->ap3 = AP_NOACCESS; + small_page->spba = paddr_to_spba(INTCTRL_PBASE); + + /* + * Map in OS Timer registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(OSTIMER_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(OSTIMER_PBASE); + + /* + * Map in UART Serial Port registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(UART_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(UART_PBASE); + small_page->ap0 = AP_ALLACCESS; + small_page->ap1 = AP_ALLACCESS; + small_page->ap2 = AP_ALLACCESS; + small_page->ap3 = AP_ALLACCESS; + + /* + * Map in GPIO registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(GPIO_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(GPIO_PBASE); + + /* + * Map Reset Controller Registers + */ + small_page = (sld_smallpage_t *) kernel_pgtable_p + + vaddr_to_sld(RSTCTL_VBASE); + *(small_page) = kernel_pgtable_p[vaddr_to_sld(INTCTRL_VBASE)].small; + small_page->spba = paddr_to_spba(RSTCTL_PBASE); + + /* Map in Contiguous RAM */ + segment = (fld_section_t *)kernel_ptdir_p + vaddr_to_fld(cpaddr); +#if ((cpaddr + PHYS_DRAMSIZE) < cpaddr) +#error: Too much memory +#endif + for (i = cpaddr; i < cpaddr+DRAM_SIZE; i+=0x100000) /* in steps of 1M */ + { + segment->sba = paddr_to_sba(virt_to_phys(i)); + segment->type = FLD_SECTION; /* 1st Level Segment Entry */ + segment->ap = AP_NOACCESS; /* Kernel Access only */ + segment++; + }; +} + + +void init_platform() +{ + init_irqs(); + init_timer(); +} diff --git a/kernel/src/arm/pleb/interrupt.c b/kernel/src/arm/pleb/interrupt.c new file mode 100644 index 0000000..877a49f --- /dev/null +++ b/kernel/src/arm/pleb/interrupt.c @@ -0,0 +1,136 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/interrupt.c + * Description: PLEB-specific interrupt/timer stuff + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.1 2002/01/24 20:20:06 ud3 Exp $ + * + ********************************************************************/ +#include + +#include +#include INC_ARCH(farcalls.h) +#include INC_PLATFORM(platform.h) + + +void init_irqs(void) L4_SECT_INIT; +void init_timer() L4_SECT_INIT; + + +/* + * Function init_irqs () + * + * Initialize interrupt handling for the SA-1100. + * + */ +void init_irqs(void) +{ + /* + * Set all interrupts to generate IRQs rather than FIQs. + */ + ICLR = 0x00000000; + + /* + * Only enabled and unmasked interrupts will bring CPU out of idle + * mode. + */ + ICCR = 1; + + /* + * Acknowledge any pending interrupts. + */ + ICIP = 0xffffffff; + ICFP = 0xffffffff; + + /* + * Enable interrupts from ostimer0. + */ + ICMR = INTR_OSTIMER0; +} + + +/* + * Function init_timer () + * + * Initialize the SA-1100 operating system timer. + * + */ +void init_timer(void) +{ + /* Clear all OS-timer matches */ + OSSR = 0x0f; + + /* Acknowledge pending OS Timer 0 interrupt */ + ICIP = INTR_OSTIMER0; + + /* Enable OS Timer 0 */ + OIER = 0x01; + + OSMR0 = OSCR + (18432000 >> 2); /* Wait 5/4 sec */ +} + + +void irq_handler(dword_t spsr) +{ + dword_t m, i, icip = ICIP, icmr = ICMR; + + /* Timer match 0 interrupt, don't care if it's masked out */ + if ( icip & INTR_OSTIMER0 ) + { +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('T'); +#endif + + OSMR0 = OSCR + (CLOCK_FREQUENCY/1024) * (TIME_QUANTUM/1024); + + OSSR = 0x01; + ICIP = INTR_OSTIMER0; + + handle_timer_interrupt(); + return; + } + + /* other interrupts, must check mask register too */ + for ( i = 31, m = (1 << 31); !(m & icmr & icip) && m; m >>= 1, i-- ); + +#if defined(CONFIG_DEBUG_TRACE_IRQS) + putc('\n'); + putc('0'+i); +#endif + + if ( m == 0 ) + { + printf("No interrupt pending\n"); + enter_kdebug(); + return; + } + + /* will be unmasked again by next ipc wait */ + mask_interrupt(i); + + handle_interrupt(i); +} + + +void mask_interrupt(dword_t num) +{ +#if defined(CONFIG_DEBUG_TRACE_IRQS) + printf("MASKing %d\n", num); +#endif + + ICMR &= ~(1 << num); +} + +void unmask_interrupt(dword_t num) +{ + // do nothing - no automatic irq acking??? +#if defined(CONFIG_DEBUG_TRACE_IRQS) + printf("unmasking %d\n", num); +#endif + + ICMR |= (1 << num); +} diff --git a/kernel/src/arm/pleb/startup.S b/kernel/src/arm/pleb/startup.S new file mode 100644 index 0000000..c5055a4 --- /dev/null +++ b/kernel/src/arm/pleb/startup.S @@ -0,0 +1,61 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: arm/pleb/startup.S + * Description: Startup code for the PLEB + * + * @LICENSE@ + * + * $Id: startup.S,v 1.1 2002/01/24 20:20:06 ud3 Exp $ + * + ********************************************************************/ +#include +#include INC_PLATFORM(platform.h) +#include INC_ARCH(cpu.h) + + .globl _start + .section .init,"xa" +_start: + /* Switch to abort mode */ + mov r0, #(IRQ_MASK|FIQ_MASK|KERNEL_MODE) + msr cpsr, r0 + + /* reset spsr */ + mov r0, #0xd3 + msr spsr, r0 + + /* Initialize stack pointer */ + ldr sp, 5f + + /* Build the initial page table */ + bl setup_kernel_pgtable__Fv + + /* Enable the MMU */ + ldr r0, 1f + mcr p15, 0, r0, c2, c0 @ Set Translation Table Base + mov r0, #0x00000005 + mcr p15, 0, r0, c3, c0 @ Access checking for Domain 1 + ldr r0, 2f + mcr p15, 0, r0, c1, c0 @ Enable the MMU + nop + nop + nop + + /* Call init() */ + ldr pc, 4f + +1: .word kernel_ptdir_p +#ifdef EXCEPTION_VECTOR_RELOCATED +2: .word (CTL_MMU_ENABLED | CTL_SYS_PROT | CTL_IVECTOR) +#else +2: .word (CTL_MMU_ENABLED | CTL_SYS_PROT) +#endif +3: .word kernel_ptdir +4: .word init__Fv +5: .word _stack_top + + /* Initializtation stack */ +_stack_bottom: + .space 4096 +_stack_top: diff --git a/kernel/src/arm/resources.c b/kernel/src/arm/resources.c new file mode 100644 index 0000000..6ec7391 --- /dev/null +++ b/kernel/src/arm/resources.c @@ -0,0 +1,59 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: arm/resources.c + * Description: Thread resource management for ARM. + * + * @LICENSE@ + * + * $Id: resources.c,v 1.1 2001/12/07 19:05:43 skoglund Exp $ + * + ********************************************************************/ + +#include +#include +#include + +void save_resources (tcb_t *current, tcb_t *dest) +{ + TRACEPOINT (SAVE_RESOURCES, printf ("save_resources: tcb=%p rc=%p\n", + current, current->resources)); + + if (current->resources | TR_IPC_MEM) + { + ptr_t pdir = current->space->pagedir (); + pdir[MEM_COPYAREA1 >> PAGEDIR_BITS] = 0; + pdir[(MEM_COPYAREA1 >> PAGEDIR_BITS) + 1] = 0; + + pdir[MEM_COPYAREA2 >> PAGEDIR_BITS] = 0; + pdir[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = 0; + + if ((dest == get_idle_tcb ()) || same_address_space (current, dest)) + flush_tlb (); + } + + current->resources = 0; +} + +void purge_resources (tcb_t * tcb) +{ + TRACEPOINT (PURGE_RESOURCES, printf("purge_resources: tcb=%p\n", tcb)); +} + + +void load_resources (tcb_t *current) +{ + TRACEPOINT (LOAD_RESOURCES, printf ("load_resources: tcb=%p rc=%p\n", + current, current->resources)); +} + + +void init_resources (tcb_t * tcb) +{ +} + +void free_resources (tcb_t * tcb) +{ +} + diff --git a/kernel/src/arm/resources.o b/kernel/src/arm/resources.o new file mode 100644 index 0000000..e2a354a Binary files /dev/null and b/kernel/src/arm/resources.o differ diff --git a/kernel/src/global.c b/kernel/src/global.c new file mode 100644 index 0000000..8c783bc --- /dev/null +++ b/kernel/src/global.c @@ -0,0 +1,54 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: global.c + * Description: Data structures having no other logical place. + * + * @LICENSE@ + * + * $Id: global.c,v 1.10 2001/11/22 13:04:52 skoglund Exp $ + * + ********************************************************************/ +#include + +extern dword_t _end_text_p; +extern dword_t text_paddr; +kernel_info_page_t kernel_info_page __attribute__((aligned(PAGE_SIZE))) = +{ + {'L','4',0xE6,'K'}, /* magic */ + 0x4711, /* version */ + {0}, /* reserved */ +#if defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB) + kdebug_init,NULL,0,0, /* kdebug */ +#else + 0,0,0,0, /* kdebug */ +#endif +#if defined(CONFIG_SIGMA0_ENTRY) + CONFIG_SIGMA0_SP,CONFIG_SIGMA0_IP, /* sigma0 sp,ip */ +#else + 0,0xFFFFFFFF, /* sigma0 sp,ip */ +#endif + 0,0, + + 0,0xFFFFFFFF,0,0, /* sigma1 */ + +#if defined(CONFIG_ROOTTASK_ENTRY) + CONFIG_ROOTTASK_SP,CONFIG_ROOTTASK_IP, /* root task sp,ip */ +#else + 0,0xFFFFFFFF, /* root task sp,ip */ +#endif + 0,0, + + 0, /* L4 config */ + + 0, 0, 0, + + 0, 32*1024*1024, /* main mem */ + (dword_t) &text_paddr, (dword_t) &_end_text_p,/* rsvd mem0 - kcode */ + (32-4)*1024*1024, 32*1024*1024, /* rsvd mem1 - kdata */ + 640*1024, 1024*1024, /* dedi mem0 - adapter */ +}; + + + diff --git a/kernel/src/global.o b/kernel/src/global.o new file mode 100644 index 0000000..ef91699 Binary files /dev/null and b/kernel/src/global.o differ diff --git a/kernel/src/init.c b/kernel/src/init.c new file mode 100644 index 0000000..d9ea481 --- /dev/null +++ b/kernel/src/init.c @@ -0,0 +1,86 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: init.c + * Description: Architecture independent initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.26 2001/11/22 15:10:32 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +#if defined(NEED_FARCALLS) +#include INC_ARCH(farcalls.h) +#endif + +void init(void) L4_SECT_INIT; +void init_startup_servers(void) L4_SECT_INIT; +void setup_excp_vector(void) L4_SECT_INIT; + +ptr_t __zero_page = NULL; + +ptr_t kernel_arg; + +/* + * Function init () + * + * Main initialization function for kernel. When the function is + * invoked, the MMU is enabled with the whole memory space mapped + * idempotently. + * + */ +void init(void) +{ + /* first init kdebug to see what's going on */ + if (kernel_info_page.kdebug_init) + kernel_info_page.kdebug_init(); + + printf(kernel_version); + + /* basic architecture initialization */ + init_arch_1(); + + /* Initialize kernel memory allocator */ + kmem_init(); + + /* map and initialize exception vector */ + /* so it is waterproof for everything afterwards :-) */ + setup_excp_vector(); + + /* Initialize mapping database */ + mdb_init(); + + /* reset the internal clock */ + kernel_info_page.clock = 0; + + /* Initialize interrupts */ + interrupts_init(); + +#if defined(CONFIG_ENABLE_PROFILING) + /* Should be initialized before entering kdebug below. */ + void kdebug_init_profiling(void) L4_SECT_KDEBUG; + kdebug_init_profiling(); +#endif + + /* We create the idle thread here so that we have something to + fall back into when entering kdebug. */ + tcb_t *idle = create_idle_thread(); + + /* Architcture initialization needed before kdebug entry. */ + init_arch_2(); + +#if defined CONFIG_DEBUG_KDB_ONSTART + enter_kdebug("startup"); +#endif + + /* now switch to idle to start the other guys */ + switch_to_initial_thread(idle); + + /* should never return */ + panic("switch_to_idle returned\n"); +} + diff --git a/kernel/src/init.o b/kernel/src/init.o new file mode 100644 index 0000000..f1e2fdc Binary files /dev/null and b/kernel/src/init.o differ diff --git a/kernel/src/ipc.c b/kernel/src/ipc.c new file mode 100644 index 0000000..46aba4a --- /dev/null +++ b/kernel/src/ipc.c @@ -0,0 +1,1072 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: ipc.c + * Description: Implementation of the L4 IPC. + * + * @LICENSE@ + * + * $Id: ipc.c,v 1.87 2002/06/14 20:17:53 haeber Exp $ + * + ********************************************************************/ +#include +#include +#include +#include INC_ARCH(syscalls.h) +#include INC_ARCH(memory.h) + +#define IS_SEND (snd_desc != (dword_t)~0) +#define IS_RECEIVE (rcv_desc != (dword_t)~0) +#define IS_OPEN_WAIT ((rcv_desc & 1) == 1) + +#define IRQ_IN_SERVICE (1<<31) + +#define IS_SHORT_IPC(x) (!(x & ~0x3)) +#define IS_MAP(x) (x & 0x2) + +#if defined(CONFIG_DEBUG_TRACE_IPC) +extern dword_t __kdebug_ipc_tracing; +extern dword_t __kdebug_ipc_tr_mask; +extern dword_t __kdebug_ipc_tr_thread; +extern dword_t __kdebug_ipc_tr_this; +extern dword_t __kdebug_ipc_tr_dest; +#endif + +#if defined(CONFIG_MEASURE_INT_LATENCY) +extern dword_t interrupted_time; +extern dword_t interrupted_rdtsc; +#endif + + +/* we can make some assumptions here: + * - we are not the idle thread + * - we know that we don't activate ourself + * --> save time :-))) + */ +INLINE void ipc_switch_to_thread(tcb_t * current, tcb_t * tcb) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + //printf("ipc_switch_to_thread(%x->%x)\n", current, tcb); +#endif + switch_to_thread(tcb, current); +} + +INLINE void ipc_switch_to_idle(tcb_t * current) +{ + TRACEPOINT(SWITCH_TO_IDLE, + printf("Switch to idle\n")); + +#if defined(CONFIG_DEBUG_TRACE_MISC) + //printf("ipc_switch_to_idle: curr: %x\n", current); +#endif + switch_to_idle(current); +} + + + + +/* + * interrupt ownership and interrupt ipc stuff + */ + +tcb_t * interrupt_owner[MAX_INTERRUPTS]; + +void interrupts_init() +{ + for (int i = 0; i < MAX_INTERRUPTS; i++) + interrupt_owner[i] = NULL; +} + +void handle_interrupt(dword_t number) +{ + spin1(77); + tcb_t * tcb = interrupt_owner[number]; + tcb_t * current = get_current_tcb(); + + //printf("handle_interrupt(%d) ass. tcb: %p\n", number, tcb); + //enter_kdebug(); + + /* if no one is associated - we simply drop the interrupt */ + if (tcb) + { + if (IS_WAITING(tcb) && + ((tcb->partner.raw == (number + 1)) || l4_is_nil_id(tcb->partner))) + { + tcb->intr_pending = (number + 1) | IRQ_IN_SERVICE; + +#if defined(CONFIG_MEASURE_INT_LATENCY) + tcb->ipc_buffer[0] = interrupted_time; + tcb->ipc_buffer[1] = interrupted_rdtsc; +#endif + + if (current->priority >= tcb->priority) + { + tcb->thread_state = TS_LOCKED_RUNNING; + thread_enqueue_ready(tcb); + } + else { + /* make sure runnable threads are in the ready queue */ + if (current != get_idle_tcb()) + thread_enqueue_ready(current); + + ipc_switch_to_thread(current, tcb); + } + + //printf("deliver irq-ipc (%d) to %p\n", number, tcb); + } + else + tcb->intr_pending = number + 1; + } +} + + + +/* + * long and long-long ipc + */ + +// ???: Perhaps we should have a generic memcpy() instead. + +#if !defined(HAVE_ARCH_IPC_COPY) +static void ipc_copy(dword_t * to, dword_t * from, dword_t len) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("ipc_copy(%p, %p, %d)\n", to, from, len); + //enter_kdebug(); +#endif + + int i = len / 4; + while ( i-- ) + *(to++) = *(from++); + + if ( len & 2 ) + { + *((word_t *) to) = *((word_t *) from); + to = (dword_t *) ((word_t *) to + 1); + from = (dword_t *) ((word_t *) from + 1); + } + + if ( len & 1 ) + *(byte_t *) to = *(byte_t *) from; +} +#endif /* defined(HAVE_ARCH_IPC_COPY) */ + + +INLINE void transfer_message(tcb_t* const from, tcb_t* const to, const dword_t snd_desc) +{ + + /* UD: use temporary variables to give gcc a hint + to->ipc_buffer = from->ipc_buffer resulted in only one register + being used for all three dwords -> stalls */ + dword_t w0, w1, w2; + w0 = from->ipc_buffer[0]; + w1 = from->ipc_buffer[1]; + w2 = from->ipc_buffer[2]; + to->ipc_buffer[0] = w0; + to->ipc_buffer[1] = w1; + to->ipc_buffer[2] = w2; + +#if 1 +#warning REVIEWME: p-bit + /* What's up with the p-bit?? We don't support autopropagation, + but we can't simply assume the bit to be zero !!! */ +#else + if (snd_desc & 1) + enter_kdebug("propagate"); +#endif + + /* IPC optimization - register ipc. */ + if (EXPECT_FALSE( snd_desc & ~0x1 )) + { + /* + * Make sure that we are marked as doing IPC (in case we are + * descheduled). Also set the SENDING_IPC flag while we are + * in the send phase. + */ + from->thread_state = TS_LOCKED_RUNNING; + from->flags |= TF_SENDING_IPC; + extended_transfer(from, to, snd_desc); + from->thread_state = TS_RUNNING; + from->flags &= ~TF_SENDING_IPC; + } + else + to->msg_desc = 0; +} + +/* avoids inlining in ipc path :-) */ +void extended_transfer(tcb_t * from, tcb_t * to, dword_t snd_desc) +{ + memmsg_t *snd_msg; + memmsg_t *rcv_msg = NULL; + fpage_t rcv_fpage; + msgdope_t msgdope = (msgdope_t) { raw: {0} }; +#if defined(CONFIG_ENABLE_SMALL_AS) +# define IFSMALL(x) do { x; } while (0) + dword_t snd_msg_limit, rcv_msg_limit = 0; +#else +# define IFSMALL(x) +#endif + + /* first dequeue thread from wakeup queue */ + thread_dequeue_wakeup(to); + + TRACEPOINT(EXTENDED_TRANSFER, + printf("Extended transfer: snd_desc %p, rcv_desc %p\n", + snd_desc, to->msg_desc)); + + if ( IS_MAP(snd_desc) && !same_address_space(from, to) ) + { + if ( !IS_SHORT_IPC(to->msg_desc) ) + { + if ( IS_MAP(to->msg_desc) ) + { + /* Receive fpage is contained in receive descriptor. */ + rcv_fpage.raw = to->msg_desc & ~0x3; + } + else + { + /* Receive fpage(s) is contained in message buffer. */ + rcv_msg = (memmsg_t *) + get_copy_area(from, to, (ptr_t) (to->msg_desc & ~0x3)); + +#if defined(CONFIG_ENABLE_SMALL_AS) + rcv_msg_limit = get_ipc_copy_limit((dword_t) rcv_msg, to); + check_limit((dword_t) &rcv_msg->dwords[0], rcv_msg_limit, to); +#endif + + if ( !rcv_msg ) + enter_kdebug("!rcv_msg"); + + rcv_fpage = rcv_msg->rcv_fpage; + } + + if ( map_fpage(from, to, + from->ipc_buffer[0], /* snd base */ + (fpage_t) {raw:{from->ipc_buffer[1]}}, /* snd fpage */ + rcv_fpage) ) /* rcv fpage */ + msgdope.raw |= IPC_MAP_MESSAGE; + else + msgdope.raw |= IPC_ERR_CUTMSG; + } + else + /* Receiver is only doing short-receive ipc. */ + msgdope.raw |= IPC_ERR_CUTMSG; + } + + if ( IS_SHORT_IPC(snd_desc) ) + { + IFSMALL(from->resources &= ~TR_LONG_IPC_PTAB;); + to->msg_desc = msgdope.raw; + if (EXPECT_FALSE(rcv_msg)) + free_copy_area(from); + return; + } + + + /* + * We have a long-send ipc. + */ + snd_msg = (memmsg_t *) (snd_desc & ~0x3); + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* + * We might need to translate snd_msg address. We must also check + * if message descriptor stays within its segment boundaries. + */ + smallid_t small = from->space->smallid (); + if (small.is_valid ()) + snd_msg = (memmsg_t *) ((dword_t) snd_msg + small.offset ()); + + snd_msg_limit = get_ipc_copy_limit((dword_t) snd_msg, from); + check_limit((dword_t) &snd_msg->dwords[0], snd_msg_limit, from); +#endif + + dword_t num_dwords_src = snd_msg->send_dope.msgdope.dwords; + dword_t num_strings_src = snd_msg->send_dope.msgdope.strings; + + TRACEPOINT(LONG_SEND_IPC, + printf("Long-Send IPC: " + "snd_msg %p, snd_dw %d, snd_str %d, rcv_msg %p\n", + snd_msg, num_dwords_src, num_strings_src, to->msg_desc)); + + /* Long send but boiling down to a short. */ + if ( (num_dwords_src <= IPC_DWORD_GAP) && (num_strings_src == 0) ) + { + IFSMALL(from->resources &= ~TR_LONG_IPC_PTAB;); + to->msg_desc = msgdope.raw; + if (EXPECT_FALSE(rcv_msg)) + free_copy_area(from); + return; + } + + /* Long send but only short receive. */ + if ( IS_SHORT_IPC(to->msg_desc) ) + { + IFSMALL(from->resources &= ~TR_LONG_IPC_PTAB;); + to->msg_desc = msgdope.raw | IPC_ERR_CUTMSG; + return; + } + + /* + * From here on we handle long-to-long IPC. + */ + +#if defined(CONFIG_ENABLE_SMALL_AS) + check_limit((dword_t) &snd_msg->dwords[0] + + (num_dwords_src * sizeof(dword_t)) + + (num_strings_src * sizeof(stringdope_t)), + snd_msg_limit-3, from); +#endif + + if ( !rcv_msg ) + { + rcv_msg = (memmsg_t *) + get_copy_area(from, to, (ptr_t) (to->msg_desc & ~0x3)); + IFSMALL(rcv_msg_limit = get_ipc_copy_limit((dword_t) rcv_msg, to);); + } + + TRACEPOINT(LONG_LONG_IPC, + printf("Long-Long IPC: " + "snd_dw %d, rcv_dw %d, snd_str %d, rcv_str %d\n", + num_dwords_src, rcv_msg->size_dope.msgdope.dwords, + num_strings_src, rcv_msg->size_dope.msgdope.strings)); + +#if defined(CONFIG_ENABLE_SMALL_AS) + check_limit((dword_t) &rcv_msg->dwords[0] + + (rcv_msg->size_dope.msgdope.dwords * sizeof(dword_t)) + + (rcv_msg->size_dope.msgdope.strings * sizeof(stringdope_t)), + rcv_msg_limit-3, to); +#endif + + /* + * Copy dword area. + */ + if (num_dwords_src > IPC_DWORD_GAP) + { + + if ( num_dwords_src > rcv_msg->size_dope.msgdope.dwords ) + { + num_dwords_src = rcv_msg->size_dope.msgdope.dwords; +#if !defined(CONFIG_JOCHEN_BUGS) + msgdope.raw |= IPC_ERR_CUTMSG; +#endif + } + +#if defined(CONFIG_JOCHEN_BUGS) + ipc_copy(&rcv_msg->dwords[IPC_DWORD_GAP], + &snd_msg->dwords[IPC_DWORD_GAP], + (num_dwords_src - IPC_DWORD_GAP + 1) * 4); +#else + ipc_copy(&rcv_msg->dwords[IPC_DWORD_GAP], + &snd_msg->dwords[IPC_DWORD_GAP], + (num_dwords_src - IPC_DWORD_GAP) * 4); +#endif + } + + msgdope.msgdope.dwords = num_dwords_src; + + + /* + * TODO: Handle multiple send flexpages. + */ + if ( IS_MAP(snd_desc) ) + { + if ( snd_msg->dwords[IPC_DWORD_GAP + 1] != 0 ) + enter_kdebug("send multiple fpages not implemented"); + } + + + /* + * Copy indirect strings. + */ + if ( num_strings_src ) + { + dword_t num_strings_dest = rcv_msg->size_dope.msgdope.strings; + +#if defined(CONFIG_JOCHEN_BUGS) + /* the "[... + 1]" is for Jochen-compatibility */ + stringdope_t *dope_src = (stringdope_t *) + &snd_msg->dwords[snd_msg->size_dope.msgdope.dwords + 1]; + + stringdope_t *dope_dest = (stringdope_t *) + &rcv_msg->dwords[rcv_msg->size_dope.msgdope.dwords + 1]; +#else + stringdope_t *dope_src = (stringdope_t *) + &snd_msg->dwords[snd_msg->size_dope.msgdope.dwords]; + + stringdope_t *dope_dest = (stringdope_t *) + &rcv_msg->dwords[rcv_msg->size_dope.msgdope.dwords]; +#endif + + char *p_src = (char *) dope_src->send_address; + char *p_dest = (char *) dope_dest->rcv_address; + + dword_t size_src = dope_src->send_size; + dword_t size_dest = dope_dest->rcv_size; + dword_t size_total = 0; + dword_t copy_size; + + for (;;) + { + if ( num_strings_dest == 0 ) + { + msgdope.raw |= IPC_ERR_CUTMSG; + break; + } + if ( num_strings_src == 0 ) + break; + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( (dword_t) snd_msg >= SMALL_SPACE_START && + (dword_t) snd_msg < TCB_AREA ) + p_src += small.offset (); + else if ( (dword_t) rcv_msg >= SMALL_SPACE_START && + (dword_t) rcv_msg < TCB_AREA ) + p_dest += to->space->smallid ().offset (); +#endif + + TRACEPOINT(STRING_COPY_IPC, + printf("snd_dope @ %p: %p, %d\n" + "rcv_dope @ %p: %p, %d (%p)\n", + dope_src, p_src, dope_src->send_size, + dope_dest, p_dest, dope_dest->rcv_size, + msgdope.raw)); + + copy_size = size_src < size_dest ? size_src : size_dest; + +#if defined(CONFIG_ENABLE_SMALL_AS) + check_limit((dword_t) p_src + copy_size, snd_msg_limit, from); + check_limit((dword_t) p_dest + copy_size, rcv_msg_limit, to); +#endif + +// ???: May not work (depending on arch) if p_dest and p_src are not +// aligned. + ipc_copy(get_copy_area(from, to, (ptr_t) p_dest), + (dword_t *) p_src, copy_size); + + size_src -= copy_size; + size_dest -= copy_size; + size_total += copy_size; + +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("size_src: %d, size_dest: %d, size_total: %d\n", + size_src, size_dest, size_total); +#endif + + if ( size_src == 0 ) + { + num_strings_src--; + + if ( num_strings_src == 0 ) + { + /* No more strings to send. */ + dope_dest->send_size = size_total; + dope_dest->send_continue = 0; + dope_dest->send_address = dope_dest->rcv_address; + msgdope.msgdope.strings++; + goto string_abort; + } + + dope_src++; + + if ( dope_src->send_continue ) + { + /* Continue copying from next send string. */ + p_src = (char *) dope_src->send_address; + size_src = dope_src->send_size; + p_dest += copy_size; + continue; + /* we ignore the case that dest_size is 0 --> + one iteration more... */ + } + + dope_dest->send_address = dope_dest->rcv_address; + + /* + * Skip to next receive dope which is not part of + * the current scatter gather string. + */ + + do { + dope_dest->send_size = size_total; + dope_dest->send_continue = 0; + dope_dest++; + num_strings_dest--; + msgdope.msgdope.strings++; + + if ( num_strings_dest == 0 ) + { + msgdope.raw |= IPC_ERR_CUTMSG; + goto string_abort; + } + + /* + * This will make the remaining scatter gather + * receive strings marked as empty. + */ + size_total = 0; + + } while( dope_dest->rcv_continue ); + + /* Found next new rcv_dope. */ + size_dest = dope_dest->rcv_size; + p_dest = (char *) dope_dest->rcv_address; + size_src = dope_src->send_size; + p_src = (char *) dope_src->send_address; + } + else /* size_dest == 0 */ + { + dope_dest->send_size = size_total; + dope_dest->send_address = dope_dest->rcv_address; + + num_strings_dest--; + msgdope.msgdope.strings++; + + if ( num_strings_dest == 0 ) + { + msgdope.raw |= IPC_ERR_CUTMSG; + goto string_abort; + } + + dope_dest++; + + if ( dope_dest->rcv_continue ) + { + /* Continue copying into next receive string. */ + p_dest = (char *) dope_dest->rcv_address; + size_dest = dope_dest->rcv_size; + p_src += copy_size; + size_total = 0; + continue; + } + else + { + /* Receive string was too small. */ + msgdope.raw |= IPC_ERR_CUTMSG; + goto string_abort; + } + + + /* + * Skip to next send dope which is not part of the + * current scatter gather string. + */ + do { + dope_src++; + num_strings_src--; + + if ( num_strings_src == 0 ) + goto string_abort; + + } while( dope_src->send_continue ); + + /* Found next new send_dope. */ + size_dest = dope_dest->rcv_size; + p_dest = (char *) dope_dest->rcv_address; + size_src = dope_src->send_size; + p_src = (char *) dope_src->send_address; + size_total = 0; + } + } + } + +string_abort: + free_copy_area(from); + + to->msg_desc = msgdope.raw; + IFSMALL(from->resources &= ~TR_LONG_IPC_PTAB;); +} + + +extern struct last_ipc_t +{ + l4_threadid_t myself; + l4_threadid_t dest; + dword_t snd_desc; + dword_t rcv_desc; + dword_t ipc_buffer[3]; + dword_t ip; +} last_ipc; + +/* + * the system call + */ +#if !defined(CONFIG_SMP) + +/********************************************************************** + * SINGLE PROCESSOR * + **********************************************************************/ + +//void sys_ipc(const l4_threadid_t dest, const dword_t snd_desc, const dword_t rcv_desc) __attribute__ ((section(".ipc-c"))); +void sys_ipc(const l4_threadid_t dest, const dword_t snd_desc, const dword_t rcv_desc) +{ + tcb_t * current = get_current_tcb(); + tcb_t * to_tcb = NULL; + +#if defined(CONFIG_DEBUG_TRACE_IPC) + { + last_ipc.myself = current->myself; + last_ipc.dest = dest; + last_ipc.snd_desc = snd_desc; + last_ipc.rcv_desc = rcv_desc; + last_ipc.ipc_buffer = (dword_t[]){current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2]}; + last_ipc.ip = get_user_ip(current); + } + if ( __kdebug_ipc_tracing && + /* Do we trace spcific threads? */ + ((! __kdebug_ipc_tr_thread) || + /* Do we trace IPCs invoked by this thread? */ + (__kdebug_ipc_tr_thread == (__kdebug_ipc_tr_mask & + (dword_t) current) && + __kdebug_ipc_tr_this) || + /* Do we trace sends _to_ this thread? */ + (__kdebug_ipc_tr_thread == (__kdebug_ipc_tr_mask & + (dword_t) tid_to_tcb(dest)) && + __kdebug_ipc_tr_dest)) ) + { + printf("ipc: %x -> %x snd_desc: %x rcv_desc: %x " + "(%x, %x, %x) - ip=%x\n", current->myself.raw, dest.raw, + snd_desc, rcv_desc, current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2], + get_user_ip(current)); + if (__kdebug_ipc_tracing > 1) + enter_kdebug("ipc"); + } +#endif + + TRACEPOINT_2PAR(SYS_IPC, current->myself.raw, dest.raw, + printf("ipc: %x -> %x snd_desc: %x rcv_desc: %x " + "(%x, %x, %x) - ip=%x\n", + current->myself.raw, dest.raw, + snd_desc, rcv_desc, current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2], + get_user_ip(current))); + + if (EXPECT_TRUE( IS_SEND )) + { + to_tcb = tid_to_tcb(dest); +// printf("ipc: send branch (%p)\n", current); + + if (EXPECT_TRUE( to_tcb->myself == dest )) + { + current->partner = dest; +// printf("exist (%p, %x, %x)\n", to_tcb, to_tcb->partner.raw, +// to_tcb->thread_state ); + + if (EXPECT_FALSE( !IS_WAITING(to_tcb) ) || + EXPECT_FALSE( ((to_tcb->partner != current->myself) + && (!l4_is_nil_id(to_tcb->partner)) ))) + { +// printf("ipc (%p->%p): partner not ready(%x->%x,%x)\n", +// current, to_tcb, current->myself.raw, +// to_tcb->partner.raw, to_tcb->thread_state); + + /* + * Is either not receiving or is receiving but not from + * me or any. + */ + + /* special case: send to ourself fails (JOCHEN-compatible) */ + if (to_tcb == current) + return_ipc(IPC_ERR_EXIST); + + if ( !IS_INFINITE_SEND_TIMEOUT(current->ipc_timeout) ) + { + /* + * We have a send timeout. Enqueue into wakeup queue. + */ + qword_t absolute_timeout = + TIMEOUT(current->ipc_timeout.timeout.snd_exp, + current->ipc_timeout.timeout.snd_man); + + if ( !absolute_timeout ) + return_ipc(IPC_ERR_SENDTIMEOUT); + + current->absolute_timeout = absolute_timeout + + get_current_time(); + + thread_enqueue_wakeup(current); +// printf("enqueue %p into wakeup; to: %d, abs timeout: %d\n", +// current, (dword_t) absolute_timeout, +// (dword_t) current->absolute_timeout); + } + + thread_enqueue_send(to_tcb, current); + current->thread_state = TS_POLLING; + + /* Start waiting for send to complete. */ + ipc_switch_to_idle(current); + + if ( current->thread_state == TS_RUNNING ) + /* Reactivated because of a timeout. */ + return_ipc(IPC_ERR_SENDTIMEOUT); + + thread_dequeue_wakeup(current); + } + +// printf("ipc: performing transfer (%p->%p) state (%x->%x)\n", +// current, to_tcb, current->thread_state, +// to_tcb->thread_state); + + transfer_message(current, to_tcb, snd_desc); + + /* If partner does open wait, he needs to know who we are. */ + to_tcb->partner = current->myself; + + + /* + * Since the other guy activates itself - we *must* switch. + */ + if (EXPECT_FALSE( !IS_RECEIVE )) + { + /* set ourself running and enqueue to ready */ + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + + ipc_switch_to_thread(current, to_tcb); + return_ipc(0); + } + } + else + { + /* ERROR - Destination is invalid. */ + return_ipc(IPC_ERR_EXIST); + } + + } /* IS_SEND */ + + + /*---------------------------------------------------------------- + * + * We are receiving (perhaps in conjunction with send). + * + */ + + /* UD: We can drop this check. If there was no send phase then there + MUST BE a receive phase. Confirmed by Jochen. + //if ( IS_RECEIVE ) + */ + { + tcb_t * from_tcb; + //printf("ipc: receive branch (%x)\n", current); + + if ( current->intr_pending & IRQ_IN_SERVICE ) + { + unmask_interrupt((current->intr_pending & ~IRQ_IN_SERVICE) - 1); + current->intr_pending = 0; + } + + if (EXPECT_TRUE( !IS_OPEN_WAIT )) + { + + /*--- receive from ---*/ + from_tcb = tid_to_tcb(dest); + + /* special cases... taskid == 0 */ + if (EXPECT_FALSE( IS_KERNEL_ID(dest) )) + { + current->msg_desc = 0; + return_ipc_args(dest, ipc_handle_kernel_id(current, dest), current); + } + + if (EXPECT_FALSE( from_tcb->myself.raw != dest.raw )) + { + /* + * Destination is invalid. This can happen if we do a + * receive-only. Otherwise, the send branch has + * tested this already. + */ + return_ipc(IPC_ERR_EXIST); + } + //printf("ipc: receive from: %x\n", from_tcb); + } + else /* OPEN WAIT */ + { + if (current->intr_pending) + { + dword_t irq; + /* Interrupt is pending. Receive it. */ + irq = current->intr_pending; + current->intr_pending = IRQ_IN_SERVICE | irq; + + if ( to_tcb ) + { + /* + * If we did a send, we must make sure that the + * receiver is woken up. We can not simply make + * him RUNNING since that will cause him to return + * with an IPC_ERR_TIMEOUT. + */ + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + + ipc_switch_to_thread(current, to_tcb); + } + /* empty msg desc */ + current->msg_desc = 0; + return_ipc_args(irq, 0, current); + } + + from_tcb = current->send_queue; + //printf("ipc: wait sq: %x\n", from_tcb); + } + + current->msg_desc = rcv_desc; + + /* + * no partner || partner does not exist || + * partner does not receive from me + */ + if ( EXPECT_FALSE(!from_tcb) || + EXPECT_TRUE(!IS_POLLING(from_tcb)) || + (from_tcb->partner != current->myself) ) + { + /* + * Partner is not ready to send to me yet or no partner. + */ + + if (EXPECT_FALSE( !IS_INFINITE_RECV_TIMEOUT(current->ipc_timeout) )) + { + /* + * We have a recv timeout. Enqueue into wakeup queue. + */ + qword_t absolute_timeout = + TIMEOUT(current->ipc_timeout.timeout.rcv_exp, + current->ipc_timeout.timeout.rcv_man); + + if ( !absolute_timeout ) + return_ipc(IPC_ERR_RECVTIMEOUT); + + current->absolute_timeout = absolute_timeout + + get_current_time(); + + thread_enqueue_wakeup(current); +// printf("enqueue %p into wakeup; timeout: 0x%x", +// current, current->ipc_timeout.raw); + } + + // this is not obvious - from_tcb can be only zero in one + // case - if we have an open wait. Otherwise the tcb does + // not exist (and we do not reach this path) or we have + // a valid tcb. thus, by checking for an open wait we are safe. + current->partner = EXPECT_FALSE(IS_OPEN_WAIT) ? L4_NIL_ID : from_tcb->myself; + current->thread_state = TS_WAITING; + + /* + * Start waiting for message to arrive. If we are + * also sending to the partner, switch to him. + */ + + if (EXPECT_TRUE( to_tcb != NULL )) + ipc_switch_to_thread(current, to_tcb); + else + ipc_switch_to_idle(current); + + if (EXPECT_FALSE( current->thread_state == TS_RUNNING )) + /* Reactivated because of a timeout. */ + return_ipc(IPC_ERR_RECVTIMEOUT); + + /* ok, got a message... */ + /* we could - but this is no clean solution - do + if (EXPECT_FALSE( current->queue_state & TS_QUEUE_WAKEUP )) + here to avoid calling the function if not needed */ + thread_dequeue_wakeup(current); + } + else + { + /* + * Partner is ready to send to me. + */ + + /* + * if we don't switch to from_tcb we must + * enqueue from_tcb into the ready queue + */ + from_tcb->thread_state = TS_LOCKED_RUNNING; + thread_enqueue_ready(from_tcb); + + /* + * The sender is waiting for us. As such, he is in + * our send-queue. Dequeue him. + */ + + thread_dequeue_send(current, from_tcb); + current->thread_state = TS_LOCKED_WAITING; + + /* + * Switch to our waiting partner. + * If we don't switch to the woken up we have + * to dequeue him from the wakeup queue + */ + thread_dequeue_wakeup(from_tcb); + + if ( to_tcb ) + ipc_switch_to_thread(current, to_tcb); + else + ipc_switch_to_thread(current, from_tcb); + + } + + current->thread_state = TS_RUNNING; + return_ipc_args(current->partner, 0, current); + } +enter_kdebug("endof_ipc"); + return_ipc(0); +} +#endif /* !defined(CONFIG_SMP) */ + + +notify_procedure(copy_pagefault, dword_t fault, tcb_t * partner) +{ + tcb_t * current = get_current_tcb(); + + dword_t save[3]; + timeout_t save_timeout; + + /* Save current ipc state. */ + save[0] = current->ipc_buffer[0]; + save[1] = current->ipc_buffer[1]; + save[2] = current->ipc_buffer[2]; + save_timeout = current->ipc_timeout; + + /* Perform the tunneled pagefault. */ + current->ipc_timeout = GET_RECV_PF_TIMEOUT(partner->ipc_timeout); + do_pagefault_ipc(current, fault, 0xffffffff); + + /* Restore old ipc state. */ + current->partner = partner->myself; + current->ipc_buffer[0] = save[0]; + current->ipc_buffer[1] = save[1]; + current->ipc_buffer[2] = save[2]; + current->ipc_timeout = save_timeout; + + current->thread_state = TS_LOCKED_WAITING; + partner->thread_state = TS_LOCKED_RUNNING; + thread_enqueue_ready(partner); + + /* + * Switch back to sender. He will restore our old stack pointer. + * It can NEVER happen that our partner is rescheduled because we run + * with disabled interrupts, Espen. + */ + switch_to_thread(partner, current); + spin(43); +} + + + + +int ipc_handle_kernel_id(tcb_t* current, l4_threadid_t dest) +{ +#if 0 + printf("ipc sleep to: %x, %d:%d\n", current->ipc_timeout, + current->ipc_timeout.timeout.rcv_exp, + current->ipc_timeout.timeout.rcv_man); +#endif + + if ( IS_INTERRUPT_ID(dest) ) + { + + dword_t irq = INTERRUPT_ID(dest) + 1; + + if ( current->intr_pending == irq ) + { + /* Interrupt is pending. Receive it. */ + current->intr_pending = IRQ_IN_SERVICE | irq; +#if defined(CONFIG_MEASURE_INT_LATENCY) + current->ipc_buffer[2] = rdtsc(); +#endif + return(0); + } + } + + + + if ( !IS_INFINITE_RECV_TIMEOUT(current->ipc_timeout) ) + { + qword_t absolute_timeout = + TIMEOUT(current->ipc_timeout.timeout.rcv_exp, + current->ipc_timeout.timeout.rcv_man); + + if ( !absolute_timeout ) + { + /* + * Interrupt association. + */ + + /* Detach from all attached interrupts. */ + for (int i = 0; i < MAX_INTERRUPTS; i++) + if ( interrupt_owner[i] == current ) + interrupt_owner[i] = NULL; + + if ( IS_INTERRUPT_ID(dest) ) + { + if ( interrupt_owner[INTERRUPT_ID(dest)] == NULL ) + { +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("associate interrupt %x\n", + INTERRUPT_ID(dest)); +#endif + interrupt_owner[INTERRUPT_ID(dest)] = current; + } + else + { + printf("interrupt association failed (%p irq: " + "%d)\n", current, INTERRUPT_ID(dest)); + return(IPC_ERR_EXIST); + } + + mask_interrupt(INTERRUPT_ID(dest)); + } + + return(IPC_ERR_RECVTIMEOUT); + } + + /* Wait for interrupt to be trigered. */ + current->absolute_timeout = absolute_timeout + + get_current_time(); + + thread_enqueue_wakeup(current); +#if 0 + printf("sleep timeout: %d us, current time: %x, wakeup: " + "%x\n", (dword_t) absolute_timeout, + (dword_t) get_current_time(), + current->absolute_timeout); +#endif + } + + /* automatic interrupt acking where available */ + if ( IS_INTERRUPT_ID(dest) ) + { + unmask_interrupt(INTERRUPT_ID(dest)); + } + + /* VU: Huuuugh - next time better read the manual!!! + * Anyone who did a sleep-call did an open wait + * in Hazelnut. L4Linux really did not like that... + */ + if (l4_is_nil_id(dest)) + dest = L4_INVALID_ID; + + current->partner = dest; + current->thread_state = TS_WAITING; + + /* Start waiting for interrupt to be triggered. */ + ipc_switch_to_idle(current); + + if ( current->thread_state == TS_RUNNING ) + /* Reactivated because of a timeout. */ + return(IPC_ERR_RECVTIMEOUT); + + thread_dequeue_wakeup(current); + +#if defined(CONFIG_MEASURE_INT_LATENCY) + current->ipc_buffer[2] = rdtsc(); +#endif + + current->thread_state = TS_RUNNING; + return(0); +} + diff --git a/kernel/src/ipc.o b/kernel/src/ipc.o new file mode 100644 index 0000000..010af3a Binary files /dev/null and b/kernel/src/ipc.o differ diff --git a/kernel/src/kmemory.c b/kernel/src/kmemory.c new file mode 100644 index 0000000..bab1575 --- /dev/null +++ b/kernel/src/kmemory.c @@ -0,0 +1,154 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: kmemory.c + * Description: Kernel memory allocator. + * + * @LICENSE@ + * + * $Id: kmemory.c,v 1.27 2001/11/22 15:10:32 skoglund Exp $ + * + ********************************************************************/ +#include + +#ifndef CONFIG_HAVE_ARCH_KMEM + +#include + + + + +dword_t *kmem_free_list = NULL; +dword_t free_chunks = 0; + +/* kernel memory allocator semaphore */ +DEFINE_SPINLOCK(kmem_spinlock); + +/* the stupid version */ +void kmem_free(ptr_t address, dword_t size) +{ + ptr_t p; + ptr_t prev, curr; + + spin_lock(&kmem_spinlock); + + //printf("kmem_free(%p, %x)\n", address, size); + + for (p = address; + p < ((ptr_t)(((dword_t)address) + size - KMEM_CHUNKSIZE)); + p = (ptr_t) *p) + *p = (dword_t) p + KMEM_CHUNKSIZE; /* write next pointer */ + + /* find the place to insert */ + for (prev = (ptr_t) &kmem_free_list, curr = kmem_free_list; + curr && (address > curr); + prev = curr, curr = (dword_t*) *curr); + /* and insert there */ + //printf("prev %p/%p, curr %p, p: %p, \n", prev, *prev, curr, p); + *prev = (dword_t) address; *p = (dword_t) curr; + + /* update counter */ + free_chunks += (size/KMEM_CHUNKSIZE); + + spin_unlock(&kmem_spinlock); +} + +#if defined(NEED_FARCALLS) +#include INC_ARCH(farcalls.h) +#endif + + +dword_t kmem_end = 0; +dword_t kmem_start = ~0; + +void kmem_init() +{ + +/* + * From linker scripts. + */ + extern dword_t text_paddr[]; + extern dword_t _end_text_p[]; + +#if defined(CONFIG_DEBUG_SANITY) + if (kmem_end < kmem_start) + printf("%s(%x,%x) is a silly config\n", __FUNCTION__, kmem_start, kmem_end); +#endif + +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("%s(%x,%x)\n", __FUNCTION__, kmem_start, kmem_end); +#endif + + kmem_free((ptr_t) kmem_start, kmem_end-kmem_start); + kernel_info_page.reserved_mem0_low = (dword_t) text_paddr; + kernel_info_page.reserved_mem0_high = (dword_t) _end_text_p; + kernel_info_page.reserved_mem1_low = virt_to_phys((dword_t) kmem_start); + kernel_info_page.reserved_mem1_high = (virt_to_phys((dword_t) kmem_end) + (PAGE_SIZE-1)) & PAGE_MASK; +} + +/* the stupid version */ +ptr_t kmem_alloc(dword_t size) +{ + spin_lock(&kmem_spinlock); + + dword_t* prev; + dword_t* curr; + dword_t* tmp; + dword_t i; + + //printf("%s(%d) kfl: %p\n", __FUNCTION__, size, kmem_free_list); + for (prev = (dword_t*) &kmem_free_list, curr = kmem_free_list; + curr; + prev = curr, curr = (dword_t*) *curr) + { +// printf("curr=%x\n", curr); + /* properly aligned ??? */ + if (!((dword_t) curr & (size - 1))) + { +// printf("%s(%d):%d: curr=%x\n", __FUNCTION__, size, __LINE__, curr); + tmp = (dword_t*) *curr; + for (i = 1; tmp && (i < (size / KMEM_CHUNKSIZE)); i++) + { +// printf("%s():%d: i=%d, tmp=%x\n", __FUNCTION__, __LINE__, i, tmp); + if ((dword_t) tmp != ((dword_t) curr + KMEM_CHUNKSIZE*i)) + { +// printf("skip: %x\n", curr); + tmp = 0; + break; + }; + tmp = (dword_t*) *tmp; + } + if (tmp) + { + /* dequeue */ + *prev = (dword_t) tmp; + + /* zero the page */ + for (dword_t i = 0; i < (size / sizeof(dword_t)); i++) + curr[i] = 0; + + /* update counter */ + free_chunks -= (size/KMEM_CHUNKSIZE); + + /* successful return */ + spin_unlock(&kmem_spinlock); + //printf("kmalloc: %x->%p (%d), kfl: %p\n", size, curr, free_chunks, kmem_free_list); + return curr; + } + } + } +#if 0 + dword_t * tmp1 = kmem_free_list; + while(tmp1) { + printf("%p -> "); + tmp1 = (dword_t*)*tmp1; + } +#endif + enter_kdebug("kmem_alloc: out of kernel memory"); + spin_unlock(&kmem_spinlock); + return NULL; +} + +#endif /* !CONFIG_HAVE_ARCH_KMEM */ + diff --git a/kernel/src/kmemory.o b/kernel/src/kmemory.o new file mode 100644 index 0000000..f77c0e2 Binary files /dev/null and b/kernel/src/kmemory.o differ diff --git a/kernel/src/lib.c b/kernel/src/lib.c new file mode 100644 index 0000000..4d8cb77 --- /dev/null +++ b/kernel/src/lib.c @@ -0,0 +1,30 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: lib.c + * Description: Various helper functions. + * + * @LICENSE@ + * + * $Id: lib.c,v 1.3 2001/11/22 13:04:52 skoglund Exp $ + * + ********************************************************************/ +#include + +void zero_memory(dword_t* dest, int len) +{ + len /= 4; + while(len--) + *(dest++) = 0; +} + +void memcpy(dword_t* dest, dword_t * src, int len) +{ + //printf("memcpy(%p, %p, %d)\n", dest, src, len); + + len /= 4; + while(len--) + *(dest++) = *(src++); + +} diff --git a/kernel/src/lib.o b/kernel/src/lib.o new file mode 100644 index 0000000..e4886b4 Binary files /dev/null and b/kernel/src/lib.o differ diff --git a/kernel/src/libkernel.a b/kernel/src/libkernel.a new file mode 100644 index 0000000..6ecaae4 Binary files /dev/null and b/kernel/src/libkernel.a differ diff --git a/kernel/src/mapping.c b/kernel/src/mapping.c new file mode 100644 index 0000000..4238260 --- /dev/null +++ b/kernel/src/mapping.c @@ -0,0 +1,599 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mapping.c + * Description: Generic mapping database implementation. + * + * @LICENSE@ + * + * $Id: mapping.c,v 1.16 2001/12/07 19:08:52 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include INC_ARCH(memory.h) +#include + + +/* + * UPLOCKS AND DOWNLOCKS + * + * There are two kinds of locks for mapping nodes: uplocks and + * downlocks. The uplock protects the prev pointer and page table + * pointer and the downlock protects the next pointer. If an uplock + * is aquired, the thread is allowed to hold it as long as it wants. + * If a downlock is aquired and the thread is not able to aquire its + * child's uplock (given that it indeed has a child node), it must + * release its own downlock and try acquiring it later. Root nodes + * contain only downlocks, and aquireing a downlock in a root node + * follows the same algorithm as acquiring a downlock in a mapping + * node. + * + * Using uplocks and downlocks, a node may only be deleted if it has + * aquired both of its own locks, the downlock of its parent, and the + * uplock of its child. A new node may be added beneath a node if its + * downlock, and its current child's uplock is aquired. + * + */ + + +static dualnode_t *mdb_create_roots(dword_t size); + + +static inline dword_t mdb_arraysize(dword_t pgsize) +{ + return 1 << (mdb_pgshifts[pgsize+1] - mdb_pgshifts[pgsize]); +} + +static inline dword_t mdb_get_index(dword_t size, dword_t addr) +{ + return (addr >> mdb_pgshifts[size]) & (mdb_arraysize(size) - 1); +} + +static inline rnode_t *mdb_index_root(dword_t size, rnode_t *r, dword_t addr) +{ + return r + mdb_get_index(size, addr); +} + +static inline int mdb_pgsize (int hw_pgsize) +{ + int s = 0; + while (mdb_pgshifts[s] < hw_pgshifts[hw_pgsize]) + s++; + return s; +} + +static inline int hw_pgsize (int mdb_pgsize) +{ + int s = 0; + while (hw_pgshifts[s] < mdb_pgshifts[mdb_pgsize]) + s++; + return s; +} + + +/* + * Function mdb_map (f_map, f_pg, f_pgsize, f_addr, t_pg, t_pgsize, t_space) + * + * Insert the specified mapping. We will have f_map->uplock upon + * entry. If bit 0 in f_addr is set, it indicates that we are + * doing a grant operation. Function returns new mapping node with + * the uplock acquired. + * + */ +mnode_t *mdb_map(mnode_t *f_map, pgent_t *f_pg, dword_t f_pgsize, + dword_t f_addr, pgent_t *t_pg, dword_t t_pgsize, + space_t *t_space) +{ + dualnode_t *dual; + rnode_t *root, *proot; + mnode_t *newm, *nmap; + dword_t newdepth = f_map->get_depth() + 1; + + if ( f_addr & 0x01 ) + { + // Grant. + if ( f_map->is_prev_root() ) + f_map->set_backlink(f_map->get_prevr(f_pg), t_pg); + else + f_map->set_backlink(f_map->get_prevm(f_pg), t_pg); + f_map->set_space(t_space); + + return f_map; + } + + // Convert to mapping database pagesizes. + f_pgsize = mdb_pgsize (f_pgsize); + t_pgsize = mdb_pgsize (t_pgsize); + + // Aquire f_map->downlock and nmap->uplock. + for (;;) + { + f_map->down_lock(); + if ( f_map->is_next_root() ) + { + dual = (dualnode_t *) f_map->get_nextr(); + nmap = dual->map; + } + else + { + dual = NULL; + nmap = f_map->get_nextm(); + } + if ( (! nmap) || nmap->up_trylock() ) + break; + f_map->down_unlock(); + } + + newm = (mnode_t *) mdb_alloc_buffer(sizeof(mnode_t)); + + if ( f_pgsize == t_pgsize ) + { + // Hook new node directly below mapping node. + newm->set_backlink(f_map, t_pg); + newm->set_space(t_space); + newm->set_depth(f_map->get_depth() + 1); + newm->clear_locks(); + newm->set_next(nmap); + + if ( dual ) + dual->map = newm; + else + f_map->set_next(newm); + + if ( nmap ) + { + nmap->set_backlink(newm, nmap->get_pgent(f_map)); + nmap->up_unlock(); + } + f_map->down_unlock(); + } + else if ( f_pgsize > t_pgsize ) + { + f_pgsize--; + if ( nmap ) + nmap->up_unlock(); // No longer needed. + + // Traverse into the root array below mappping node. + if ( ! dual ) + { + // New array needs to be created. + dual = mdb_create_roots(f_pgsize); + dual->map = nmap; + + root = mdb_index_root(f_pgsize, dual->root, f_addr); + root->down_lock(); + f_map->set_next((rnode_t *) dual); + nmap = NULL; + dual = NULL; + } + else + { + root = mdb_index_root(f_pgsize, dual->root, f_addr); + + // Aquire root->downlock and nmap->uplock. + for (;;) + { + root->down_lock(); + if ( root->is_next_root() ) + { + dual = (dualnode_t *) root->get_map(); + nmap = dual->map; + } + else + { + dual = NULL; + nmap = root->get_map(); + } + if ( (! nmap) || nmap->up_trylock() ) + break; + root->down_unlock(); + } + } + + f_map->down_unlock(); // No longer needed. + + // Traverse into the root array below root arrays. + while ( f_pgsize > t_pgsize ) + { + f_pgsize--; + if ( ! dual ) + { + // New array needs to be created. + dual = mdb_create_roots(f_pgsize); + dual->map = root->get_map(); + root->set_ptr((rnode_t *) dual); + } + proot = root; + root = mdb_index_root(f_pgsize, dual->root, f_addr); + + if ( root->is_next_root() ) + { + dual = (dualnode_t *) root->get_map(); + nmap = dual->map; + } + else + { + dual = NULL; + nmap = root->get_map(); + } + + root->down_lock(); + proot->down_unlock(); + } + + newm->set_backlink(root, t_pg); + newm->set_space(t_space); + newm->set_depth(newdepth); + newm->set_next(nmap); + newm->down_unlock(); + + if ( dual ) + dual->map = newm; + else + root->set_ptr(newm); + + if ( nmap ) + { + nmap->set_backlink(newm, nmap->get_pgent(root)); + nmap->up_unlock(); + } + root->down_unlock(); + } + else + enter_kdebug("mdb_map: f_pgsize < t_pgsize"); + + return newm; +} + + + +int mdb_flush(mnode_t *f_map, pgent_t *f_pg, dword_t f_pgsize, + dword_t f_addr, dword_t t_pgsize, dword_t mode) +{ + dualnode_t *dual = NULL; + mnode_t *pmap = NULL, *nmap; + rnode_t *root = NULL, *proot = NULL; + dword_t rcnt, startdepth, vaddr; + + mnode_t *r_nmap[NUM_PAGESIZES-1]; + rnode_t *r_root[NUM_PAGESIZES-1]; + dword_t r_rcnt[NUM_PAGESIZES-1]; + dword_t r_prev[NUM_PAGESIZES-1]; /* Bit 0 set indicates mapping. + Bit 0 cleared indicates root. */ + + rcnt = 0; + startdepth = f_map->get_depth(); + + // Convert to mapping database pagesizes. + f_pgsize = mdb_pgsize (f_pgsize); + t_pgsize = mdb_pgsize (t_pgsize); + + do { + // Variables `f_map' and `f_pg' are valid at this point. + + // Aquire f_map->downlock and nmap->uplock. We already + // have f_map->uplock. + for (;;) + { + f_map->down_lock(); + if ( f_map->is_next_root() ) + { + dual = (dualnode_t *) f_map->get_nextr(); + nmap = dual->map; + } + else + { + dual = NULL; + nmap = f_map->get_nextm(); + } + if ( (! nmap) || nmap->up_trylock() ) + break; + f_map->down_unlock(); + } + + // Aquire either pmap->downlock or proot->downlock. + if ( f_map->is_prev_root() ) + { + pmap = NULL; + proot = f_map->get_prevr(f_pg); + proot->down_lock(); + } + else + { + proot = 0; + pmap = f_map->get_prevm(f_pg); + pmap->down_lock(); + } + + // Variable contents at this point: + // + // f_map - the current mapping node + // f_pg - the current pgent node + // pmap - the previous mapping node (or NULL if prev is root) + // proot - the previous root node (or NULL if prev is map) + // nmap - the next mapping node (may be NULL) + // dual - next dual node (or NULL if no such node) + // root - Current root array pointer (or NULL) + +// printf("New: f_map=%p dual=%p nmap=%p pmap=%p proot=%p " +// "fsize=%d tsize=%d root=%p\n", +// f_map, dual, nmap, pmap, proot, f_pgsize, t_pgsize, root); + + if ( mode & MDB_ALL_SPACES ) + { + space_t * space = f_map->get_space (); + + if ( (f_pgsize > t_pgsize) && nmap ) + { + enter_kdebug("mdb_flush: trying to flush too small page"); + return -1; + } + + int f_hwpgsize = hw_pgsize (f_pgsize); + vaddr = f_pg->vaddr(space, f_hwpgsize, f_map); + + if ( mode & MDB_FLUSH ) + { + // Remove ourselves. + if ( pmap ) + { + pmap->set_next(nmap); + if ( nmap ) + nmap->set_backlink(pmap, nmap->get_pgent(f_map)); + } + else + { + proot->set_ptr(nmap); + if ( nmap ) + nmap->set_backlink(proot, nmap->get_pgent(f_map)); + } + + mdb_free_buffer((dword_t *) f_map, sizeof(mnode_t)); + f_pg->clear(space, f_hwpgsize); + } + else + { + f_pg->set_readonly(space, f_hwpgsize); + pmap = f_map; + proot = NULL; + } + + // We might have to flush some TLB entries. +#if defined(CONFIG_ENABLE_SMALL_AS) + if (space->is_small ()) + // Page in small space. Need to flush since we might + // happen to swith to this space next (plus small + // space TLB entries on x86 have global bit set). + flush_tlbent ((ptr_t) (vaddr + space->smallid ().offset ())); + else if (space == get_current_space ()) + // Page is in currently accessible page table. We + // have to flush. + flush_tlbent ((ptr_t) vaddr); +#else + if (space == get_current_space ()) + flush_tlbent ((ptr_t) vaddr); +#endif + } + else + { + pmap = f_map; + proot = NULL; + } + f_map = NULL; + + + // Variables `f_map' and `f_pg' are no longer valid here. + + if ( dual ) + { + f_pgsize--; + + if ( f_pgsize < t_pgsize ) + { + // Recurse into subarray before checking mappings. + r_prev[f_pgsize] = pmap ? (dword_t) pmap | 0x01 : + (dword_t) proot; + r_nmap[f_pgsize] = nmap; + r_root[f_pgsize] = root; + r_rcnt[f_pgsize] = rcnt; + + root = dual->root - 1; + rcnt = mdb_arraysize(f_pgsize); + + if ( (mode & MDB_FLUSH) & (mode & MDB_ALL_SPACES) ) + mdb_free_buffer((dword_t *) dual, sizeof(dualnode_t)); + } + else + { + // We may use the virtual address `f_addr' for + // indexing here since the alignment within the page + // will be the same as with the physical address. + root = mdb_index_root(f_pgsize, dual->root, f_addr) - 1; + rcnt = 1; + } + } + else + { + if ( nmap ) + { + if ( pmap ) + f_pg = nmap->get_pgent(pmap); + else + f_pg = nmap->get_pgent(proot); + + f_map = nmap; + } + else if ( f_pgsize < t_pgsize && root ) + { + // Recurse up from subarray and delete it. + if ( mode & MDB_FLUSH ) + { + root -= mdb_arraysize(f_pgsize) - 1; + mdb_free_buffer((dword_t *) root, + mdb_arraysize(f_pgsize) * sizeof(rnode_t)); + } + + f_map = r_nmap[f_pgsize]; + root = r_root[f_pgsize]; + rcnt = r_rcnt[f_pgsize]; + if ( r_prev[f_pgsize] & 0x01 ) + { + proot = NULL; + pmap = (mnode_t *) (r_prev[f_pgsize] & ~0x01); + if ( f_map ) + f_pg = f_map->get_pgent(pmap); + } + else + { + proot = (rnode_t *) r_prev[f_pgsize]; + pmap = NULL; + if ( f_map ) + f_pg = f_map->get_pgent(proot); + } + + f_pgsize++; + } + } + + // If f_map now is non-nil, the variables f_map, f_pg, pmap + // and proot will all be valid. Otherwise, root and rcnt will + // be valid. + + while ( (! f_map) && (rcnt > 0) ) + { + rcnt--; + root++; + + // Aquire root->downlock and child->upmap (if child exists). + // There is no need to release the root->downlocks, since no one + // will be able to reference the root nodes when we have flushed + // them (we remove the parent node from the mapping tree before + // recursing into the root nodes). + for (;;) + { + root->down_lock(); + if ( root->is_next_root() ) + { + dual = (dualnode_t *) root->get_map(); + f_map = dual->map; + } + else + { + dual = NULL; + f_map = root->get_map(); + } + + if ( (! f_map) || f_map->up_trylock() ) + break; + } + + if ( dual ) + { + // Recurse into subarray before checking mappings. + f_pgsize--; + + if ( mode & MDB_FLUSH ) + root->set_ptr(f_map); // Remove subarray. + + r_prev[f_pgsize] = (dword_t) root; + r_nmap[f_pgsize] = f_map; + r_root[f_pgsize] = root; + r_rcnt[f_pgsize] = rcnt; + + f_map = NULL; + root = dual->root - 1; + rcnt = mdb_arraysize(f_pgsize); + + if ( mode & MDB_FLUSH ) + mdb_free_buffer((dword_t *) dual, sizeof(dualnode_t)); + } + else + { + if ( f_map ) + { + f_pg = f_map->get_pgent(root); + pmap = NULL; + proot = root; + } + } + } + + if ( f_pgsize <= t_pgsize ) + // From now on, we will remove all nodes. + mode |= MDB_ALL_SPACES; + + } while ( f_map && f_map->get_depth() > startdepth ); + + // Allow next mapping node in tree to have it's prev counter modified. + if ( f_map ) + f_map->up_unlock(); + + return 0; +} + + + +static dualnode_t * mdb_create_roots(dword_t size) +{ + rnode_t *newnodes, *n; + + size = mdb_arraysize(size); + newnodes = (rnode_t *) mdb_alloc_buffer(sizeof(rnode_t) * size); + + for ( n = newnodes; size--; n++ ) + { + n->set_ptr((mnode_t *) NULL); + n->clear_locks(); + } + + n = (rnode_t *) mdb_alloc_buffer(sizeof(dualnode_t)); + ((dualnode_t *) n)->map = NULL; + ((dualnode_t *) n)->root = newnodes; + + return (dualnode_t *) n; +} + + + +// The sigma0_mapnode is initialized to own the whole address space. +static mnode_t __sigma0_mapnode; +mnode_t *sigma0_mapnode; + +#if defined(NEED_FARCALLS) +#include INC_ARCH(farcalls.h) +#endif + +void mdb_init(void) +{ + static dualnode_t *(*__mdb_create_roots)(dword_t) = mdb_create_roots; + dualnode_t *dual; + + mdb_buflist_init(); + + // Frame table for the complete address space. + dual = __mdb_create_roots(NUM_PAGESIZES-1); + + // Let sigma0 own the whole address space. + sigma0_mapnode = &__sigma0_mapnode; + sigma0_mapnode->set_backlink((mnode_t *) NULL, (pgent_t *) NULL); + sigma0_mapnode->set_space(SIGMA0_PGDIR_ID); + sigma0_mapnode->set_depth(0); + sigma0_mapnode->clear_locks(); + sigma0_mapnode->set_next((rnode_t *) dual); + + // Sanity checking of pgshift arrays. + for (int i = 0, j; i < HW_NUM_PGSIZES; i++) + { + if (! ((1 << hw_pgshifts[i]) & HW_VALID_PGSIZES)) + continue; + for (j = 0; j < NUM_PAGESIZES; j++) + if (hw_pgshifts[i] == mdb_pgshifts[j]) + break; + if (j == NUM_PAGESIZES) + panic("mdb_pgshifts[] is not a superset of hw_pgshifts[]"); + } +} + + diff --git a/kernel/src/mapping.o b/kernel/src/mapping.o new file mode 100644 index 0000000..aaea9ac Binary files /dev/null and b/kernel/src/mapping.o differ diff --git a/kernel/src/mapping_alloc.c b/kernel/src/mapping_alloc.c new file mode 100644 index 0000000..244e437 --- /dev/null +++ b/kernel/src/mapping_alloc.c @@ -0,0 +1,277 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mapping_alloc.c + * Description: Memory management for mapping database. + * + * @LICENSE@ + * + * $Id: mapping_alloc.c,v 1.10 2001/11/22 13:04:52 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + + +/* + * Size of chunks allocated from kmem. + */ +#define MDB_ALLOC_CHUNKSZ 4096 + + + +#define enable_interrupts() +#define disable_interrupts() + + +//#define MDB_DEBUG + +#ifdef MDB_DEBUG +#define ASSERT_BL(_bl_) \ +{ \ + mdb_mng_t *p = NULL, *m = (mdb_mng_t *) (_bl_)->list_of_lists; \ + mdb_link_t *l; \ + int cnt; \ + \ + if ( m ) { \ + ASSERT( m->prev_freelist == NULL ); \ + do { \ + ASSERT( m->prev_freelist == p ); \ + ASSERT( m->freelist != NULL ); \ + ASSERT( m->num_free > 0 ); \ + ASSERT( m->bl == (_bl_) ); \ + for ( cnt = 0, l = m->freelist; l; cnt++ ) \ + l = l->next; \ + ASSERT( cnt == m->num_free ); \ + p = m; \ + m = m->next_freelist; \ + } while ( m ); \ + } \ +} + +#else +# define ASSERT_BL(_bl_) +#endif + + + +/* + * Structure used for freelists. + */ +typedef struct mdb_link_t mdb_link_t; +struct mdb_link_t { + mdb_link_t *next; +}; + +/* + * Structure used for managing contents of a 4kb page. + */ +struct mdb_mng_t { + mdb_link_t *freelist; + dword_t num_free; + mdb_mng_t *next_freelist; + mdb_mng_t *prev_freelist; + mdb_buflist_t *bl; +}; + + +void mdb_buflist_init(void) +{ + mdb_buflist_t *bl; + dword_t i; + + /* + * Initialize the remaining fields in the buflists array. The max_ + * free field is calculated here so that we don't have to use + * division in the mdb_alloc_buffer() function. + */ + for ( bl = mdb_buflists; bl->size; bl++ ) + { + bl->list_of_lists = NULL; + if ( bl->size >= MDB_ALLOC_CHUNKSZ ) + continue; + for ( bl->max_free = 0, i = MDB_ALLOC_CHUNKSZ - bl->size; + i >= sizeof(mdb_mng_t); + i -= bl->size, bl->max_free++ ) {} + } +} + + + +/* + * Function mdb_alloc_buffer (size) + * + * Allocate a buffer of the indicated size. It is assumed the size + * is at least 8, and a multiple of 4. + * + */ +ptr_t mdb_alloc_buffer(dword_t size) +{ + mdb_buflist_t *bl; + mdb_link_t *buf; + mdb_mng_t *mng; + + /* + * Find the correct buffer list. + */ + for ( bl = mdb_buflists; bl->size != size; bl++ ) + { + if ( bl->size == 0 ) + { + printf("MDB alloc size = %d\n", size); + panic("Illegal MDB buffer allocation size.\n"); + } + } + + /* + * Forward large buffer requests directly to the kmem allocator. + */ + if ( size >= MDB_ALLOC_CHUNKSZ ) + return kmem_alloc(size); + + disable_interrupts(); + + /* + * Get pool of available buffers. + */ + mng = (mdb_mng_t *) bl->list_of_lists; + if ( mng == NULL ) + { + mdb_link_t *b, *n, *p, *ed; + + enable_interrupts(); + + /* + * First slot of page is dedicated to management strucures. + */ + mng = (mdb_mng_t *) kmem_alloc(MDB_ALLOC_CHUNKSZ); + mng->freelist = (mdb_link_t *) + ((dword_t) mng + MDB_ALLOC_CHUNKSZ - bl->max_free*size); + mng->num_free = bl->max_free; + mng->prev_freelist = (mdb_mng_t *) NULL; + mng->bl = bl; + + /* + * Initialize buffers. + */ + ed = (mdb_link_t *) ((dword_t) mng + MDB_ALLOC_CHUNKSZ - size); + for ( b = mng->freelist; b <= ed; b = n ) + { + n = (mdb_link_t *) ((dword_t) b + size); + b->next = n; + } + p = (mdb_link_t *) ((dword_t) b - size); + p->next = (mdb_link_t *) NULL; + + disable_interrupts(); + + /* + * Update list of freelists. + */ + mng->next_freelist = (mdb_mng_t *) bl->list_of_lists; + bl->list_of_lists = (ptr_t) mng; + if ( mng->next_freelist ) + { + mng->next_freelist->prev_freelist = mng; + } + } + + ASSERT_BL(bl); + + /* + * Remove buffer from freelist inside page. + */ + buf = mng->freelist; + mng->freelist = buf->next; + mng->num_free--; + + if ( mng->num_free == 0 ) + { + /* + * All buffers in page have been used. Remove freelist from + * list_of_lists. + */ + bl->list_of_lists = (ptr_t) mng->next_freelist; + if ( bl->list_of_lists != NULL ) + ((mdb_mng_t *) bl->list_of_lists)->prev_freelist = + (mdb_mng_t *) NULL; + } + + ASSERT_BL(bl); + enable_interrupts(); + + return (ptr_t) buf; +} + + +/* + * Function mdb_free_buffer (addr) + * + * Free buffer at address `addr'. + * + */ +void mdb_free_buffer(ptr_t addr, dword_t size) +{ + mdb_buflist_t *bl; + mdb_mng_t *mng; + mdb_link_t *buf; + + /* + * Forward large buffer requests directly to the kmem allocator. + */ + if ( size >= MDB_ALLOC_CHUNKSZ ) + { + kmem_free(addr, size); + return; + } + + buf = (mdb_link_t *) addr; + mng = (mdb_mng_t *) ((dword_t) addr & ~(MDB_ALLOC_CHUNKSZ-1)); + bl = mng->bl; + + ASSERT_BL(bl); + disable_interrupts(); + + /* + * Put buffer into local pool of buffers. + */ + buf->next = mng->freelist; + mng->freelist = buf; + mng->num_free++; + + if ( mng->num_free == 1 ) + { + /* + * Buffer pool has gone from empty to non-empty. Put pool back + * into list of pools. + */ + if ( bl->list_of_lists ) + ((mdb_mng_t *) bl->list_of_lists)->prev_freelist = mng; + mng->next_freelist = (mdb_mng_t *) bl->list_of_lists; + mng->prev_freelist = (mdb_mng_t *) NULL; + bl->list_of_lists = (ptr_t) mng; + + } + else if ( mng->num_free == bl->max_free ) + { + /* + * We have freed up all buffers in the frame. Give frame back + * to kernel memory allocator. + */ + if ( mng->next_freelist ) + mng->next_freelist->prev_freelist = mng->prev_freelist; + + if ( bl->list_of_lists == (ptr_t) mng ) + bl->list_of_lists = (ptr_t) mng->next_freelist; + else if ( mng->prev_freelist ) + mng->prev_freelist->next_freelist = mng->next_freelist; + + kmem_free((ptr_t) mng, MDB_ALLOC_CHUNKSZ); + } + + ASSERT_BL(bl); + enable_interrupts(); +} + diff --git a/kernel/src/mapping_alloc.o b/kernel/src/mapping_alloc.o new file mode 100644 index 0000000..79f89f0 Binary files /dev/null and b/kernel/src/mapping_alloc.o differ diff --git a/kernel/src/memory.c b/kernel/src/memory.c new file mode 100644 index 0000000..8e49605 --- /dev/null +++ b/kernel/src/memory.c @@ -0,0 +1,677 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, 2002, Karlsruhe University + * + * File path: memory.c + * Description: Architecture independent multilevel page table + * access functions. + * + * @LICENSE@ + * + * $Id: memory.c,v 1.20 2002/06/07 17:03:41 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#if defined(CONFIG_IO_FLEXPAGES) +#include INC_ARCH(io_mapping.h) +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) +#define USER_LIMIT SMALL_SPACE_START +#else +#define USER_LIMIT TCB_AREA +#endif + + +extern int __kdebug_pf_tracing; + + +/* + * Function sys_fpage_unmap (fpage, mapmask) + * + * The system call interface for fpage_unmap(). + * + */ +void sys_fpage_unmap(fpage_t fpage, dword_t mapmask) +{ + TRACEPOINT_2PAR(SYS_FPAGE_UNMAP, fpage.raw, mapmask); +#if defined(CONFIG_DEBUG_TRACE_SYSCALLS) + printf("%s(%x, %x) - %p\n", __FUNCTION__, fpage.raw, mapmask, + get_current_tcb()); +#endif +#if defined(CONFIG_IO_FLEXPAGES) + + /* Before doing anything related to main memory, check, if send fpage is + * actually a IO-Flexpage + */ + if (EXPECT_FALSE(IOFP_LO_BOUND <= fpage.raw && fpage.raw <= IOFP_HI_BOUND)){ + unmap_io_fpage(get_current_tcb(), fpage, mapmask); + return; + } + +#endif + fpage_unmap(get_current_tcb()->space, fpage, mapmask); +} + + + +/* + * Helper functions. + */ + +static inline dword_t base_mask(fpage_t fp, dword_t num) +{ + return ((~0U) >> (32 - fp.fpage.size)) & ~((~0U) >> (32 - num)); +} + +static inline dword_t address(fpage_t fp, dword_t num) +{ + return fp.raw & ~((~0U) >> (32 - num)); +} + +static inline int is_pgsize_valid (dword_t pgsize) +{ + return (1 << hw_pgshifts[pgsize]) & HW_VALID_PGSIZES; +} + +/* + * the mapping database is made SMP save by a code lock + */ +DEFINE_SPINLOCK(mdb_spinlock); +#define SPIN_LOCK_MDB spin_lock(&mdb_spinlock); +#define SPIN_UNLOCK_MDB spin_unlock(&mdb_spinlock); + + +/* + * Function map_fpage (from, to, base, snd_fp, rcv_fp) + * + * Map/grant a flexpage from one thread to another. + * + */ +int map_fpage(tcb_t *from, tcb_t *to, dword_t base, + fpage_t snd_fp, fpage_t rcv_fp) +{ + dword_t offset, f_addr, t_addr, f_num, t_num; + dword_t pgsize, f_size, t_size; + pgent_t *fpg, *tpg; + mnode_t *newmap, *map; + + pgent_t *r_fpg[HW_NUM_PGSIZES-1], *r_tpg[HW_NUM_PGSIZES-1]; + dword_t r_fnum[HW_NUM_PGSIZES-1], r_tnum[HW_NUM_PGSIZES-1]; +#if defined(CONFIG_SMP) + int tlb_shootdown = 0; +#endif + +#if defined(CONFIG_IO_FLEXPAGES) + + /* + * Before doing anything related to main memory, check, if send fpage is + * actually a IO-Flexpage + */ + if (EXPECT_FALSE(IOFP_LO_BOUND <= snd_fp.raw && snd_fp.raw <= IOFP_HI_BOUND)){ + return map_io_fpage(from, to, snd_fp); + } + +#endif +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("map_fpage(sender=%p, receiver=%p, base=%x, " + "sndfp=%x, rcvfp=%x)\n", from, to, base, + snd_fp.raw, rcv_fp.raw); + } +#endif + + /* + * Calculate the actual send and receive address to use. This is + * almost magic. Please THINK before you consider changing this. + */ + if ( snd_fp.fpage.size <= rcv_fp.fpage.size ) + { + f_num = snd_fp.fpage.size; + base &= base_mask(rcv_fp, f_num); + f_addr = address(snd_fp, f_num); + t_addr = (address(rcv_fp, f_num) & ~base_mask(rcv_fp, f_num)) + base; + } + else + { + enter_kdebug("map_fpage(): Larger send window"); + return 0; + } + + if ( f_num < hw_pgshifts[0] ) + { + enter_kdebug("map_fpage(): Invalid fpage size"); + return 0; + } + + /* + * Setting bit 0 in the from address indicates to mdb_map() that + * we are doing a grant operation. + */ + if ( snd_fp.fpage.grant ) + f_addr |= 0x1; + + + /* + * Find pagesize to use, and number of pages to map. + */ + for (pgsize = HW_NUM_PGSIZES-1; + (hw_pgshifts[pgsize] > f_num) || (!is_pgsize_valid (pgsize)); + pgsize--) {} + f_num = t_num = 1 << (f_num - hw_pgshifts[pgsize]); + f_size = t_size = HW_NUM_PGSIZES-1; + + fpg = from->space->pgent (table_index (f_addr, f_size)); + tpg = to->space->pgent (table_index (t_addr, t_size)); + + SPIN_LOCK_MDB; + + while ( f_num > 0 || t_num > 0 ) + { + if ( (f_addr >= USER_LIMIT && from != sigma0) || t_addr >= USER_LIMIT ) + { + /* Do not mess with the kernel area. */ + break; + } + + if ( from == sigma0 ) + { + /* + * When mapping from sigma0 we bypass the page table lookup. + */ + f_size = pgsize; + } + else + { + if ( !fpg->is_valid(from->space, f_size) ) + { + while ( t_size < f_size ) + { + /* Recurse up. */ + tpg = r_tpg[t_size]; + t_num = r_tnum[t_size]; + t_size++; + } + + if ( t_size == f_size ) + goto Next_receiver_entry; + + /* t_size > f_size */ + goto Next_sender_entry; + } + + if ( (f_size > pgsize) && fpg->is_subtree(from->space, f_size) ) + { + /* + * We are currently working on to large page sizes. + */ + f_size--; + fpg = fpg->subtree (from->space, f_size+1)->next + (from->space, table_index(f_addr, f_size), f_size); + continue; + } + else if ( fpg->is_subtree(from->space, f_size) ) + { + /* + * The mappings in the senders address space are to small. + * We have to map each single entry in the subtree. + */ + f_size--; + r_fpg[f_size] = fpg->next(from->space, 1, f_size+1); + r_fnum[f_size] = f_num - 1; + + fpg = fpg->subtree(from->space, f_size+1); + f_num = table_size(f_size); + continue; + } + else if ( f_size > pgsize ) + { + f_num = 1; + } + } + + /* + * If we get here `fpg' is a valid mapping in the senders + * address space. + */ + + + if ( (t_size > f_size) || ((t_size > pgsize) && (f_size > pgsize)) ) + { + /* + * We are currently working on larger receive pages than + * send pages. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + + if ( !tpg->is_valid(to->space, t_size+1) ) + { + /* + * Subtree does not exist. Create one. + */ + tpg->make_subtree(to->space, t_size+1); + } + else if ( !tpg->is_subtree(to->space, t_size+1) ) + { + /* + * There alredy exists a larger mapping. Just + * continue. BEWARE: This may cause extension of + * access rights to be refused even though they are + * perfectly legal. I.e. if all the mappings in the + * subtree of the sender's address space are valid. + */ + printf("map_fpage(): Larger mapping already exists.\n"); + enter_kdebug(); + goto Next_receiver_entry; + } + + if ( t_size >= pgsize ) + { + tpg = tpg->subtree (to->space, t_size+1)->next + (to->space, table_index(t_addr, t_size), t_size); + continue; + } + else + { + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + } + + /* Adjust destination according to where source is located. */ + tpg = tpg->next(to->space, table_index(f_addr, t_size), t_size); + t_num -= table_index(f_addr, t_size); + t_addr += table_index(f_addr, t_size) << hw_pgshifts[t_size]; + continue; + } + else if ( tpg->is_valid(to->space, t_size) && + tpg->is_subtree(to->space, t_size) ) + { + /* + * Target mappings are of smaller page size. We have to + * map each single entry in the subtree. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + } + else if ( !is_pgsize_valid (t_size) ) + { + /* + * Pagesize is ok but is not a valid hardware pagesize. + * Need to create mappings of smaller size. + */ + t_size--; + r_tpg[t_size] = tpg->next(to->space, 1, t_size+1); + r_tnum[t_size] = t_num - 1; + tpg->make_subtree(to->space, t_size+1); + + tpg = tpg->subtree(to->space, t_size+1); + t_num = table_size(t_size); + continue; + } + + + /* + * If we get here `tpg' will be the page table entry that we + * are going to change. + */ + + offset = f_addr & page_mask(f_size) & ~page_mask(t_size); + + if ( tpg->is_valid(to->space, t_size) ) + { + /* + * If a mapping already exists, it might be that we are + * just extending the current access rights. + */ + if ( (from == sigma0) ? (tpg->address(to->space, t_size) != f_addr) : + (tpg->address(to->space, t_size) != + fpg->address(from->space, f_size) + offset) ) + { + printf("map_fpage(sender=%p, receiver=%p, base=%x, " + "sndfp=%x, rcvfp=%x)\n", from, to, base, + snd_fp.raw, rcv_fp.raw); + enter_kdebug("map_fpage(): Mapping already exists."); + goto Next_receiver_entry; + } + + /* Extent access rights. */ + if ( (fpg->is_writable(from->space, t_size) || from == sigma0) && + snd_fp.fpage.write ) + { + tpg->set_writable(to->space, t_size); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (to->space->is_small ()) + flush_tlbent ((ptr_t) (t_addr + + to->space->smallid ().offset ())); + else if (from->space->is_small ()) + flush_tlbent((ptr_t) t_addr); +#endif +#if defined(CONFIG_SMP) + tlb_shootdown = 1; +#endif + } + } + else + { + /* + * This is where the real work is done. + */ + + if ( from == sigma0 ) + { + /* + * If mapping from sigma0, fpg will not be a valid + * page table entry. + */ +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("paddr=%p mdb_map(from=sigma0,4G,%p, " + "to=%p,%dk,%p)\n", + f_addr, f_addr, (dword_t) to->space, + 1 << (hw_pgshifts[t_size] - 10), t_addr); + if ( __kdebug_mdb_tracing > 1 ) + enter_kdebug("mdb_map"); + } +#endif + + newmap = mdb_map(sigma0_mapnode, fpg, HW_NUM_PGSIZES, + f_addr + offset, tpg, t_size, + to->space); + + tpg->set_entry(to->space, f_addr, snd_fp.fpage.write, t_size); + tpg->set_mapnode(to->space, t_size, newmap, t_addr); + +#if defined(CONFIG_CACHEABILITY_BITS) + if (snd_fp.fpage.uncacheable) + tpg->set_uncacheable(to->space, t_size); + if (snd_fp.fpage.unbufferable) + tpg->set_unbufferable(to->space, t_size); +#endif + } + else + { +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("mdb_map(paddr=%p, from=%p,%dK,%p, to=%p,%dk,%p)\n", + fpg->address(from->space, f_size) + offset, + (dword_t) from->space, + 1 << (hw_pgshifts[f_size] - 10), + f_addr, to->space, + 1 << (hw_pgshifts[t_size] - 10), t_addr); + if ( __kdebug_mdb_tracing > 1 ) + enter_kdebug("mdb_map"); + } +#endif + + map = fpg->mapnode(from->space, f_size, + f_addr & ~page_mask(f_size)); + + // Make sure that we are not flushed. + while ( ! map->up_trylock() ) + if ( ! fpg->is_valid(from->space, f_size) ) + goto Next_receiver_entry; + else + enter_kdebug("map_fpage: waiting for uplock"); + + newmap = mdb_map(map, fpg, f_size, f_addr, tpg, t_size, + to->space); + + tpg->set_entry(to->space, + fpg->address(from->space, f_size) + offset, + fpg->is_writable(from->space, f_size) && + snd_fp.fpage.write, + t_size); + tpg->set_mapnode(to->space, t_size, newmap, t_addr); + +#if defined(CONFIG_CACHEABILITY_BITS) + if (snd_fp.fpage.uncacheable) + tpg->set_uncacheable(to->space, t_size); + if (snd_fp.fpage.unbufferable) + tpg->set_unbufferable(to->space, t_size); +#endif + + if ( f_addr & 0x1 ) + { + /* Grant operation. Remove mapping from current space. */ + fpg->clear(from->space, f_size); +#if defined(CONFIG_ENABLE_SMALL_AS) + if (from->space->is_small ()) + flush_tlbent ((ptr_t) (f_addr + from->space->smallid + ().offset ())); + else +#endif + flush_tlbent((ptr_t) f_addr); + } + newmap->up_unlock(); + map->up_unlock(); + } + } + + Next_receiver_entry: + + t_addr += page_size(t_size); + t_num--; + + if ( t_num > 0 ) + { + /* Go to next entry */ + tpg = tpg->next(to->space, 1, t_size); + if ( t_size < f_size ) + continue; + } + else if ( t_size < f_size && f_size < pgsize ) + { + /* Recurse up */ + tpg = r_tpg[t_size]; + t_num = r_tnum[t_size]; + t_size++; + continue; + } + else if ( t_size > f_size ) + { + /* Skip to next fpg entry. Happens if tpg is already mapped. */ + f_addr += page_size(t_size) - page_size(f_size); + f_num = 1; + } + + Next_sender_entry: + + f_addr += page_size(f_size); + f_num--; + + if ( f_num > 0 ) + { + /* Go to next entry */ + if ( from != sigma0 ) + fpg = fpg->next(from->space, 1, f_size); + continue; + } + else if ( f_size < pgsize ) + { + /* Recurse up */ + fpg = r_fpg[f_size]; + f_num = r_fnum[f_size]; + f_size++; + } + else + { + /* Finished */ + t_num = 0; + } + } + SPIN_UNLOCK_MDB; +#if defined (CONFIG_SMP) + if (tlb_shootdown) + smp_flush_tlb(); +#endif + return 1; +} + + +/* + * Function fpage_unmap (space, fpage, mapmask) + * + * Unmap FPAGE from SPACE. MAPMASK indicates whether to flush or + * remap, and if current pgdir should also be flushed. + * + */ +void fpage_unmap(space_t *space, fpage_t fpage, dword_t mapmask) +{ + dword_t vaddr, num, size, pgsize; + pgent_t *pg; + mnode_t *map; + int r; + + pgent_t *r_pg[HW_NUM_PGSIZES-1]; + dword_t r_num[HW_NUM_PGSIZES-1]; +#if defined(CONFIG_SMP) + int tlb_shootdown = 0; +#endif + +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("fpage_unmap(%x, %x, %x)\n", space, fpage.raw, mapmask); + } +#endif + + num = fpage.fpage.size; + vaddr = address(fpage, num); + + if ( num < hw_pgshifts[0] ) + { + printf("map_fpage(): Invalid fpage size (%d).\n", num); + enter_kdebug(); + return; + } + + /* + * Find pagesize to use, and number of pages to map. + */ + for (pgsize = HW_NUM_PGSIZES-1; + (hw_pgshifts[pgsize] > num) || (!is_pgsize_valid (pgsize)); + pgsize-- ) {} + num = 1 << (num - hw_pgshifts[pgsize]); + + size = HW_NUM_PGSIZES-1; + pg = space->pgent (table_index (vaddr, size)); + + SPIN_LOCK_MDB; + + while ( num ) + { + if ( vaddr >= USER_LIMIT ) + /* Do not mess with the kernel area. */ + break; + + if ( size > pgsize ) + { + /* We are operating on to large page sizes. */ + if ( ! pg->is_valid(space, size) ) + break; + else if ( pg->is_subtree(space, size) ) + { + size--; + pg = pg->subtree(space, size+1)->next + (space, table_index(vaddr, size), size); + continue; + } + else if ( mapmask & MDB_ALL_SPACES ) + { + printf("fpage_unmap(%x, %x, %x)\n", space, fpage.raw, mapmask); + enter_kdebug("fpage_unmap: page is to large"); + break; + } + } + + if ( ! pg->is_valid(space, size) ) + goto Next_entry; + + if ( pg->is_subtree(space, size) ) + { + /* We have to flush each single page in the subtree. */ + size--; + r_pg[size] = pg; + r_num[size] = num - 1; + + pg = pg->subtree(space, size+1); + num = table_size(size); + continue; + } + +#if defined(CONFIG_DEBUG_TRACE_MDB) + if ( __kdebug_mdb_tracing ) + { + printf("mdb_flush(space=%p, vaddr=%p, %dK:%p, %dk:%p, mode=%p)\n", + space, vaddr, + 1 << (hw_pgshifts[size] - 10), + pg->address(space, size), + 1 << (hw_pgshifts[pgsize] - 10), + pg->address(space, size) + (vaddr & page_mask(size)), + mapmask); + if ( __kdebug_mdb_tracing > 1) + enter_kdebug("mdb_flush"); + } +#endif + map = pg->mapnode(space, size, vaddr & ~page_mask(size)); + + // Make sure that we are not flushed. + while ( ! map->up_trylock() ) + if ( ! pg->is_valid(space, size) ) + goto Next_entry; + else + enter_kdebug("fpage_unmap: waiting for uplock"); + + r = mdb_flush(pg->mapnode(space, size, vaddr & ~page_mask(size)), + pg, size, vaddr, pgsize, mapmask); + if ( r == -1 ) + enter_kdebug("fpage_unmap: page already flushed"); +#if defined(CONFIG_SMP) + else + tlb_shootdown |= r; +#endif + Next_entry: + + pg = pg->next(space, 1, size); + vaddr += page_size(size); + num--; + + if ( num == 0 && size < pgsize ) + { + /* Recurse up */ + pg = r_pg[size]; + num = r_num[size]; + size++; + + if ( (mapmask & MDB_ALL_SPACES) && (mapmask & MDB_FLUSH) ) + pg->remove_subtree(space, size); + pg = pg->next(space, 1, size); + } + } + SPIN_UNLOCK_MDB; +#if defined(CONFIG_SMP) + smp_flush_tlb(); +#endif +} + + + + + + + + + + + diff --git a/kernel/src/memory.o b/kernel/src/memory.o new file mode 100644 index 0000000..f3d85d8 Binary files /dev/null and b/kernel/src/memory.o differ diff --git a/kernel/src/mips/.cvsignore b/kernel/src/mips/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/mips/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/mips/Makefile b/kernel/src/mips/Makefile new file mode 100644 index 0000000..1526b09 --- /dev/null +++ b/kernel/src/mips/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: mips/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.6 2001/11/22 13:27:53 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libarch.a +OBJ_SRC = +LIB_SRC = init.c memory.c mapping.c interrupt.c + + +###################################################################### +# includes +include ../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/mips/exception.S b/kernel/src/mips/exception.S new file mode 100755 index 0000000..f7a1ef2 --- /dev/null +++ b/kernel/src/mips/exception.S @@ -0,0 +1,252 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/exception.S + * Description: Exception entries for MIPS. + * + * @LICENSE@ + * + * $Id: exception.S,v 1.2 2001/11/22 13:27:53 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + + .set noat + +#define ENTRY(name) \ + .globl name ; \ + .align 2 ; \ + .type name, @function ; \ + .ent name, 0 ; \ +name: + +#define END(name) \ + .globl name##__end ; \ + .end name ; \ + .size name,.-name ; \ +name##__end: + + +.MACRO open_frame + mfc0 k1, CP0_STATUS + andi k0, k1, ST0_KUP + beq k0, zero, 9f // If we came from kernel + la k0, current_stack + lw k0, 0(k0) + + addiu k0, k0, -4 + sw sp, 0(k0) + move sp, k0 +9: + addiu sp, sp, -8 + mfc0 k0, CP0_EPC // Return address + sw k1, 4(sp) // push mode + sw k0, 0(sp) // Save return address +.ENDM + + +.MACRO close_frame + .set push + .set reorder + + lw k1, 4(sp) // Status + lw k0, 0(sp) // Return address + + mtc0 k1, CP0_STATUS + + andi k1, k1, ST0_KUP + bne k1, zero, 9f // If we did not come from kernel + addiu sp, sp, 8 + eret + jr k0 +9: + + lw sp, 8(sp) // User stack pointer + eret // Restore from exception + jr k0 // Return to user + nop + .set pop +.ENDM + + +ENTRY(tlb_refill) + .set noreorder + .set noat + + la k0, current_page_table + lw k0, 0(k0) + + /* get pagedir entry */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, PAGEDIR_BITS + sll k1, k1, 2 + add k0, k0, k1 + + lw k0, 0(k0) /* k0 is pdir-entry */ + beq k0, zero, refill_fault + + /* now the pagetable */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, (PAGE_BITS - 2) + andi k1, k1, ((~PAGE_MASK) << 2) + add k1, k1, k0 + lw k0, 0(k1) /* ptab entry */ + beq k0, zero, refill_fault + srl k1, k1, 3 + sll k1, k1, 3 +#if 0 + move a0, k0 + move a1, k1 + j 9f +#endif + +#if 1 + lw k0, 0(k1) + lw k1, 4(k1) + srl k0, k0, 2 + srl k1, k1, 2 + + mtc0 k0, CP0_ENTRYLO0 + mtc0 k1, CP0_ENTRYLO1 + b 1f + tlbwr # write random tlb entry +1: + nop + eret # return from trap +#else + lw a0, 0(k1) + lw a1, 4(k1) + move a2, k1 +9: + la k0, tlb_refill__FUiUi + jr k0 + nop +#endif + + +refill_fault: + la k0, handle_pagefault + jr k0 + nop +END(tlb_refill) + +ENTRY(handle_pagefault) + .set reorder + open_frame + + addiu sp, sp, -15*4 + + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + + sw t0, 12(sp) + sw t1, 16(sp) + sw t2, 20(sp) + sw t3, 24(sp) + sw t4, 28(sp) + sw t5, 32(sp) + sw t6, 36(sp) + sw t7, 40(sp) + sw v1, 44(sp) + sw ra, 48(sp) + sw v0, 52(sp) + sw gp, 56(sp) + + mfc0 a0, CP0_BADVADDR + mfc0 a1, CP0_CAUSE + mfc0 a2, CP0_EPC + mfc0 a3, CP0_STATUS + + jal pagefault__FUiUiUi + + + lw a0, 0(sp) + lw a1, 4(sp) + lw a2, 8(sp) + + lw t0, 12(sp) + lw t1, 16(sp) + lw t2, 20(sp) + lw t3, 24(sp) + lw t4, 28(sp) + lw t5, 32(sp) + lw t6, 36(sp) + lw t7, 40(sp) + lw v1, 44(sp) + lw ra, 48(sp) + lw v0, 52(sp) + lw gp, 56(sp) + + addiu sp, sp, 15*4 + + close_frame +END(handle_pagefault) + +ENTRY(exception_handler) + mfc0 k0, CP0_CAUSE + and k1, k0, 0x3c + la k0, except_table + add k1, k0, k1 + lw k1, 0(k1) + beqz k1, 1f + jr k1 // Jump + +1: + la k0, general_exception + jr k0 + nop +END(exception_handler) + +ENTRY(exception_cache_error) + la k0, mips_cache_error__Fv + jr k0 +1: + j 1b +END(exception_cache_error) + +ENTRY(switch_to_sigma0__Fv) + addiu sp, 4 + /* fall through */ +END(switch_to_sigma0__Fv) + +// this is the general entry point for all user functions +ENTRY(switch_to_user__Fv) + lw k0, 0(sp) // uip + lw k1, 4(sp) // status + mtc0 k1, CP0_STATUS + lw sp, 8(sp) // usp + eret + jr k0 + +END(switch_to_user__Fv) + +general_exception: + mfc0 a1, CP0_EPC + mfc0 a2, CP0_STATUS + la k0, exception__FUiUiUi + jalr k0 + nop + eret + + +except_table: + .word general_exception + .word 0 + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word general_exception + .word general_exception + .word general_exception + .word general_exception + + + + + + diff --git a/kernel/src/mips/init.c b/kernel/src/mips/init.c new file mode 100644 index 0000000..5aeb079 --- /dev/null +++ b/kernel/src/mips/init.c @@ -0,0 +1,93 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/init.c + * Description: MIPS specific initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.4 2001/11/22 13:27:53 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +/* Master romvec interface. */ +struct linux_romvec *romvec; +struct linux_promblock *sgi_pblock; +int prom_argc; +char **prom_argv, **prom_envp; +unsigned short prom_vers, prom_rev; + + +void init_arch_1() +{ + //printf(__FUNCTION__); + init_paging(); +} + +void init_arch_2() +{ +} + +void init_arch_3() +{ + printf(__FUNCTION__); + enter_kdebug(); +} + +#define DEF_EXCEPT(name) extern "C" void* name##();extern "C" void* name##__end(); +#define EXCEPT_LEN(name) (((dword_t)(##name##__end)) - (dword_t)(name)) + +DEF_EXCEPT(exception_handler); +DEF_EXCEPT(exception_cache_error); +DEF_EXCEPT(tlb_refill); + +void setup_excp_vector() +{ + zero_memory((dword_t*)EXCEPTION_VECTOR_BASE, 0x200); + + if (EXCEPT_LEN(tlb_refill) > 128 || EXCEPT_LEN(exception_handler) > 128 || + EXCEPT_LEN(exception_cache_error) > 128) + panic("invalid exception handler size!\n"); + + memcpy((dword_t*)EXCEPTION_TLB_REFILL, + (dword_t*)tlb_refill, + EXCEPT_LEN(tlb_refill)); + + memcpy((dword_t*)EXCEPTION_XTLB_REFILL, + (dword_t*)tlb_refill, + EXCEPT_LEN(tlb_refill)); + + + memcpy((dword_t*)EXCEPTION_OTHER, + (dword_t*)exception_handler, + EXCEPT_LEN(exception_handler)); + + memcpy((dword_t*)EXCEPTION_CACHE_ERROR, + (dword_t*)exception_cache_error, + EXCEPT_LEN(exception_cache_error)); + + printf(__FUNCTION__); + enter_kdebug(); +} + +void tlb_refill(dword_t val1, dword_t val2) +{ + printf("tlb refill: %x, %x)\n", val1, val2); + panic("tlb"); +} + +void exception(dword_t cause, dword_t ip, dword_t status) +{ + printf("exception cause: %x (err: %d), ip: %x, status: %x\n", cause, + (cause >> 2) & 0x1f, ip, status); + enter_kdebug(); +} + +void mips_cache_error() +{ + panic(__FUNCTION__); +} + diff --git a/kernel/src/mips/interrupt.c b/kernel/src/mips/interrupt.c new file mode 100644 index 0000000..01bb031 --- /dev/null +++ b/kernel/src/mips/interrupt.c @@ -0,0 +1,31 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/interrupt.c + * Description: MIPS interrupt handling code. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.3 2001/11/22 13:27:53 skoglund Exp $ + * + ********************************************************************/ +#include + + +void init_irqs() +{ +} + + +void irq_handler(dword_t num) +{ +} + +void mask_interrupt(unsigned int number) +{ +} + +void unmask_interrupt(unsigned int number) +{ +} diff --git a/kernel/src/mips/mapping.c b/kernel/src/mips/mapping.c new file mode 100644 index 0000000..7c42f81 --- /dev/null +++ b/kernel/src/mips/mapping.c @@ -0,0 +1,27 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: mips/mapping.c + * Description: Mapping specification for MIPS. + * + * @LICENSE@ + * + * $Id: mapping.c,v 1.2 2001/11/22 13:27:53 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +dword_t mdb_pgshifts[2] = { + 12, // 4KB + 32 // 4GB (whole address space) +}; + +mdb_buflist_t mdb_buflists[4] = { + { 12 }, // Mapping nodes + { 8 }, // ptrnode_t + { 4096 }, // 4KB array + { 0 } +}; + diff --git a/kernel/src/mips/memory.c b/kernel/src/mips/memory.c new file mode 100644 index 0000000..3728953 --- /dev/null +++ b/kernel/src/mips/memory.c @@ -0,0 +1,484 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/memory.c + * Description: MIPS specific memory management handling. + * + * @LICENSE@ + * + * $Id: memory.c,v 1.5 2001/11/22 13:27:53 skoglund Exp $ + * + ********************************************************************/ +#include +#include + +dword_t __pdir_root[PAGE_SIZE / 4] __attribute__((aligned(4096))); + +/* context specific registers */ +dword_t * current_stack; +dword_t * current_page_table; + +#define EXC_CODE(x) ((x >> 2) & 0x1f) + +#define PF_USERMODE(x) (x < KERNEL_VIRT) +#define PF_WRITE(x) (EXC_CODE(x) == 3) +#define PF_PROTECTION(x) (EXC_CODE(x) == 1) + +#define FP_NUM_PAGES(x) (1 << (((x & 0xfc) >> 2) - PAGE_BITS)) +#define FP_ADDR(x) (x & PAGE_MASK) + +//#define DOUBLE_PF_CHECK +#ifdef DOUBLE_PF_CHECK +static dword_t last_pf_addr = ~0; +static tcb_t * last_pf_tcb = NULL; +#endif + +void init_paging() +{ + zero_memory(__pdir_root, PAGE_SIZE); + printf("pdir_root: %x\n", __pdir_root); + + __asm__ __volatile__ ( + "mtc0 %0, $5\n" + : + : "r"(0x00fffc000)); + + current_page_table = __pdir_root; + +} + +ptr_t create_new_pagetable() +{ + printf("create_new_ptab\n"); + + // allocate root ptab + dword_t *pt = (dword_t*)kmem_alloc(PAGE_SIZE); + + // now copy the kernel area - assumption: one pagetable + pt[KERNEL_VIRT >> PAGEDIR_BITS] = __pdir_root[KERNEL_VIRT >> PAGEDIR_BITS]; + + /* and the tcb area. we need that, because otherwise we cannot create + * new tasks. we create a task and switch to it. the exception stack is + * on our own tcb. thus we need at least our own tcb mapped. + */ + for (dword_t i = (TCB_AREA >> PAGEDIR_BITS); i < ((TCB_AREA + TCB_AREA_SIZE) >> PAGEDIR_BITS); i++) + pt[i] = __pdir_root[i]; + + return pt; +} + +/* + * Function delete_pagetable (tcb) + * + * Called from task_delete(). + * + */ +void delete_pagetable(tcb_t *tcb) +{ + /* Flush whole address space. */ + fpage_unmap((dword_t) tcb->page_dir, FPAGE_WHOLE_SPACE, + (FPAGE_OWN_SPACE | FPAGE_FLUSH)); + + /* Delete page directory. */ + kmem_free((ptr_t) phys_to_virt(tcb->page_dir), PAGE_SIZE*2); +} + + +void mips_map_kpage(dword_t addr, dword_t val) +{ + printf("mips_map_kpage %x, %x\n", addr, val); + + dword_t *ptab = (dword_t*)__pdir_root[addr >> PAGEDIR_BITS]; + + /* first check if there is a second level pagetable */ + if (!ptab) + { + /* allocate second level */ + ptab = kmem_alloc(PAGE_SIZE); + __pdir_root[addr >> PAGEDIR_BITS] = (dword_t)(ptab); + printf("alloced 2nd level: %x\n", __pdir_root[addr >> PAGEDIR_BITS]); + } + ptab[(addr >> PAGE_BITS) & ~PAGE_MASK] = val; +} + +void mips_map_upage(ptr_t pdir, dword_t addr, dword_t val) +{ + printf("mips_map_upage %x, %x, %x\n", pdir, addr, val); + enter_kdebug("map userpage"); +#if 0 + dword_t *ptab = (dword_t*)pdir[addr >> PAGEDIR_BITS]; + dword_t *vptab; + + //printf("map_upage: pdir %x (%x), val %x\n", pdir, &pdir[addr >> 22], ptab); + /* first check if there is a second level pagetable */ + if (!((dword_t)ptab & PAGE_VALID)) + { + /* allocate second level */ + ptab = virt_to_phys(kmem_alloc(PAGE_SIZE)); + pdir[addr >> PAGEDIR_BITS] = ((dword_t)(ptab)) | PT_USER_TABLE; + } + vptab = phys_to_virt((dword_t*)((dword_t)ptab & PAGE_MASK)); + //printf("ptab: %x (%x), addr: %x, val: %x (%x)\n", ptab, vptab, addr, val, vptab[(addr >> 12) & 0x3ff]); + vptab[(addr >> PAGE_BITS) & ~PAGE_MASK] = val; +#endif +} + +dword_t lookup_page(ptr_t pdir, dword_t vaddr) +{ +#if 0 + dword_t *ptab = (dword_t*)pdir[vaddr >> PAGEDIR_BITS]; + dword_t *vtab; + if (!((dword_t)ptab & PAGE_VALID)) return NULL; + vtab = phys_to_virt((dword_t*)((dword_t)ptab & PAGE_MASK)); + return vtab[(vaddr >> PAGE_BITS) & ~PAGE_MASK]; +#else + return 0; +#endif +} + + +/* + * Function pg_flush (pgdir, vaddr, pgsize, mode) + * + * Called from mdb_flush() whenever a page table entry needs to be + * changed. + * + */ +void pg_flush(dword_t pgdir, dword_t vaddr, dword_t pgsize, dword_t mode) +{ + enter_kdebug("pg_flush not impl."); +#if 0 + dword_t *pdent, *ptent; + + + if ( __kdebug_pf_tracing ) + { + printf("pg_flush(%x, %x, %dK, %x)\n", + pgdir, vaddr, 1 << (mdb_pgshifts[pgsize]-10), mode); + } + + pdent = ((dword_t *) pgdir) + pgdir_idx(vaddr); + + if ( !(*pdent & PAGE_VALID) ) + { + printf("pg_flush: no pagetable present (pdir: %x, vaddr: %x, " + "pdent: %x)\n", pgdir, vaddr, *pdent); + enter_kdebug(); + return; + } + + /* Flush/remap regular page */ + ptent = (dword_t *) (*pdent & PAGE_MASK) + pgtab_idx(vaddr); + + if ( mode & MDB_FLUSH ) + *ptent = 0; + else + *ptent &= ~PAGE_WRITABLE; + + if ( pgdir == get_current_pagetable() ) + flush_tlbent((ptr_t) vaddr); +#endif +} + + +/********************************************************************** + * temporary mapping for IPC + * the resource bits are set in the pagefault handler!!! + */ + +ptr_t get_copy_area(tcb_t * from, tcb_t * to, ptr_t addr) +{ +#if 0 + //printf("get_map_area: %x->%x, %x\n", from, to, addr); + //enter_kdebug(); + + if (from->copy_area1 == COPYAREA_INVALID) + { + /* nothing mapped yet */ + from->copy_area1 = ((dword_t)addr & PAGEDIR_MASK); + return (ptr_t)(((dword_t)addr & ~PAGEDIR_MASK) + MEM_COPYAREA1); + } + else { + if (from->copy_area1 == ((dword_t)addr & PAGEDIR_MASK)) + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA1); + else if (from->copy_area2 == ((dword_t)addr & PAGEDIR_MASK)) + { + /* works for invalid too :) */ + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + else + { + if (from->resources & TR_IPC_MEM2) + { + /* resource area 2 in use -> worst case + * we have to manipulate the pagetable + */ + printf("remap copy_area2\n"); + enter_kdebug(); + + ptr_t pdir_from = phys_to_virt(from->page_dir); + ptr_t pdir_to = phys_to_virt((tid_to_tcb(from->partner))->page_dir); + pdir_from[MEM_COPYAREA2 >> PAGEDIR_BITS] = pdir_to[(dword_t)addr >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = pdir_to[((dword_t)addr >> PAGEDIR_BITS) + 1]; + + flush_tlb(); + } + + from->copy_area2 = ((dword_t)addr) & PAGEDIR_MASK; + //printf("copy_area2: %x\n",from->copy_area2); + //from->resources |= TR_IPC_MEM2; + + return (ptr_t)((((dword_t)addr) & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + } +#endif + return 0; +} + +void free_copy_area(tcb_t * tcb) +{ + tcb->copy_area1 = COPYAREA_INVALID; + tcb->copy_area2 = COPYAREA_INVALID; +} + +void save_resources(tcb_t * current, tcb_t * dest) +{ +#if 0 + printf("free thread resources (tcb: %x (%x))\n", current, current->resources); + if (current->resources | TR_IPC_MEM) + { + ptr_t pdir = phys_to_virt(current->page_dir); + pdir[MEM_COPYAREA1 >> PAGEDIR_BITS] = 0; + pdir[(MEM_COPYAREA1 >> PAGEDIR_BITS) + 1] = 0; + + pdir[MEM_COPYAREA2 >> PAGEDIR_BITS] = 0; + pdir[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = 0; + + if ((dest == get_idle_tcb()) || same_address_space(current, dest)) + flush_tlb(); + } + + current->resources = 0; +#endif +} + +void load_resources(tcb_t *current) +{ + /* currently no resources are loaded on MIPS */ +} + +void init_resources(tcb_t * tcb) +{ + /* currently no resources are initialized on MIPS */ +} + +void free_resources(tcb_t * tcb) +{ + /* currently no resources are freed on MIPS */ +} + +/********************************************************************** + * pagefault handling + */ + +dword_t get_current_stack() +{ + dword_t tmp; + asm("move %0, $sp\n" + : "=r"(tmp)); + return tmp; +} + +void pagefault(dword_t fault, dword_t cause, dword_t ip) +{ + tcb_t * current; + +#ifdef DOUBLE_PF_CHECK + if (last_pf_addr == fault && last_pf_tcb == get_current_tcb()) { + printf("double pagefault (%x)\n", fault); + enter_kdebug(); + } + last_pf_addr = fault; + last_pf_tcb = get_current_tcb(); +#endif + + //printf("pagefault: %x ip: %x, cause: %x\n", fault, ip, cause); + //printf("tcb: %x, stack: %x\n", get_current_tcb(), get_current_stack()); + + /*---- user pagefault ------------------------------------------------*/ + if (PF_USERMODE(ip)) + { + + current = get_current_tcb(); + printf("upf (%x): %x @ %x, err: %x\n", current, fault, ip, cause); + enter_kdebug(); + + if (fault >= TCB_AREA) + panic("user touches kernel area\n"); + + + if (current->page_dir == sigma0->page_dir) + { + /* sigma0 pf are simple map operations */ + ASSERT(fault < TCB_AREA); + mips_map_upage(phys_to_virt(current->page_dir), fault, + (fault & PAGE_MASK) | PT_SIGMA0); + return; + } + else { + printf("do pf ipc to %x\n", current->pager); + panic("upf"); + //do_pagefault_ipc(current, fault, ip); + return; + } + spin(78); + } + + /*---- kernel pagefault ----------------------------------------------*/ + + printf("kpf: %x @ %x, cause: %x\n", fault, ip, cause); + + + /* kernel pagefault */ + if (PF_PROTECTION(cause)) { + /* null-page remap? */ + dword_t phys = lookup_page(phys_to_virt(get_current_pagetable()), fault); + if ((phys & PAGE_MASK) == (dword_t)virt_to_phys(__zero_page)) + { + // remap + } + panic("kernel protection error"); + } + + if (fault < TCB_AREA) { + /* that is a string copy pf, registers are + * already transfered - ipc_buffer[...] can be spilled + */ + current = get_current_tcb(); + l4_threadid_t saved_partner = current->partner; + + printf("string copy pf..."); + enter_kdebug(); + //do_pagefault_ipc(current, fault, 0xffffffff); + //printf("...handled\n"); + + current->partner = saved_partner; + current->thread_state = TS_LOCKED_RUNNING; + + return; + } + else if (fault < (TCB_AREA + TCB_AREA_SIZE)) + { + /* is the area mapped in the kernel's pagetable ? */ + //tcb_t * current = get_current_tcb(); + ptr_t pdir = get_current_pagetable(); + + /* do we run on the kernel ptab (idler...)? */ + if (pdir != __pdir_root) + { + if (__pdir_root[fault >> PAGEDIR_BITS] != pdir[fault >> PAGEDIR_BITS]) + { + /* sync pagetables */ + pdir[fault >> PAGEDIR_BITS] = __pdir_root[fault >> PAGEDIR_BITS]; + return; + } + } + /* tcb map request */ + if (PF_WRITE(cause)) { + ptr_t page = kmem_alloc(PAGE_SIZE); + printf("map new tcb: %x\n", page); + mips_map_kpage(fault, ((dword_t)virt_to_phys(page)) | PT_TCB); + return; + } + else + { + printf("map zero page"); + enter_kdebug(); + } + } + else + { +#if 0 + if (fault >= MEM_COPYAREA1 && fault < MEM_COPYAREA_END) + { + current = get_current_tcb(); + tcb_t * partner = tid_to_tcb(current->partner); + ptr_t pdir_from = phys_to_virt(current->page_dir); + ptr_t pdir_to = phys_to_virt(partner->page_dir); + + dword_t *saved_stack; + + //printf("fault in copy area %x @ %x\n", current, fault); + + if (fault < MEM_COPYAREA2) + { + if (current->resources & TR_IPC_MEM1) + { + /* pagefault */ + //printf("tunneled pf ipc1\n"); + //enter_kdebug(); + + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area1 + (fault - MEM_COPYAREA1), + (dword_t)current); + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + /* xxx: should we: thread_enqueue_ready(partner); */ + dispatch_thread(partner); + //printf("tunneled pf done\n"); + partner->stack = saved_stack; + + /* we did an IPC here with a thread switch - the pagetable + * entries of the copy area are gone -> we would directly + * pagefault -> so run into the pagedir update... + */ + } + + pdir_from[MEM_COPYAREA1 >> PAGEDIR_BITS] = pdir_to[current->copy_area1 >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA1 >> PAGEDIR_BITS) + 1] = pdir_to[(current->copy_area1 >> PAGEDIR_BITS) + 1]; + current->resources |= TR_IPC_MEM1; + return; + } + else + { + //printf("fault in copy area %x @ %x\n", current, fault); + + if (current->resources & TR_IPC_MEM2) + { + /* pagefault */ + //printf("tunneled pf ipc2\n"); + //enter_kdebug(); + + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area2 + (fault - MEM_COPYAREA2), + (dword_t)current); + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + /* xxx: should we: thread_enqueue_ready(partner); */ + dispatch_thread(partner); + //printf("tunneled pf2 done\n"); + partner->stack = saved_stack; + } + + /* see comment above */ + pdir_from[MEM_COPYAREA2 >> PAGEDIR_BITS] = pdir_to[current->copy_area2 >> PAGEDIR_BITS]; + pdir_from[(MEM_COPYAREA2 >> PAGEDIR_BITS) + 1] = pdir_to[(current->copy_area2 >> PAGEDIR_BITS) + 1]; + current->resources |= TR_IPC_MEM2; + return; + } + } +#endif + panic("kernel pagefault"); + } + printf("%x", fault); + spin(79); +} + + + + + + diff --git a/kernel/src/mips/misc.c b/kernel/src/mips/misc.c new file mode 100644 index 0000000..8a6bdd5 --- /dev/null +++ b/kernel/src/mips/misc.c @@ -0,0 +1,89 @@ +/* $Id: misc.c,v 1.1 2000/02/07 18:03:43 uhlig Exp $ + * + * misc.c: Miscellaneous ARCS PROM routines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include +#include +#include +#if 0 +#include +#include +#include + +#include +#include +#include +#include +#endif + +extern unsigned long mips_cputype; +extern void *sgiwd93_host; +extern void reset_wd33c93(void *instance); + +void prom_halt(void) +{ + bcops->bc_disable(); + disable_interrupts(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + romvec->halt(); +} + +void prom_powerdown(void) +{ + bcops->bc_disable(); + disable_interrupts(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + romvec->pdown(); +} + +/* XXX is this a soft reset basically? XXX */ +void prom_restart(void) +{ + bcops->bc_disable(); + disable_interrupts(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + romvec->restart(); +} + +void prom_reboot(void) +{ + bcops->bc_disable(); + disable_interrupts(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + romvec->reboot(); +} + +void prom_imode(void) +{ + bcops->bc_disable(); + disable_interrupts(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + romvec->imode(); +} + +long prom_cfgsave(void) +{ + return romvec->cfg_save(); +} + +struct linux_sysid *prom_getsysid(void) +{ + return romvec->get_sysid(); +} + +void prom_cacheflush(void) +{ + romvec->cache_flush(); +} diff --git a/kernel/src/mips/pr31700/.cvsignore b/kernel/src/mips/pr31700/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/mips/pr31700/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/mips/pr31700/Makefile b/kernel/src/mips/pr31700/Makefile new file mode 100644 index 0000000..de921a6 --- /dev/null +++ b/kernel/src/mips/pr31700/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: mips/pr31700/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.2 2001/11/22 13:27:54 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = exception.S init.c + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/mips/pr31700/exception.S b/kernel/src/mips/pr31700/exception.S new file mode 100755 index 0000000..03f6ed8 --- /dev/null +++ b/kernel/src/mips/pr31700/exception.S @@ -0,0 +1,260 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/pr31700/exception.S + * Description: Exception handling for the MIPS PR31700. + * + * @LICENSE@ + * + * $Id: exception.S,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + + .set noat + +#define ENTRY(name) \ + .globl name ; \ + .align 2 ; \ + .type name, @function ; \ + .ent name, 0 ; \ +name: + +#define END(name) \ + .globl name##__end ; \ + .end name ; \ + .size name,.-name ; \ +name##__end: + + +.MACRO open_frame + mfc0 k1, CP0_STATUS + andi k0, k1, ST0_KUP + beq k0, zero, 9f // If we came from kernel + la k0, current_stack + lw k0, 0(k0) + + addiu k0, k0, -4 + sw sp, 0(k0) + move sp, k0 +9: + addiu sp, sp, -8 + mfc0 k0, CP0_EPC // Return address + sw k1, 4(sp) // push mode + sw k0, 0(sp) // Save return address +.ENDM + + +.MACRO close_frame + .set push + .set reorder + + lw k1, 4(sp) // Status + lw k0, 0(sp) // Return address + + mtc0 k1, CP0_STATUS + + andi k1, k1, ST0_KUP + bne k1, zero, 9f // If we did not come from kernel + addiu sp, sp, 8 + rfe + jr k0 +9: + + lw sp, 8(sp) // User stack pointer + rfe // Restore from exception + jr k0 // Return to user + nop + .set pop +.ENDM + + +ENTRY(tlb_refill) + .set noreorder + .set noat + + la k0, current_page_table + lw k0, 0(k0) + + /* get pagedir entry */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, PAGEDIR_BITS + sll k1, k1, 2 + add k0, k0, k1 + + lw k0, 0(k0) /* k0 is pdir-entry */ + beq k0, zero, refill_fault + + /* now the pagetable */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, (PAGE_BITS - 2) + andi k1, k1, ((~PAGE_MASK) << 2) + add k1, k1, k0 + lw k0, 0(k1) /* ptab entry */ + beq k0, zero, refill_fault + srl k1, k1, 3 + sll k1, k1, 3 +#if 0 + move a0, k0 + move a1, k1 + j 9f +#endif + +#if 1 + lw k0, 0(k1) + lw k1, 4(k1) + srl k0, k0, 2 + srl k1, k1, 2 + + mtc0 k0, CP0_ENTRYLO0 + mtc0 k1, CP0_ENTRYLO1 + b 1f + tlbwr # write random tlb entry +1: + nop + rfe # return from trap +#else + lw a0, 0(k1) + lw a1, 4(k1) + move a2, k1 +9: + la k0, tlb_refill__FUiUi + jr k0 + nop +#endif + + +refill_fault: + la k0, handle_pagefault + jr k0 + nop +END(tlb_refill) + +ENTRY(handle_pagefault) + .set reorder + open_frame + + addiu sp, sp, -15*4 + + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + + sw t0, 12(sp) + sw t1, 16(sp) + sw t2, 20(sp) + sw t3, 24(sp) + sw t4, 28(sp) + sw t5, 32(sp) + sw t6, 36(sp) + sw t7, 40(sp) + sw v1, 44(sp) + sw ra, 48(sp) + sw v0, 52(sp) + sw gp, 56(sp) + + mfc0 a0, CP0_BADVADDR + mfc0 a1, CP0_CAUSE + mfc0 a2, CP0_EPC + mfc0 a3, CP0_STATUS + + jal pagefault__FUiUiUi + + + lw a0, 0(sp) + lw a1, 4(sp) + lw a2, 8(sp) + + lw t0, 12(sp) + lw t1, 16(sp) + lw t2, 20(sp) + lw t3, 24(sp) + lw t4, 28(sp) + lw t5, 32(sp) + lw t6, 36(sp) + lw t7, 40(sp) + lw v1, 44(sp) + lw ra, 48(sp) + lw v0, 52(sp) + lw gp, 56(sp) + + addiu sp, sp, 15*4 + + close_frame +END(handle_pagefault) + +ENTRY(exception_handler) + mfc0 k0, CP0_CAUSE + and k1, k0, 0x3c + la k0, except_table + add k1, k0, k1 + lw k1, 0(k1) + beqz k1, 1f + jr k1 // Jump + +1: + la k0, general_exception + jr k0 + nop +END(exception_handler) + +ENTRY(exception_cache_error) + la k0, mips_cache_error__Fv + jr k0 +1: + j 1b +END(exception_cache_error) + +ENTRY(switch_to_sigma0__Fv) + addiu sp, 4 + /* fall through */ +END(switch_to_sigma0__Fv) + +// this is the general entry point for all user functions +.globl switch_to_roottask__Fv +.type switch_to_roottask__Fv, @function + +.globl abort_ipc__Fv +.type abort_ipc__Fv, @function + +switch_to_roottask__Fv: +abort_ipc__Fv: +ENTRY(switch_to_user__Fv) + lw k0, 0(sp) // uip + lw k1, 4(sp) // status + mtc0 k1, CP0_STATUS + lw sp, 8(sp) // usp + rfe + jr k0 + +END(switch_to_user__Fv) + +general_exception: + mfc0 a1, CP0_EPC + mfc0 a2, CP0_STATUS + la k0, exception__FUiUiUi + jalr k0 + nop + rfe + + +except_table: + .word general_exception + .word 0 + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word general_exception + .word general_exception + .word general_exception + .word general_exception + + + + + + diff --git a/kernel/src/mips/pr31700/init.c b/kernel/src/mips/pr31700/init.c new file mode 100644 index 0000000..9e07f4b --- /dev/null +++ b/kernel/src/mips/pr31700/init.c @@ -0,0 +1,24 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/pr31700/init.c + * Description: MIPS PR31700 initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include "mips/pr31700/platform.h" + +void init_platform() +{ + int start = 0x80000000; + while(1) { + siu_out(SIU_VIDEO_CTRL_3, start); + start+=0x20; + //putc('a'); + }; +} diff --git a/kernel/src/mips/pr31700/startup.S b/kernel/src/mips/pr31700/startup.S new file mode 100644 index 0000000..fccf6f9 --- /dev/null +++ b/kernel/src/mips/pr31700/startup.S @@ -0,0 +1,34 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/pr31700/startup.S + * Description: Startup code for the MIPS PR31700. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include + +.section .init +.globl _start + + .type _start, @function +_start: + //j _start + la sp, _mini_stack + jal init_platform__Fv + + jal init__Fv + nop + /* we should not return!!! */ +1: + j 1b + nop + +.section .init + .space 1024 +_mini_stack: + diff --git a/kernel/src/mips/r4000/.cvsignore b/kernel/src/mips/r4000/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/mips/r4000/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/mips/r4000/Makefile b/kernel/src/mips/r4000/Makefile new file mode 100644 index 0000000..62d8915 --- /dev/null +++ b/kernel/src/mips/r4000/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: mips/r4000/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.6 2001/11/22 13:27:54 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = init.c exception.S + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/mips/r4000/exception.S b/kernel/src/mips/r4000/exception.S new file mode 100755 index 0000000..de9c68b --- /dev/null +++ b/kernel/src/mips/r4000/exception.S @@ -0,0 +1,252 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/r4000/exception.S + * Description: Exception handling for the MIPS R4000. + * + * @LICENSE@ + * + * $Id: exception.S,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + + .set noat + +#define ENTRY(name) \ + .globl name ; \ + .align 2 ; \ + .type name, @function ; \ + .ent name, 0 ; \ +name: + +#define END(name) \ + .globl name##__end ; \ + .end name ; \ + .size name,.-name ; \ +name##__end: + + +.MACRO open_frame + mfc0 k1, CP0_STATUS + andi k0, k1, ST0_KUP + beq k0, zero, 9f // If we came from kernel + la k0, current_stack + lw k0, 0(k0) + + addiu k0, k0, -4 + sw sp, 0(k0) + move sp, k0 +9: + addiu sp, sp, -8 + mfc0 k0, CP0_EPC // Return address + sw k1, 4(sp) // push mode + sw k0, 0(sp) // Save return address +.ENDM + + +.MACRO close_frame + .set push + .set reorder + + lw k1, 4(sp) // Status + lw k0, 0(sp) // Return address + + mtc0 k1, CP0_STATUS + + andi k1, k1, ST0_KUP + bne k1, zero, 9f // If we did not come from kernel + addiu sp, sp, 8 + eret + jr k0 +9: + + lw sp, 8(sp) // User stack pointer + eret // Restore from exception + jr k0 // Return to user + nop + .set pop +.ENDM + + +ENTRY(tlb_refill) + .set noreorder + .set noat + + la k0, current_page_table + lw k0, 0(k0) + + /* get pagedir entry */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, PAGEDIR_BITS + sll k1, k1, 2 + add k0, k0, k1 + + lw k0, 0(k0) /* k0 is pdir-entry */ + beq k0, zero, refill_fault + + /* now the pagetable */ + mfc0 k1, CP0_BADVADDR + srl k1, k1, (PAGE_BITS - 2) + andi k1, k1, ((~PAGE_MASK) << 2) + add k1, k1, k0 + lw k0, 0(k1) /* ptab entry */ + beq k0, zero, refill_fault + srl k1, k1, 3 + sll k1, k1, 3 +#if 0 + move a0, k0 + move a1, k1 + j 9f +#endif + +#if 1 + lw k0, 0(k1) + lw k1, 4(k1) + srl k0, k0, 2 + srl k1, k1, 2 + + mtc0 k0, CP0_ENTRYLO0 + mtc0 k1, CP0_ENTRYLO1 + b 1f + tlbwr # write random tlb entry +1: + nop + eret # return from trap +#else + lw a0, 0(k1) + lw a1, 4(k1) + move a2, k1 +9: + la k0, tlb_refill__FUiUi + jr k0 + nop +#endif + + +refill_fault: + la k0, handle_pagefault + jr k0 + nop +END(tlb_refill) + +ENTRY(handle_pagefault) + .set reorder + open_frame + + addiu sp, sp, -15*4 + + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + + sw t0, 12(sp) + sw t1, 16(sp) + sw t2, 20(sp) + sw t3, 24(sp) + sw t4, 28(sp) + sw t5, 32(sp) + sw t6, 36(sp) + sw t7, 40(sp) + sw v1, 44(sp) + sw ra, 48(sp) + sw v0, 52(sp) + sw gp, 56(sp) + + mfc0 a0, CP0_BADVADDR + mfc0 a1, CP0_CAUSE + mfc0 a2, CP0_EPC + mfc0 a3, CP0_STATUS + + jal pagefault__FUiUiUi + + + lw a0, 0(sp) + lw a1, 4(sp) + lw a2, 8(sp) + + lw t0, 12(sp) + lw t1, 16(sp) + lw t2, 20(sp) + lw t3, 24(sp) + lw t4, 28(sp) + lw t5, 32(sp) + lw t6, 36(sp) + lw t7, 40(sp) + lw v1, 44(sp) + lw ra, 48(sp) + lw v0, 52(sp) + lw gp, 56(sp) + + addiu sp, sp, 15*4 + + close_frame +END(handle_pagefault) + +ENTRY(exception_handler) + mfc0 k0, CP0_CAUSE + and k1, k0, 0x3c + la k0, except_table + add k1, k0, k1 + lw k1, 0(k1) + beqz k1, 1f + jr k1 // Jump + +1: + la k0, general_exception + jr k0 + nop +END(exception_handler) + +ENTRY(exception_cache_error) + la k0, mips_cache_error__Fv + jr k0 +1: + j 1b +END(exception_cache_error) + +ENTRY(switch_to_sigma0__Fv) + addiu sp, 4 + /* fall through */ +END(switch_to_sigma0__Fv) + +// this is the general entry point for all user functions +ENTRY(switch_to_user__Fv) + lw k0, 0(sp) // uip + lw k1, 4(sp) // status + mtc0 k1, CP0_STATUS + lw sp, 8(sp) // usp + eret + jr k0 + +END(switch_to_user__Fv) + +general_exception: + mfc0 a1, CP0_EPC + mfc0 a2, CP0_STATUS + la k0, exception__FUiUiUi + jalr k0 + nop + eret + + +except_table: + .word general_exception + .word 0 + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word tlb_refill + .word general_exception + .word general_exception + .word general_exception + .word general_exception + + + + + + diff --git a/kernel/src/mips/r4000/init.c b/kernel/src/mips/r4000/init.c new file mode 100644 index 0000000..5daa61e --- /dev/null +++ b/kernel/src/mips/r4000/init.c @@ -0,0 +1,28 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/r4000/init.c + * Description: MIPS R4000 initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include + +void init_platform() +{ + struct linux_promblock *pb; + + romvec = ROMVECTOR; + pb = sgi_pblock = PROMBLOCK; + + if(pb->magic != 0x53435241) { + panic("bad prom vector magic"); + } + + prom_vers = pb->ver; + prom_rev = pb->rev; +} diff --git a/kernel/src/mips/r4000/startup.S b/kernel/src/mips/r4000/startup.S new file mode 100644 index 0000000..25f9398 --- /dev/null +++ b/kernel/src/mips/r4000/startup.S @@ -0,0 +1,33 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: mips/r4000/startup.S + * Description: MIPS R4000 startup code. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.2 2001/11/22 13:27:54 skoglund Exp $ + * + ********************************************************************/ +#include + +.section .init +.globl _start + + .type _start, @function +_start: + la sp, _mini_stack + jal mips_init__Fv + + jal init__Fv + nop + /* we should not return!!! */ +1: + j 1b + nop + +.section .init + .space 1024 +_mini_stack: + diff --git a/kernel/src/schedule.c b/kernel/src/schedule.c new file mode 100644 index 0000000..8a2a2b8 --- /dev/null +++ b/kernel/src/schedule.c @@ -0,0 +1,323 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: schedule.c + * Description: Code dealing with scheduling and thread switching. + * + * @LICENSE@ + * + * $Id: schedule.c,v 1.64 2002/05/13 13:04:30 stoess Exp $ + * + ********************************************************************/ +#include +#include +#include +#include INC_ARCH(syscalls.h) + +int current_max_prio L4_SECT_CPULOCAL; +tcb_t *prio_queue[MAX_PRIO + 1] L4_SECT_CPULOCAL; + + +void dispatch_thread(tcb_t * tcb) +{ + tcb_t * current = get_current_tcb(); + + if (tcb == current) + return; + + if (tcb == get_idle_tcb()) { + printf("dispatch: switch to idle, current=%x, state=%x\n", + current, current->thread_state); + enter_kdebug("dispatch: switch to idle"); + switch_to_idle(current); + return; + } + + //printf("dispatch: %p -> %p\n", current, tcb); + /* Do not insert TCBS not in the ready queue into the prio_queue */ + if (tcb->queue_state & TS_QUEUE_READY) + prio_queue[tcb->priority] = tcb; + + //printf("switch_to %x->%x (%x)\n", current, tcb, tcb->thread_state); + switch_to_thread(tcb, current); +} + + +/* the scheduler code */ +tcb_t * find_next_thread() +{ + + for (int i = current_max_prio; i >= 0; i--) + { + tcb_t *tcb = prio_queue[i]; + while (tcb) { + //printf("find_next1 (%d) %x (%x, %x)\n", i, tcb, tcb->ready_next, tcb->thread_state); +#if defined(CONFIG_DEBUG_SANITY) + ASSERT(tcb->queue_state & TS_QUEUE_READY); + ASSERT(tcb->ready_next != NULL); +#endif + tcb = tcb->ready_next; + //printf("find_next2 %x (%x, %x)\n", tcb, tcb->ready_next, tcb->thread_state); + + if ( IS_RUNNING(tcb) && (tcb->timeslice > 0) ) + { + prio_queue[i] = tcb; + current_max_prio = i; + //printf("find_next: returns %p\n", tcb); + return tcb; + } + else { + //printf("dequeueing %p state=%x, snd_queue=%p\n", tcb, tcb->thread_state, tcb->send_queue); + //enter_kdebug(); + thread_dequeue_ready(tcb); + tcb = prio_queue[i]; + } + } + } + /* if we can't find a schedulable thread - switch to idle */ + //printf("find_next: returns idle\n"); + current_max_prio = -1; + return get_idle_tcb(); +} + + +tcb_t * parse_wakeup_queue(dword_t current_prio, qword_t current_time) +{ + tcb_t * highest_wakeup = NULL; + tcb_t * tcb = get_idle_tcb()->wakeup_next; + + while(tcb != get_idle_tcb()) + { + if (tcb->absolute_timeout <= current_time) + { + /* we have to wakeup the guy */ + if (tcb->priority > current_prio) + { + current_prio = tcb->priority; + highest_wakeup = tcb; + } + tcb_t * tmp = tcb->wakeup_next; + thread_dequeue_wakeup(tcb); + + /* set it running and enqueue into ready-queue */ + tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(tcb); + + tcb = tmp; + } + else + tcb = tcb->wakeup_next; + } + return highest_wakeup; +} + + +/* this function is called from the hardware dependend + * interrupt service routine for a timer tick + */ +void handle_timer_interrupt() +{ +#if (defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB)) && defined(CONFIG_DEBUG_BREAKIN) + kdebug_check_breakin(); +#endif + + TRACEPOINT(HANDLE_TIMER_INTERRUPT, + printf("timer interrupt (curr=%p)\n", get_current_tcb())); + +#if defined(CONFIG_SMP) + /* only cpu 0 maintains the clock */ + if (get_cpu_id() == 0) +#endif + kernel_info_page.clock += TIME_QUANTUM; + + + tcb_t * current = get_current_tcb(); + tcb_t * wakeup = parse_wakeup_queue(current->priority, kernel_info_page.clock); + + current->current_timeslice -= TIME_QUANTUM; + + /* make sure runable threads are in the run queue */ + if (current != get_idle_tcb()) + thread_enqueue_ready(current); + + if (wakeup) + { + dispatch_thread(wakeup); + return; + } + + if (current->current_timeslice <= 0) + { + spin1(78); + current->current_timeslice = current->timeslice; + dispatch_thread(find_next_thread()); + } +} + + + +/* this is the initial startup function of the idle + * thread. The idle thread initializes the main task (sigma0) + * and does all the stuff where a valid tcb is necessary. + */ +void final_init() +{ +#if defined(CONFIG_SMP) + printf("starting idler - cpu %d\n", get_apic_cpu_id()); + if (!is_boot_cpu()) { + /* tell the boot CPU we're there */ + set_cpu_online(get_apic_cpu_id()); + return; + } +#endif + + /* we initialize SMP processors here + and have to do that BEFORE we create all the other tasks + otherwise we don't have cpu-local kernel pagetables */ + init_arch_3(); + + /* do initialization */ + create_nil_tcb(); + create_sigma0(); + create_root_task(); +} + + +notify_procedure(initialize_idle_thread) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("idler started\n"); +#endif + + /* prio queues are processor local - clear here */ + for(int i = 0; i < MAX_PRIO; i++) + prio_queue[i] = (tcb_t *)NULL; + current_max_prio = -1; + + /* do the final init. now we have a valid tcb and a virtual stack */ + final_init(); + + /* and now simply schedule */ + while(1) + { + spin1(79); +#if defined(CONFIG_DEBUG_SANITY) + if (get_idle_tcb()->queue_state & (TS_QUEUE_READY | TS_QUEUE_SEND)) + enter_kdebug("idler has broken queue state"); +#endif + + //enable_interrupts(); + tcb_t * next = find_next_thread(); + if (next != get_idle_tcb()) + dispatch_thread(next); + else + system_sleep(); + } +} + + +void sys_thread_switch(l4_threadid_t tid) +{ + TRACEPOINT_1PAR(SYS_THREAD_SWITCH, tid.raw); + +#if defined (CONFIG_DEBUG_TRACE_SYSCALLS) + if (tid == L4_NIL_ID) + spin1(75); + else + printf("sys_thread_switch(tid: %x)\n", tid); +#endif + + /* Make sure we are in the ready queue to + * find at least ourself and ensure that the thread + * is rescheduled */ + thread_enqueue_ready(get_current_tcb()); + + tcb_t * tcb = tid_to_tcb(tid); + if (!(!l4_is_nil_id(tid) && (tcb->myself == tid ) && (IS_RUNNING(tcb)))) + tcb = find_next_thread(); + + /* do dispatch only if necessary */ + if (tcb != get_current_tcb()) + dispatch_thread(tcb); + + return_thread_switch(); +} + + +void sys_schedule(schedule_param_t param, l4_threadid_t tid) +{ +#if defined (CONFIG_DEBUG_TRACE_SYSCALLS) + printf("sys_schedule (%p) tid: %x, param: %x - ip:%x\n", + get_current_tcb(), tid.raw, param.raw, get_user_ip(get_current_tcb())); +#endif + TRACEPOINT(SYS_SCHEDULE, + printf("sys_schedule (param: %p, tid: %p) - tcb/ip: %p/%x\n", + param.raw, tid.raw, get_current_tcb(), + get_user_ip(get_current_tcb()))); + + + tcb_t * tcb = tid_to_tcb(tid); + schedule_param_t oldparam; + + if (tcb->myself != tid) + return_thread_schedule(INVALID_SCHED_PARAM); + + /* save current values for return */ + oldparam.param.prio = tcb->priority; +#if defined(CONFIG_ENABLE_SMALL_AS) + oldparam.param.small_as = tcb->space->smallid ().value (); +#elif defined(CONFIG_SMP) + oldparam.param.small_as = tcb->cpu; +#endif + if (param.raw == ~0U) + { + /* only read out */ + } + else + { + if (param.param.prio != tcb->priority) + { + TRACEPOINT(SET_PRIO, + printf("%s: setting prio of %x %d -> %d\n", + __FUNCTION__, tid.raw, tcb->priority, + param.param.prio)); + if (tcb->queue_state & TS_QUEUE_READY) + { + thread_dequeue_ready(tcb); + tcb->priority = (param.param.prio); + thread_enqueue_ready(tcb); + } + else + tcb->priority = (param.param.prio); + } + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( (param.param.small_as != 0) && + (param.param.small_as != SMALL_SPACE_INVALID) && + (tcb->space != NULL) ) + { + smallid_t small = tcb->space->smallid (); + + TRACEPOINT(SET_SMALL_SPACE, + printf("%s: setting small_as of %p %2x -> %2x\n", + __FUNCTION__, tid.raw, small, + param.param.small_as)); + + if (param.param.small_as != small.value ()) + make_small_space (tcb->space, param.param.small_as); + } +#endif + +#if defined(CONFIG_SMP) + if (dword_t cpu = param.param.cpu) + { + if (tcb != get_current_tcb() && ((cpu - 1) < CONFIG_SMP_MAX_CPU)) + smp_move_thread(tcb, cpu - 1); + }; +#endif + } + + /* return the old values to the user */ + return_thread_schedule(oldparam); +} diff --git a/kernel/src/schedule.o b/kernel/src/schedule.o new file mode 100644 index 0000000..3564938 Binary files /dev/null and b/kernel/src/schedule.o differ diff --git a/kernel/src/thread.c b/kernel/src/thread.c new file mode 100644 index 0000000..3ff5fd1 --- /dev/null +++ b/kernel/src/thread.c @@ -0,0 +1,581 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, 2004, Karlsruhe University + * + * File path: thread.c + * Description: Thread creating and deletion. + * + * @LICENSE@ + * + * $Id: thread.c,v 1.90 2004/01/22 13:52:22 ud3 Exp $ + * + ********************************************************************/ +#include +#include +#include +#include INC_ARCH(syscalls.h) + +#if defined(CONFIG_IO_FLEXPAGES) +#include INC_ARCH(io_mapping.h) +#endif + + +/* the idle thread has a dedicated tcb which is not in the paged area */ +whole_tcb_t __idle_tcb L4_SECT_CPULOCAL; + +/* tcb pointer to sigma0 */ +tcb_t * sigma0; + + +static tcb_t * create_tcb(l4_threadid_t tid, space_t *space); + +extern void switch_to_sigma0(); +extern void switch_to_roottask(); +extern ptr_t kernel_arg; + +void create_nil_tcb(void) +{ + /* Make sure the NIL_ID thread contains an invalid thread id. */ + create_tcb(L4_NIL_ID, (space_t *) get_kernel_pagetable())->myself = + L4_INVALID_ID; +} + +void create_sigma0() +{ + if (kernel_info_page.sigma0_ip != 0xFFFFFFFF) + { + sigma0 = create_tcb(L4_SIGMA0_ID, NULL); + if (!sigma0) + panic("create_sigma0: create_tcb() failed"); +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("sigma0: %p, %x\n", sigma0, sigma0->myself.raw); +#endif + + create_user_stack_frame(sigma0, + kernel_info_page.sigma0_sp, kernel_info_page.sigma0_ip, + switch_to_sigma0, &kernel_info_page); + +#if defined(CONFIG_IO_FLEXPAGES) + io_mdb_init_sigma0(); +#endif + sigma0->priority = 50; + sigma0->thread_state = TS_RUNNING; + + + thread_enqueue_ready(sigma0); + } + else + panic("No sigma0 configured"); +} + +void create_root_task() +{ + if (kernel_info_page.root_ip != 0xFFFFFFFF) + { + tcb_t* tcb = create_tcb(L4_ROOT_TASK_ID, NULL); + if (!tcb) + panic("create_roottask: create_tcb() failed"); +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("root_task: %p, %x\n", tcb, tcb->myself.raw); +#endif + + create_user_stack_frame(tcb, + kernel_info_page.root_sp, kernel_info_page.root_ip, + switch_to_roottask, kernel_arg); + +#if defined(CONFIG_IO_FLEXPAGES) + io_mdb_task_new(sigma0, tcb); +#endif + tcb->priority = 50; + tcb->pager = L4_SIGMA0_ID; + tcb->thread_state = TS_RUNNING; + + thread_enqueue_ready(tcb); + } +} + + +void unwind_ipc(tcb_t *tcb); + +/* mark a tcb as free */ +static void free_tcb(tcb_t* tcb); +/* remove a tcb from all queues */ +static void free_thread(tcb_t* tcb); + +#if defined(CONFIG_SMP) +int smp_delete_all_threads(space_t *); +#endif +void delete_all_threads(space_t *space) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("%s(%p)\n", __FUNCTION__, space); +#endif + tcb_t *tcb, *next; + //enter_kdebug("task delete"); +#warning task_delete does not work over cpu boundaries + /* walk along the present queue */ + for (tcb = get_idle_tcb()->present_next; + tcb != get_idle_tcb(); + tcb = next) + { + next = tcb->present_next; + if (tcb->space == space) + { + /* remove the tcb from all queues */ + free_thread(tcb); + + /* free the tcb */ + free_tcb(tcb); + } + } +} + + + +/* mark a tcb as free */ +static void free_tcb(tcb_t* tcb) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf(" %s(%p)\n", __FUNCTION__, tcb); +#endif + thread_dequeue_present(tcb); + // this ensures that nobody can perform operations on that thread + tcb->myself = L4_NIL_ID; + tcb->thread_state = TS_ABORTED; + + free_resources(tcb); +} + + +/* remove a tcb from all queues */ +static void free_thread(tcb_t* tcb) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf(" %s(%p)\n", __FUNCTION__, tcb); +#endif + unwind_ipc(tcb); /* dequeues from wakeup */ + while (tcb->send_queue) + unwind_ipc(tcb->send_queue); + thread_dequeue_ready(tcb); + purge_resources(tcb); +} + +/* on smp systems we hold the spinlock on tcb */ +void unwind_ipc(tcb_t *tcb) +{ + dword_t ipc_error = 0; + tcb_t* partner; + + TRACEPOINT(UNWIND_IPC, + printf("unwind_ipc - thread: %p, state: %x\n", + tcb, tcb->thread_state)); + +#if defined(CONFIG_SMP) + /* xcpu unwinds are always done there */ + extern int smp_unwind_ipc(tcb_t *); + retry_smp_unwind_ipc: + if (tcb->cpu != get_cpu_id()) + { + if (!smp_unwind_ipc(tcb)) + goto retry_smp_unwind_ipc; + return; + } +#endif + + thread_dequeue_wakeup(tcb); + + switch(tcb->thread_state) + { + case TS_RUNNING: + case TS_ABORTED: + return; + break; + case TS_WAITING: + ipc_error = IPC_ERR_CANCELED | IPC_ERR_RECV; + break; + case TS_POLLING: +#if CONFIG_DEBUG_SANITY + if (l4_is_nil_id(tcb->partner)) + enter_kdebug("unwind_ipc: partner = 0!!!"); +#endif + partner = tid_to_tcb(tcb->partner); + ipc_error = IPC_ERR_CANCELED | IPC_ERR_SEND; + /* we spinlock in ex_regs!!! */ + thread_dequeue_send(partner, tcb); + break; + case TS_LOCKED_WAITING: + tcb->thread_state = TS_ABORTED; /* avoid recursion */ +#ifdef CONFIG_DEBUG_SANITY + if (l4_is_nil_id(tcb->partner)) + enter_kdebug("unwind_ipc: partner = 0!!!"); +#endif + if (!IS_KERNEL_ID(tcb->partner)) + { + partner = tid_to_tcb(tcb->partner); + unwind_ipc(partner); + partner->thread_state = TS_RUNNING; + thread_enqueue_ready(partner); + } + ipc_error = IPC_ERR_ABORTED | IPC_ERR_RECV; + break; + +#if defined(CONFIG_SMP) + case TS_XCPU_LOCKED_WAITING: + /* this is _really_ nasty: + * we have to deal with sillions of races and conditions + * like concurrent ex-regs on multiple cpu's + * and loop-unwinding (cpu0:ex_regs(cpu1:ipc(cpu0))) + */ + printf("unwind ipc of xcpu-ipc (%p)\n", tcb); + enter_kdebug("unwind_ipc xcpu"); + break; + + case TS_XCPU_LOCKED_RUNNING: + printf("unwind TS_XCPU_LOCKED_RUNNING %x\n", tcb); + printf("partner = %x on cpu %d\n", tcb->partner, tcb->cpu); + /* fall through */ +#endif /* CONFIG_SMP */ + + case TS_LOCKED_RUNNING: + tcb->thread_state = TS_ABORTED; /* avoid recursion */ +#ifdef CONFIG_DEBUG_SANITY + if (l4_is_nil_id(tcb->partner)) + enter_kdebug("unwind_ipc: partner = 0!!!"); +#endif + if (!IS_KERNEL_ID(tcb->partner)) + { + partner = tid_to_tcb(tcb->partner); + unwind_ipc(partner); +#if defined(CONFIG_SMP) + /* only enqueue if we are on the same cpu! */ + if (partner->cpu == get_cpu_id()) +#endif + { + partner->thread_state = TS_RUNNING; + thread_enqueue_ready(partner); + } + } + ipc_error = IPC_ERR_ABORTED | IPC_ERR_SEND; + break; + default: + ipc_error = 0; + panic("unwind_ipc: unknown thread_state"); + } + + if (!tcb->unwind_ipc_sp) + { + create_user_stack_frame (tcb, get_user_sp (tcb), get_user_ip (tcb), + abort_ipc, (void *) ipc_error); +#if defined(CONFIG_IA32_FEATURE_SEP) + /* + * If doing sysnter we need to pop off the sysenter/sysexit + * specific stuff from the user stack. + */ + if (is_ipc_sysenter (tcb)) + set_user_sp (tcb, get_user_sp (tcb) + 16); +#endif + } + else + { + if ((*(dword_t*)tcb->unwind_ipc_sp) < 0xf0000000) + enter_kdebug("strange unwind ipc sp"); + tcb->stack = tcb->unwind_ipc_sp; + tcb->unwind_ipc_sp = 0; + } +} + + + +void sys_task_new(l4_threadid_t task, dword_t mcp, l4_threadid_t pager, dword_t uip, dword_t usp) +{ +#if defined(CONFIG_DEBUG_TRACE_SYSCALLS) + printf("sys_task_new(tid: %x, mcp: %x, pager: %x, uip: %x, usp: %x)\n", + task.raw, mcp, pager.raw, uip, usp); +#endif + TRACEPOINT_2PAR(SYS_TASK_NEW, task.raw, pager.raw, + printf("sys_task_new (task: %p, mcp: %p, pager: %p, " + "uip: %p, usp: %p) - tcb/ip: %p/%x\n", + task.raw, mcp, pager.raw, uip, usp, + get_current_tcb(), get_user_ip(get_current_tcb()))); + + tcb_t *current = get_current_tcb(); + + if (task.x0id.task == 0) + panic("sys_task_new: press b to retry :-)"); + + task.x0id.thread = 0; /* thread 0 of the task */ + tcb_t * tcb = tid_to_tcb(task); + + if (current->myself.x0id.task == task.x0id.task) + { + enter_kdebug("sys_task_new: delete_myself not allowed"); + return_task_new(0); + } + + /* if the task already exists - delete it first */ + if (tcb_exist(tcb)) + { + space_t * space = tcb->space; /* store space */ + +#if defined(CONFIG_IO_FLEXPAGES) + io_mdb_delete_iospace(tcb); /* remove the IO-Space */ +#endif + +#if defined(CONFIG_SMP) + /* invoke remote task delete until remote partner signals ok. */ + while (!smp_delete_all_threads(space)); +#endif + delete_all_threads(space); /* delete all threads */ + delete_space(space); /* and remove the space */ + } + + if (l4_is_nil_id(pager)) + return_task_new(task); /* hand-over ? */ + + /* create new task */ +#warning REVIEWME: avoid tcb_exist + allocate_tcb(tcb); + + tcb = create_tcb(task, NULL); + if (!tcb) + panic("sys_task_new: create_tcb() failed"); + + tcb->pager = pager; + create_user_stack_frame(tcb, usp, uip, switch_to_user, 0); + +#if defined(CONFIG_IO_FLEXPAGES) + io_mdb_task_new(tid_to_tcb(pager), tcb); +#endif + + tcb->priority = current->priority; + tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(tcb); + + return_task_new(tcb->myself); +} + +void sys_lthread_ex_regs(dword_t threadno, dword_t uip, dword_t usp, l4_threadid_t pager) +{ + tcb_t* current = get_current_tcb(); + l4_threadid_t tid = current->myself; + + tid.x0id.thread = threadno; + tcb_t* tcb = tid_to_tcb(tid); + +#if defined(CONFIG_DEBUG_TRACE_SYSCALLS) + printf("lthread_ex_regs (%x,%x,%x,%x) by %p to %x - ip: %x\n", + threadno, uip, usp, pager.raw, current, tid.raw, get_user_ip(current)); +#endif + TRACEPOINT(SYS_LTHREAD_EX_REGS, + printf("sys_lthread_ex_regs (threadno: %p, uip: %p, usp: %p, " + "pager: %p)", threadno, uip, usp, pager.raw, + current, tid.raw); + printf(" - tcb/ip: %p/%x\n", current, get_user_ip(current))); + + if (~(uip & usp) && (tid != current->myself)) + /* allocate tcb on demand */ + { +#warning REVIEWME: avoid tcb_exist + allocate_tcb(tcb); + if (!tcb_exist(tcb)) + { + tcb = create_tcb(tid, current->space); + if (!tcb) + panic("sys_lthread_ex_regs: create_tcb() failed"); + create_user_stack_frame(tcb, usp, uip, switch_to_user, 0); + tcb->pager = pager; + tcb->priority = current->priority; + tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(tcb); + return_lthread_ex_regs(~0, ~0, L4_INVALID_ID, tid, 0); + } + else { +#if !defined(CONFIG_SMP) + unwind_ipc(tcb); + tcb->thread_state = TS_RUNNING; +#else /* CONFIG_SMP */ + retry_ex_regs: + spin_lock(&tcb->tcb_spinlock); + if (tcb->cpu == get_cpu_id()) + { + unwind_ipc(tcb); + tcb->thread_state = TS_RUNNING; + /* free spinlock after setting thread state */ + spin_unlock(&tcb->tcb_spinlock); + } + else + { + spin_unlock(&tcb->tcb_spinlock); + dword_t flags; + printf("cpu %d: ex-regs on cpu %d (%x)\n", get_cpu_id(), tcb->cpu, tcb); + if (!smp_ex_regs(tcb, &uip, &usp, &pager, &flags)) + goto retry_ex_regs; + + /* if we have a remote ex_regs we are done here */ + return_lthread_ex_regs(uip, usp, pager, tid, flags); + } +#endif /* !CONFIG_SMP */ + } + } + +#if defined(CONFIG_IA32_FEATURE_SEP) + /* + * If thread is returning through ipc_sysenter (i.e., sysexit) it + * doesn't read the modified EIP from the kernel stack. We + * therefore redirect the thread through another exit stub. + */ + extern dword_t alternate_sys_ipc_return; + if (~(usp & uip) != 0 && is_ipc_sysenter (tcb)) + { + get_tcb_stack_top(tcb)[IPCSTK_RETADDR] = + (dword_t) &alternate_sys_ipc_return; + set_user_sp(tcb, get_user_sp(tcb) + 16); + } +#endif + + if (usp == ~0U) + usp = get_user_sp(tcb); + else + usp = set_user_sp(tcb, usp); + + if (uip == ~0U) + uip = get_user_ip(tcb); + else + uip = set_user_ip(tcb, uip); + + if (pager == L4_INVALID_ID) + pager = tcb->pager; + else + { + l4_threadid_t oldpager; + oldpager = tcb->pager; + tcb->pager = pager; + pager = oldpager; + } + + if (tcb->thread_state == TS_RUNNING) + thread_enqueue_ready(tcb); + + return_lthread_ex_regs(uip, usp, pager, tid, get_user_flags(tcb)); +} + + +static tcb_t * create_tcb(l4_threadid_t tid, space_t *space) +{ + /* xxx sanity */ + tcb_t * tcb = tid_to_tcb(tid); + +#if defined(CONFIG_DEBUG_TRACE_MISC) + printf("create_tcb: tcb: %p, tid: %x, space %p, pdir=%x\n", tcb, tid.raw, space, get_current_pagetable()); +#endif + allocate_tcb(tcb); + +#if defined(CONFIG_DEBUG_SANITY) +#warning REVIEW: clears tcb + extern void zero_memory(dword_t * address, int size); + zero_memory((dword_t*)tcb, L4_TOTAL_TCB_SIZE); +#endif + tcb->myself = tid; + tcb->magic = TCB_MAGIC; + + /* thread state *must* be aborted, otherwise IPC is possible + * ending in a disaster... */ + tcb->thread_state = TS_ABORTED; + tcb->queue_state = 0; + tcb->send_queue = NULL; + tcb->intr_pending = 0; + tcb->timeslice = DEFAULT_TIMESLICE; + tcb->current_timeslice = 0; + tcb->resources = 0; + tcb->copy_area1 = COPYAREA_INVALID; + tcb->copy_area2 = COPYAREA_INVALID; + tcb->unwind_ipc_sp = 0; + tcb->intr_pending = 0; + + /* initialize resources */ + init_resources(tcb); + + /* no exception handling by default */ + tcb->excpt = 0; + + if (space == NULL) + tcb->space = create_space (); + else + tcb->space = space; + +#if !defined(CONFIG_SMP) + tcb->pagedir_cache = tcb->space->pagedir_phys(); +#else + tcb->pagedir_cache = tcb->space->pagedir_phys(get_cpu_id()); + tcb->cpu = get_cpu_id(); + spin_lock_init(&tcb->tcb_spinlock); +#endif + + thread_enqueue_present(tcb); + return tcb; +} + + + + +/* the famous null call */ + +void sys_id_nearest(l4_threadid_t tid) +{ + TRACEPOINT_2PAR(SYS_ID_NEAREST, get_current_tcb()->myself.raw, get_user_ip(get_current_tcb())); + +#if defined(CONFIG_DEBUG_TRACE_SYSCALLS) + printf("id_nearest(%x) by %x at %p\n", tid.raw, + get_current_tcb()->myself.raw, get_user_ip(get_current_tcb())); +#endif + + if (l4_is_nil_id(tid)) + return_id_nearest(get_current_tcb()->myself, 0); + + /* VU: Hazelnut does not support clans and chiefs + * therefore we emulate the C&C behavior by returning + * the task-creator's thread id */ + l4_threadid_t chief = L4_NIL_ID; + chief.x0id.task = get_current_tcb()->myself.x0id.chief; + return_id_nearest(tid_to_tcb(chief)->myself, 4); +}; + + +#if defined(NEED_FARCALLS) +#include INC_ARCH(farcalls.h) +#endif + +tcb_t * create_idle_thread() +{ + tcb_t *idle = get_idle_tcb(); + if (idle) { + idle->magic = TCB_MAGIC; + idle->myself = (l4_threadid_t){ raw: 0x12345678 }; + idle->priority = 0; + + /* we use the idle tcb as start of the wakeup and present queue */ + idle->present_next = idle->present_prev = idle; + idle->wakeup_next = idle->wakeup_prev = idle; + idle->queue_state = TS_QUEUE_PRESENT | TS_QUEUE_WAKEUP; + + /* the idler never wakes up */ + idle->absolute_timeout = ~0; + + idle->stack = get_tcb_stack_top(idle); + + /* idler should have no timeslice at all */ + idle->timeslice = DEFAULT_TIMESLICE; + idle->current_timeslice = 0; + + /* sanity */ + idle->space = NULL; + + notify_thread(idle, initialize_idle_thread); + + return idle; + } + panic("can't create idle tcb"); + return NULL; +} + + diff --git a/kernel/src/thread.o b/kernel/src/thread.o new file mode 100644 index 0000000..18d7ff1 Binary files /dev/null and b/kernel/src/thread.o differ diff --git a/kernel/src/version.c b/kernel/src/version.c new file mode 100644 index 0000000..f8747aa --- /dev/null +++ b/kernel/src/version.c @@ -0,0 +1,14 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: version.c + * Description: Autogenerated kernel version string. + * + * @LICENSE@ + * + * $Id: version.c,v 1.5 2001/11/22 13:04:52 skoglund Exp $ + * + ********************************************************************/ +const char* kernel_version = "L4Ka/Hazelnut - built on " __DATE__ " " __TIME__ + " by " __USER__ " using " __GCCVERSION__ "\n"; diff --git a/kernel/src/version.o b/kernel/src/version.o new file mode 100644 index 0000000..afd2093 Binary files /dev/null and b/kernel/src/version.o differ diff --git a/kernel/src/x86/.#interrupt.c.1.64 b/kernel/src/x86/.#interrupt.c.1.64 new file mode 100644 index 0000000..415ce5c --- /dev/null +++ b/kernel/src/x86/.#interrupt.c.1.64 @@ -0,0 +1,1575 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001-2002, Karlsruhe University + * + * File path: x86/interrupt.c + * Description: Interrupt and exceptiond handling and initialization + * for the x86. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.64 2002/05/31 11:51:44 stoess Exp $ + * + ********************************************************************/ +#include +#include +#include +#include +#include + +#if defined(CONFIG_IO_FLEXPAGES) +#include +#include +#endif + +#if defined(CONFIG_ENABLE_PVI) +/* Virtual Interrupts Indicator*/ +dword_t pending_irq; +#define IRQ_IN_SERVICE (1<<31) + +#define MAX_PENDING_IRQS 16 +#define PENDING_IRQ_BIT(x) (1 << x) +#define PENDING_TIMER_IRQ (1 << 31) + +void handle_pending_irq(void); + +#endif /* CONFIG_ENABLE_PVI */ + + +#ifndef CONFIG_X86_APIC + +#ifdef CONFIG_MEASURE_INT_LATENCY +#include +#endif + +#ifdef CONFIG_X86_INKERNEL_PIC +static byte_t pic1_mask, pic2_mask; +#endif + + +/********************************************************************** + * + * 8259A - standard PIC + * + **********************************************************************/ + +static void disable_8259A_irq(unsigned int irq) +{ + if (irq & 8) PIC2_MASK(irq - 8); + else PIC1_MASK(irq); +} + +static void enable_8259A_irq(unsigned int irq) +{ + if (irq & 8) PIC2_UNMASK(irq - 8); + else PIC1_UNMASK(irq); +} + +static int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1<> 8)); +} + +/* + * Careful! The 8259A is a fragile beast, it pretty + * much _has_ to be done exactly like this (mask it + * first, _then_ send the EOI, and the order of EOI + * to the two 8259s is important! + */ +static void mask_and_ack_8259A(unsigned int irq) +{ + if (irq & 8) { + PIC2_MASK(irq - 8); + outb(X86_PIC2_CMD, 0x60 + (irq&7)); /* Specific EOI to slave */ + outb(X86_PIC1_CMD, 0x62); /* Specific EOI to cascade */ + } else { + PIC1_MASK(irq); + outb(X86_PIC1_CMD, 0x60 + (irq)); + } +} + +static void mask_8259A(unsigned int irq) +{ + if (irq & 8) { + PIC2_MASK(irq - 8); + outb(X86_PIC1_CMD, 0x62); /* Specific EOI to cascade */ + } else { + PIC1_MASK(irq); + } +} + +void init_irqs() +{ + printf("%s\n", __FUNCTION__); + + /* first mask all interrupts */ + PIC1_SET_MASK(0xff); + PIC2_SET_MASK(0xff); + + /* setup pic (directly copied from Jochen's init)*/ + outb(X86_PIC1_CMD, 0x11); + outb(X86_PIC1_DATA, 0x20); /* start at idt entry 0x20 */ + outb(X86_PIC1_DATA, 0x04); + outb(X86_PIC1_DATA, 0x01); /* mode - *NOT* fully nested */ + outb(X86_PIC1_CMD, 0xc1); /* prio 8..15, 3..7, 0, 1 */ + + outb(X86_PIC2_CMD, 0x11); + outb(X86_PIC2_DATA, 0x28); /* start at idt entry 0x28 */ + outb(X86_PIC2_DATA, 0x02); + outb(X86_PIC2_DATA, 0x01); /* not fully nested */ + outb(X86_PIC2_CMD, 0xc7); /* prios... */ + + outb(X86_PIC1_CMD, 0x0A); + outb(X86_PIC2_CMD, 0x0A); + + /* enable timer irq (int 8) and init PIC mask cache */ + PIC1_SET_MASK(0xfb); + PIC2_SET_MASK(0xfe); + + outb(X86_PIC1_CMD, 0x60); + + /* enable nmi */ + in_rtc(0); + outb(0x61, inb(0x61) & ~(0xC)); + +#if defined(CONFIG_ENABLE_PVI) + pending_irq = 0; +#endif +} + + +void mask_interrupt(unsigned int number) +{ + disable_8259A_irq(number); +} + +void unmask_interrupt(unsigned int number) +{ +#ifdef CONFIG_X86_INKERNEL_PIC + enable_8259A_irq(number); +#endif +} + + + +void irq_handler(exception_frame_t *frame) +{ + + /* We do not need special handling for the timer IRQ here, + because this is done by timer_irq_handler(). */ + + TRACEPOINT_1PAR(INTERRUPT, frame->fault_code, + printf("irq_handler: irq #%d\n", frame->fault_code)); + +#ifdef CONFIG_X86_INKERNEL_PIC + mask_and_ack_8259A(frame->fault_code); +#else + disable_8259A_irq(frame->fault_code); +#endif + +#if defined(CONFIG_ENABLE_PVI) + + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we tag the interrupt bit in + * the fiels to handle it later. + */ + if(((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0)){ + + frame->eflags |= X86_EFL_VIP; + + tcb_t *current = get_current_tcb(); + current->resources |= TR_PVI; + + /* Save pending interrupt */ + pending_irq |= (1<< (frame->fault_code)); + + // printf("IRQ Handler irq=%x, enq irq_pending %x\n", frame->fault_code, + // pending_irq); + + return; + } +#endif /* CONFIG_ENABLE_PVI */ + + // printf("%s - irq: %d, tcb=%p\n", __FUNCTION__, frame->fault_code, get_current_tcb()); + // printf("IRQ %d pending\n ", frame->fault_code); + + handle_interrupt(frame->fault_code); +} + + +#else /* CONFIG_X86_APIC */ + +/********************************************************************** + * + * APIC and IO-APIC + * + **********************************************************************/ + +#include + +#warning APIC experimental + +void apic_setup_timer(int tickrate) L4_SECT_INIT; +void setup_local_apic() L4_SECT_INIT; + + +/* + * Function for accessing PCI configuration space with type 1 accesses + */ +static byte_t pci_read_config_byte(byte_t bus, byte_t devfn, byte_t where) +{ + byte_t value; + outl(0xCF8, (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3))); + value = inb(0xCFC + (where&3)); + return value; +} + +/* store information about io-apic interrupts */ +static apic_redir_t io_apic_intr[MAX_IOAPIC_INTR]; +/* A table for getting the IO-APIC line for an IRQ number */ +static byte_t irq_to_ioapicline_map[16]; +static void setup_io_apic() L4_SECT_INIT; + +#include INC_ARCH(mps-14.h) + +#if defined(CONFIG_DEBUG_TRACE_INIT) +#define Dprintf(x...) printf(x) +#else +#define Dprintf(x...) +#endif + +void setup_io_apic() +{ + /* check for io apic */ + apic_version_t io_apic_version; + + io_apic_version.raw = get_io_apic(X86_IOAPIC_VERSION); + + if (io_apic_version.ver.version != 0x11) { + printf("Panic: no io APIC detected. syshalt."); + asm("hlt\n"); + } + + Dprintf("io-apic max lvt: %d\n", io_apic_version.ver.max_lvt); + + int num_irqs = io_apic_version.ver.max_lvt + 1; + + /* first mask all interrupts on the PIC */ + outb(X86_PIC1_DATA, 0xff); + outb(X86_PIC2_DATA, 0xff); + + /* set apic to symmetric mode */ + outb(0x22, 0x70); + outb(0x23, 0x01); + + + /* initialize the array */ + for (int i = 0; i < num_irqs; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + entry->vector = 0; + entry->delivery_mode = APIC_DEL_FIXED; + entry->dest_mode = APIC_DEST_PHYS; + entry->trigger_mode = 0; + entry->polarity = 0; + entry->mask = IOAPIC_IRQ_MASKED; + entry->dest.physical.physical_dest = 0; /* send everything to apic 0 */ + } + + + intel_mp_floating_t *f; + byte_t isabus_id = 0xFE; + byte_t ioapic_id = 0xFE; + for (f = (intel_mp_floating_t*) 0xF0000; + f < (intel_mp_floating_t*) 0x100000; + f = (intel_mp_floating_t*) (((dword_t) f) + 0x10)) + if (f->signature == MPS_MPF_SIGNATURE) + { +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("SMP: Found MPS signature at %x\n", f); + printf("SMP: Version 1.%c\n", '0' + f->specification); + if (f->feature[0] != 0) + { + printf("SMP: Default config requested. No idea how!\n"); + f = (intel_mp_floating_t*) 0x100000; + break; + }; +#endif + mp_config_table_t *t = (mp_config_table_t*) f->physptr; + + if (t->signature == MPS_MPC_SIGNATURE) + { + Dprintf("SMP: Found MPC table at %x\n", t); + Dprintf("SMP: Length: %x\n", t->length); + Dprintf("SMP: Enties: %d\n", t->entries); + Dprintf("SMP: Local APIC at %x\n", t->lapic); + + union e_t { + byte_t type; + mpc_config_processor_t cpu; + mpc_config_bus_t bus; + mpc_config_ioapic_t ioapic; + mpc_config_intsrc_t irq; + mpc_config_lintsrc lint; + } *e = (union e_t *) (t + 1); + + for (int inc=0, i = t->entries; + i--; + e = (union e_t *) ((dword_t) e + inc)) + switch (e->type) + { + case MP_PROCESSOR: + Dprintf("SMP: Cpu: %d %cP\n", + e->cpu.apicid, + (e->cpu.cpuflag & 2) ? 'B':'A'); + inc = sizeof(e->cpu); +#if defined(CONFIG_SMP) + extern dword_t processor_map; + processor_map |= (1 << e->cpu.apicid); +#endif + break; + case MP_BUS: + Dprintf("SMP: Bus: %d %c%c%c%c%c%c\n", + e->bus.busid, + e->bus.bustype[0], e->bus.bustype[1], + e->bus.bustype[2], e->bus.bustype[3], + e->bus.bustype[4], e->bus.bustype[5]); + if ((e->bus.bustype[0] == 'I') && + (e->bus.bustype[1] == 'S') && + (e->bus.bustype[2] == 'A')) + { + + isabus_id = e->bus.busid; + Dprintf("SMP: ISA Bus is %2x\n", isabus_id); + }; + inc = sizeof(e->bus); + break; + case MP_IOAPIC: + Dprintf("SMP: IOAPIC: id=%2x, flags=%02, ver=%2x @ %p\n", + e->ioapic.apicid, e->ioapic.flags, + e->ioapic.apicver, e->ioapic.apicaddr); + /* keep the IOAPICs id */ + if (e->ioapic.flags & 1) + ioapic_id = e->ioapic.apicid; + inc = sizeof(e->ioapic); + break; + case MP_INTSRC: + Dprintf("SMP: IRQ: %2x %4x %2x %2x %2x %2x\n", + e->irq.irqtype, e->irq.irqflag, + e->irq.srcbus, e->irq.srcbusirq, + e->irq.dstapic, e->irq.dstirq); + if (e->irq.irqtype == 0) + /* set up ISA irqs - if we know the ISA bus already */ + if (e->irq.dstapic == ioapic_id) + { + apic_redir_t *entry = &io_apic_intr[e->irq.dstirq]; + /* PCI defaults to level-triggered, active low */ + int dpo = 1, dtm = 1; + if (e->irq.srcbus == isabus_id) + { + Dprintf("SMP: ISA irq 0x%2x is on APIC pin 0x%2x\n", + e->irq.srcbusirq, e->irq.dstirq); + entry->vector = e->irq.srcbusirq + 0x20; + irq_to_ioapicline_map[e->irq.srcbusirq] = e->irq.dstirq; + /* ISA defaults to edge-triggered, active high */ + dpo = 0; + dtm = 0; + }; + /* (irqflag & 0x3) - polarity + = 0 - default, = 1 - active high, = 2 - reserved, = 3 - active low + IO-APIC: 0 - active high, 1 - active low */ + entry->polarity = ((int []){ dpo, 0, 0, 1})[e->irq.irqflag & 3]; + /* ((irqflag >> 2) & 0x3) - trigger mode + = 0 - default, = 1 - edge, = 2 - reserved, = 3 - level + IO-APIC: 0 - edge, 1 - level */ + entry->trigger_mode = ((int []){ dtm, 0, 0, 1})[(e->irq.irqflag >> 2) & 3]; + }; + inc = sizeof(e->irq); + break; + case MP_LINTSRC: + Dprintf("SMP: LINT: %2x %4x %2x %2x %2x %2x\n", + e->lint.irqtype, e->lint.irqflag, + e->lint.srcbus, e->lint.srcbusirq, + e->lint.dstapic, e->lint.dstlint); + inc = sizeof(e->lint); + break; +#if defined(CONFIG_DEBUG_TRACE_INIT) + default: + printf("SMP: Unknown type %2x. Aborting\n", e->type); + i = 0; + break; +#endif + }; + + } +#if defined(CONFIG_DEBUG_TRACE_INIT) + else + { + printf("MPC shall be at %x\n", f->physptr); + printf("mpc.sig: %x should be %x\n", + t->signature, MPS_MPC_SIGNATURE); + } +#endif + /* exit from scan loop */ + break; + } + +#if defined(CONFIG_DEBUG_TRACE_INIT) + /* when we can't find anything useful go with very hacky defaults */ + if ( f >= (intel_mp_floating_t*) 0x100000) + { + printf("SMP: couldn't find MPS floating structure.\n" + "SMP: Doing default setup.\n"); + + /* initialize the ISA interrupts - line 0 is unused */ + for (int i = 1; i < 16; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + entry->vector = i + 0x20; /* hw irqs start at 0x20 */ + entry->trigger_mode = 0; + entry->polarity = 0; + irq_to_ioapicline_map[i] = i; + } + /* IRQ0 is linked to input line 2 - link that back to IRQ0 */ + io_apic_intr[2].vector = 0x20; + irq_to_ioapicline_map[0] = 2; + } +#endif + + + { + /* try to figure out the mapping of PCI INT# to ISA IRQ# + - PCI INT#A is wired to IO-APIC's INT16 input + - PCI INT#B is wired to IO-APIC's INT17 input + - PCI INT#C is wired to IO-APIC's INT18 input + - PCI INT#D is wired to IO-APIC's INT19 input */ + + /* arry to temporarily store the apicpin_to_irq mapping */ + char ioapicline_to_irq[4] = { 0 , 0, 0, 0 }; + + /* scan BIOS area for the "$PIR" signature of the PCI IRQ Routing table */ + struct irq_routing_table *r; + for (r = (irq_routing_table*) 0xF0000; + r < (irq_routing_table*) 0x100000; + r = (irq_routing_table*) (((dword_t) r) + 0x10)) + if (r->signature == MPS_PIRT_SIGNATURE) + { + Dprintf("IRQ: Found PCI IRQ routing information at %p\n", r); + +#if defined(CONFIG_DEBUG_TRACE_INIT) + int slots = (r->size - sizeof(irq_routing_table))/sizeof(irq_info); + printf("IRQ: %d slots in table\n", slots); + + for (int i = slots; i--;) + { + printf("IRQ: %d: bus=%02x dev=%02x link=(%02x,%02x,%02x,%02x) slot=%02x\n", + i, + r->slots[i].bus, r->slots[i].devfn, + r->slots[i].irq[0].link, + r->slots[i].irq[1].link, + r->slots[i].irq[2].link, + r->slots[i].irq[3].link, + r->slots[i].slot); + + }; +#endif + + /* do we know how to handle the IRQ router ? */ + switch((r->rtr_vendor << 16) | (r->rtr_device)) + { + case 0x80867000: + { + Dprintf("IRQ: Router is Intel PIIX4\n"); + + /* The PIIX stores the mapping in its PCI config space at + offsets 0x60-0x63 for INTA-INTD. + See 82371AB (PIIX4) specification, section 4.1.10, p.59 */ + for (int i = 0; i < 4; i++) + { + int irq; + irq = pci_read_config_byte(r->rtr_bus, r->rtr_devfn, 0x60 + i); + /* bit 7 = 0 marks valid entries */ + if ((irq & 0x80) == 0) + { + ioapicline_to_irq[i] = irq; + Dprintf("IRQ: INT#%c routed to vector %d\n", 'A' + i, irq); + } + } + }; break; + case 0x11660200: + { + Dprintf("IRQ: Router is ServerWorks\n"); + + /* port 0xc00 is index register + port 0xc01 is data register */ + for (int i = 0; i < 4; i++) + { + int irq; + outb(0xc00, i | 0x10); + irq = inb(0xc01); + Dprintf("IRQ: Got back %02x for %02x\n", irq + 0x66, i); + { + ioapicline_to_irq[i] = irq; + Dprintf("IRQ: INT#%c routed to vector %d\n", 'A' + i, irq); + } + } + }; break; +#if defined(CONFIG_DEBUG_TRACE_INIT) + default: + { + printf("IRQ: Unknown PCI IRQ router %4x:%4x on %2x:%2x ... :-(\n", + r->rtr_vendor, r->rtr_device, r->rtr_bus, r->rtr_devfn); + }; break; +#endif + } + } + + /* with the information gathered configure the PCI inputs of the IO-APIC */ + for (int i = 16; i < 20; i++) + { + char irq; + apic_redir_t *entry = &io_apic_intr[i]; + irq = ioapicline_to_irq[i-16]; + if (irq == 0) + continue; /* no entry */ + entry->vector = irq + 0x20; /* hw irqs start at 0x20 */ + irq_to_ioapicline_map[irq] = i; + }; + + } + + /* write the entries to the IO-APIC */ + for (int i = 0; i < num_irqs; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + set_io_apic(X86_IOAPIC_REDIR0 + (i*2) + 0, *(((dword_t*)entry) + 0)); + set_io_apic(X86_IOAPIC_REDIR0 + (i*2) + 1, *(((dword_t*)entry) + 1)); +#if 0 + printf("ioredir(%d): %x, %x\n", i, + get_io_apic(X86_IOAPIC_REDIR0 + 0 + (i*2)), + get_io_apic(X86_IOAPIC_REDIR0 + 1 + (i*2))); +#endif + } +} + + +/* + * initializes the local apic + * the timer setup happens in apic_second_tick after + * measuring the duration of one second + */ +void setup_local_apic() +{ + dword_t tmp; + + /* enable local apic */ + tmp = get_local_apic(X86_APIC_SVR); + tmp |= 0x100; /* enable APIC */ + tmp &= ~(0x200); /* enable focus processor */ + ASSERT((APIC_SPURIOUS_INT_VECTOR & 0xf) == 0xf); + tmp |= APIC_SPURIOUS_INT_VECTOR; /* spurious interrupt = 0xff */ + set_local_apic(X86_APIC_SVR, tmp); + + /* set prio to accept all */ + tmp = get_local_apic(X86_APIC_TASK_PRIO); + tmp &= ~0xff; + set_local_apic(X86_APIC_TASK_PRIO, tmp); + + /* flat mode */ + tmp = get_local_apic(X86_APIC_DEST_FORMAT); + tmp |= 0xf0000000; + set_local_apic(X86_APIC_DEST_FORMAT, tmp); + + /* set lint0 as extINT - keep disabled for now */ + set_local_apic(X86_APIC_LVT_LINT0, 0x18000 | APIC_LINT0_INT_VECTOR); + /* set lint1 as NMI */ + set_local_apic(X86_APIC_LVT_LINT1, 0x08000 | APIC_DEL_NMI); + /* set error handler - keep disabled for now */ + set_local_apic(X86_APIC_LVT_ERROR, 0x18000 | APIC_ERROR_INT_VECTOR); + /* set timer handler - keep it disabled for now */ + set_local_apic(X86_APIC_LVT_TIMER, APIC_TIMER_INT_VECTOR | APIC_IRQ_MASK); + +#if defined(CONFIG_ENABLE_PROFILING) +# if defined(CONFIG_PROFILING_WITH_NMI) + /* Set perfctr as NMI */ + set_local_apic(X86_APIC_PERF_COUNTER, 0x0400 | APIC_PERFCTR_INT_VECTOR); +# else + /* Set perfctr as Fixed */ + set_local_apic(X86_APIC_PERF_COUNTER, 0x0000 | APIC_PERFCTR_INT_VECTOR); +# endif +#endif + + /* Enable NMI */ + in_rtc(0); + outb(0x61, inb(0x61) & ~(0xC)); +} + +void init_irqs() +{ +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("%s\n", __FUNCTION__); +#endif + + /* first mask all interrupts on the pic */ + outb(X86_PIC1_DATA, 0xff); + outb(X86_PIC2_DATA, 0xff); + + /* set apic to symetric mode */ + outb(0x22, 0x70); + outb(0x23, 0x01); + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("local APIC-id: %x\n", get_local_apic(X86_APIC_ID)); + printf("local APIC-Version: %x\n", get_local_apic(X86_APIC_VERSION)); + printf("local APIC SVR: %x\n", get_local_apic(X86_APIC_SVR)); + + printf("io APIC-id: %x\n", get_io_apic(X86_IOAPIC_ID)); + printf("io APIC-Version: %x\n", get_io_apic(X86_IOAPIC_VERSION)); +#endif + + /* check for local apic */ + if ((get_local_apic(X86_APIC_VERSION) & 0xf0) != 0x10) { + printf("Panic: no local APIC detected. syshalt."); + asm("hlt\n":); + } + setup_local_apic(); + + /* initialize io apic interrupts */ + setup_io_apic(); +} + +/* timer is handled in apic_handle_timer */ +void irq_handler(exception_frame_t *frame) +{ + //printf("irq %d\n", frame->fault_code); + + TRACEPOINT_1PAR(INTERRUPT, frame->fault_code, + printf("irq_handler: irq #%d\n", frame->fault_code)); + + /* edge triggered irq's can be simply ack'd + * level triggered have to be masked first. + * they are re-enabled in the ipc path + */ + if (io_apic_intr[irq_to_ioapicline_map[frame->fault_code]].trigger_mode == IOAPIC_TRIGGER_LEVEL) + { + //printf("mask_irq %d\n", frame->fault_code); + io_apic_mask_irq(irq_to_ioapicline_map[frame->fault_code]); + } + apic_ack_irq(); + +#if defined(CONFIG_ENABLE_PVI) + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we tag the interrupt bit in + * the field to handle it later. + */ + if( ((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0) ) + + { + tcb_t *current = get_current_tcb(); + /* set VIP flag - sti will cause #GP */ + frame->eflags |= X86_EFL_VIP; + current->resources |= TR_PVI; + + /* Save pending interrupt */ + pending_irq |= (1 << frame->fault_code); + + /* Bail out - keep the actual IRQ handling for later */ + return; + } +#endif /* CONFIG_ENABLE_PVI */ + + handle_interrupt(frame->fault_code); +} + +void apic_handler_lint0() +{ + enter_kdebug("apic_handler_lint0"); + apic_ack_irq(); +} + +void apic_handler_lint1() +{ + enter_kdebug("apic_handler_lint1"); + apic_ack_irq(); +} + +void apic_handler_error() +{ + enter_kdebug("apic_handler_error"); + apic_ack_irq(); +} + +void apic_handler_spurious_int() +{ + enter_kdebug("apic_handler_spurious"); + apic_ack_irq(); +} + +void apic_handler_timer() +{ + apic_ack_irq(); + handle_timer_interrupt(); +} + + +void mask_interrupt(unsigned int number) +{ + //printf("mask_interrupt %d\n", number); + io_apic_mask_irq(irq_to_ioapicline_map[number]); +} + +void unmask_interrupt(unsigned int number) +{ + //printf("unmask_interrupt %d\n", number); + io_apic_unmask_irq(irq_to_ioapicline_map[number]); +} + + +#endif /* CONFIG_X86_APIC */ + + + +void timer_irq_handler(exception_frame_t *frame) +{ + +#if defined(CONFIG_ENABLE_PVI) + + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we bear the interrupt in mind + * and handle it later. + */ + + if( ((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0) ){ + + // printf("enq timer interrupt, eip=%x\n", frame->fault_address); + // enter_kdebug("timer_irq"); + + mask_and_ack_8259A(8); + /* reset timer intr line */ + in_rtc(0x0c); + + frame->eflags |= X86_EFL_VIP; + pending_irq |= PENDING_TIMER_IRQ; + + tcb_t *current = get_current_tcb(); + current->resources |= TR_PVI; + return; + } + +#endif /* CONFIG_ENABLE_PVI */ + +#if !defined(CONFIG_X86_APICTIMER) + mask_and_ack_8259A(8); + /* reset timer intr line */ + in_rtc(0x0c); + enable_8259A_irq(8); +#else + apic_ack_irq(); +#endif /* CONFIG_X86_APICTIMER */ + handle_timer_interrupt(); +} + + +#define TRACEPOINT_INSTR(instruction...) \ + TRACEPOINT(INSTRUCTION_EMULATION, \ + { printf("instruction emulation @ %p: ", \ + frame->fault_address); \ + printf(##instruction); }) + + +static int handle_faulting_instruction(tcb_t* current, + exception_frame_t* frame) +{ + /* This function returns TRUE if the fault was handled, FALSE otherwise. + current pointer to current TCB + frame pointer to exception frame + instr pointer to first byte of instruction that caused the exception + */ + + unsigned char * instr = (unsigned char *) frame->fault_address; + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* + * Translate fault address so that we can access it using + * kernel segments. + */ + + smallid_t sid = current->space->smallid (); + if (sid.is_valid () && ((dword_t) instr < sid.bytesize ())) + instr += sid.offset (); +#endif + +#if defined(CONFIG_ENABLE_PVI) + if ( (frame->eflags & X86_EFL_VIP) && (frame->eflags & X86_EFL_VIF)){ + // printf("PVI2: tid=%x, eflags=%x\n", current->myself.raw, frame->eflags); + // enter_kdebug(); + /* Set VIF flag, clear VIP flag */ + frame->eflags |= X86_EFL_VIF; + frame->eflags &= ~X86_EFL_VIP; + current->resources &= ~TR_PVI; + + /* Handle pending interrupts */ + if (pending_irq){ + handle_pending_irq(); + } + return TRUE; + + } +#endif + switch (instr[0]) { + + case 0x0f: + switch (instr[1]) { + case 0x01: + if ( instr[2] != 0x18 ) break; + /* + * 0F 01 18 lidt (%eax) + * + * Currently, we only support LIDT emulation where the + * IDT descriptor address is in EAX. Other ways to + * load IDT are not detected and result in a GP + * exception. + */ + if ( frame->eax < USER_AREA_MAX - 6 ) + { + dword_t idt = frame->eax + 2; +#if defined(CONFIG_ENABLE_SMALL_AS) + if (sid.is_valid () && (idt < sid.bytesize ())) + idt += sid.offset (); +#endif + idt = *(dword_t *) idt; + if ( idt >= (USER_AREA_MAX - 32*8) ) + idt = 0; + current->excpt = idt; + TRACEPOINT_INSTR("lidt (idt-desc: %x, idt: %x)\n", + frame->eax, idt); + } + frame->fault_address += 3; + return TRUE; + + + case 0x09: + /* + * 0F 09 /r wbinvd + * + * wbinvd emulation is turned off by default but can + * be enabled if _really_ necessary + */ + + TRACEPOINT_INSTR("wbinvd\n"); +#if defined(CONFIG_X86_WBINVD_EMULATION) + __asm__("wbinvd\n\r"); +#endif + frame->fault_address += 2; + return TRUE; + + case 0x21: + case 0x23: + { + /* + * 0F 21 /r mov %dreg, %reg + * 0F 23 /r mov %reg, %dreg + * + * Virtualize debug registers. Registers DR4 and DR5 + * are not accessible and only task local breakpoints + * can be enabled. + * + * HERE BE DRAGONS! This code is by no means + * thoroughly tested and will not work properly in + * conjunction with KDB breakpoints. + */ +# define MOVDR_GENREG (&frame->eax)[0-(instr[2] & 0x7)] + dword_t val = MOVDR_GENREG; + dword_t dreg = (instr[2] >> 3) & 0x7; + + if ( dreg == 4 || dreg == 5 ) + break; + + if ( instr[1] == 0x21 ) + /* Get register contents from TCB. */ + MOVDR_GENREG = current->priv[0].dbg.dr[dreg]; + else + { + if ( dreg == 7 ) val &= ~0xaa; + + if ( current->resources & TR_DEBUG_REGS ) + { + TRACEPOINT_INSTR("mov reg, dr%d\n", dreg); + switch (dreg) { + case 0: asm("mov %0, %%dr0" : :"r"(val)); break; + case 1: asm("mov %0, %%dr1" : :"r"(val)); break; + case 2: asm("mov %0, %%dr2" : :"r"(val)); break; + case 3: asm("mov %0, %%dr3" : :"r"(val)); break; + case 6: asm("mov %0, %%dr6" : :"r"(val)); break; + case 7: asm("mov %0, %%dr7" : :"r"(val)); break; + } + } + + /* Store register contents into TCB. */ + current->priv[0].dbg.dr[dreg] = val; + + if ( dreg == 7 ) + if ( val & 0x33 ) + { + if ( !(current->resources & TR_DEBUG_REGS) ) + /* + * Debug registers are beeing enabled. + * Load contents of all debug + * registers from TCB. + */ + load_debug_regs((ptr_t) ¤t->priv[0].dbg); + current->resources |= TR_DEBUG_REGS; + } + else + current->resources &= ~TR_DEBUG_REGS; + } + enter_kdebug("debug register access"); + frame->fault_address += 3; + return TRUE; + } + + case 0x30: + case 0x32: + /* + * 0F 30 wrmsr + * 0F 32 rdmsr + * + * Virtualize accesses to model specific registers. + * We must check the validity of the register number + * too, or we might end up shooting ourself in the + * foot. + */ + switch (frame->ecx & 0xffff) { +#if defined(CONFIG_ARCH_X86_I686) + case IA32_PERFCTR0: + case IA32_PERFCTR1: + case IA32_EVENTSEL0: + case IA32_EVENTSEL1: +#elif defined(CONFIG_ARCH_X86_I586) + case IA32_TSC: + case IA32_CESR: + case IA32_CTR0: + case IA32_CTR1: +#elif defined(CONFIG_ARCH_X86_P4) + default: +#else + case 0xffffffff: +#endif + if ( instr[1] == 0x30 ) + { + TRACEPOINT_INSTR("wrmsr (eax=%x, edx=%x, %ecx=%x)\n", + frame->eax, frame->edx, frame->ecx); + asm volatile ("wrmsr" : : + "a"(frame->eax), + "d"(frame->edx), + "c"(frame->ecx)); + } + else + { + asm volatile ("rdmsr" + : "=a"(frame->eax), + "=d"(frame->edx) + : "c"(frame->ecx)); + TRACEPOINT_INSTR("rdmsr (eax=%x, edx=%x, %ecx=%x)\n", + frame->eax, frame->edx, frame->ecx); + } + frame->fault_address += 2; + return TRUE; + } + break; + + case 0xa1: + case 0xa9: + goto pop_seg; + } + break; + + case 0x8e: + case 0x07: + case 0x17: + case 0x1f: + pop_seg: + /* + * 8E /r mov %reg, %segreg + * 07 pop %es + * 17 pop %ss + * 1F pop %ds + * 0F A1 pop %fs + * 0F A9 pop %gs + * + * Segment descriptor is being written with an invalid + * value. Reset all descriptors with the correct value + * and skip the instruction. + */ + if ( frame->fault_address >= KERNEL_VIRT ) break; + TRACEPOINT(SEGREG_RELOAD); + + asm volatile ( +#if defined(CONFIG_TRACEBUFFER) + " movl %1, %%fs \n" +#else + " movl %0, %%fs \n" +#endif + " movl %0, %%gs \n" + : + :"r"(X86_UDS), "r"(X86_TBS)); + frame->ds = frame->es = X86_UDS; + + frame->fault_address++; + if ( instr[0] == 0x8e || instr[0] == 0x0f ) + frame->fault_address++; + return TRUE; + +#if defined(CONFIG_ENABLE_SMALL_AS) + case 0xcf: + { + /* + * CF iret + * + * When returning to user-level the instruction pointer + * might happen to be outside the small space. If so, we + * must promote the space to a large one. + */ + if ( (dword_t) instr >= KERNEL_VIRT && + sid.is_valid () && + get_user_ip(current) > sid.bytesize () ) + { + small_space_to_large (current->space); + return TRUE; + } + break; + } +#endif + + case 0xf4: + /* + * F4 hlt + * + * Kernel version / API interface detection. Return the + * appropriate values in register EAX. + */ + TRACEPOINT(GET_KERNEL_VERSION, + printf("GetKernelVersion @ %x\n",frame->fault_address)); + frame->eax = ((KERNEL_VERSION_API << 24) | + (KERNEL_VERSION_KID << 20) | + (KERNEL_VERSION_VER << 16) | + (KERNEL_VERSION_SUB << 1) | 1); + frame->fault_address += 1; + return TRUE; +#if defined(CONFIG_ENABLE_PVI) + + case 0xfb: /* sti */ + { + /* + * If running in PVI Mode, sti can only cause an exception + * if a virtual interrupt is pending + */ + // printf("PVI: tid = %x, eflags=%x\n", current->myself.raw, frame->eflags); + // enter_kdebug(""); + /* Set VIF flag, clear VIP flag */ + frame->eflags |= X86_EFL_VIF; + frame->eflags &= ~X86_EFL_VIP; + current->resources &= ~TR_PVI; + + /* Handle pending interrupts */ + if (pending_irq){ + handle_pending_irq(); + } + return TRUE; + } + +#else +/* This can be used to virtualize sti/cli completely in software */ + +#if 0 + case 0xfa: /* sti */ + { + frame->eflags &= ~X86_EFL_IF; + frame->fault_address += 1; + return TRUE; + } + case 0xfb: /* sti */ + { + frame->eflags |= X86_EFL_IF; + frame->fault_address += 1; + return TRUE; + } + +#endif + +#endif /* CONFIG_ENABLE_PVI */ + +#if defined(CONFIG_IO_FLEXPAGES) + + case 0xe4: /* in %al, port imm8 (byte) */ + case 0xe6: /* out %al, port imm8 (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xe5: /* in %eax, port imm8 (dword) */ + case 0xe7: /* out %eax, port imm8 (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xec: /* in %al, port %dx (byte) */ + case 0xee: /* out %al, port %dx (byte) */ + case 0x6c: /* insb port %dx (byte) */ + case 0x6e: /* outsb port %dx (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %eax, port %dx (dword) */ + case 0xef: /* out %eax, port %dx (dword) */ + case 0x6d: /* insd port %dx (dword) */ + case 0x6f: /* outsd port %dx (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 2, 0); + printf("pagefault, addr = %x\n", io_fault.raw); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0x66: + + /* operand size override prefix */ + switch (instr[1]) + { + case 0xe5: /* in %ax, port imm8 (word) */ + case 0xe7: /* out %ax, port imm8 (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 1 , 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %ax, port %dx (word) */ + case 0xef: /* out %ax, port %dx (word) */ + case 0x6d: /* insw port %dx (word) */ + case 0x6f: /* outsw port %dx (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 1, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + } + case 0xf3: + + /* rep instruction */ + switch (instr[1]){ + case 0xe4: /* in %al, port imm8 (byte) */ + case 0xe6: /* out %al, port imm8 (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xe5: /* in %eax, port imm8 (dword) */ + case 0xe7: /* out %eax, port imm8 (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xec: /* in %al, port %dx (byte) */ + case 0xee: /* out %al, port %dx (byte) */ + case 0x6c: /* insb port %dx (byte) */ + case 0x6e: /* outsb port %dx (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %eax, port %dx (dword) */ + case 0xef: /* out %eax, port %dx (dword) */ + case 0x6d: /* insd port %dx (dword) */ + case 0x6f: /* outsd port %dx (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0x66: + + /* operand size override prefix */ + switch (instr[2]) + { + case 0xe5: /* in %ax, port imm8 (word) */ + case 0xe7: /* out %ax, port imm8 (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 1 , 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %ax, port %dx (word) */ + case 0xef: /* out %ax, port %dx (word) */ + case 0x6d: /* insw port %dx (word) */ + case 0x6f: /* outsw port %dx (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 1, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + } + } +#endif /* CONFIG_IO_FLEXPAGES */ + } + + /* Nothing to repair */ + return FALSE; +} + + +static int handle_nm_exception(tcb_t *current) +{ + /* the current FPU owner resides in the cpu-local section */ + extern tcb_t* fpu_owner; + + TRACEPOINT(FPU_VIRTUALIZATION, + printf("FPU: %x uses fpu at %x, owner=%p\n", + current->myself.raw, get_user_ip(current), + fpu_owner)); + + /* allow access to the FPU until the next thread switch */ + enable_fpu(); + + /* mark the FPU usage in the resources */ + current->resources |= TR_FPU; + + /* if we own the fpu just re-enable and go */ + if (fpu_owner == current) + return TRUE; + +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) +# if X86_FLOATING_POINT_ALLOC_SIZE < KMEM_CHUNKSIZE +# error FIXME: Too small allocation size for floating point state +# endif + /* save the fpu state into the fpu-owner's save area */ + if (fpu_owner != NULL) + save_fpu_state ((byte_t *) fpu_owner->priv->fpu_ptr); + + /* now reload the fpu state */ + if (current->priv->fpu_ptr) + load_fpu_state ((byte_t *) current->priv->fpu_ptr); + else + { + init_fpu(); + current->priv->fpu_ptr = (x86_fpu_state_t *) + kmem_alloc (X86_FLOATING_POINT_ALLOC_SIZE); + if (current->priv->fpu_ptr == NULL) + panic ("fpu virtualization: alloc mem for fpu state failed"); + } +#else + /* save the fpu state into the fpu-owner's tcb */ + if (fpu_owner != NULL) + save_fpu_state ((byte_t *) &fpu_owner->priv->fpu); + + /* now reload the fpu state */ + if (current->priv->fpu_used) + load_fpu_state ((byte_t *) ¤t->priv->fpu); + else + { + init_fpu(); + current->priv->fpu_used = 1; + } +#endif + + /* update the owner */ + fpu_owner = current; + + return TRUE; +} + + +#if defined(CONFIG_ENABLE_SMALL_AS) +extern "C" void sysexit_tramp(void); +extern "C" void reenter_sysexit(void); +#endif + +void exception_handler(exception_frame_t * frame) +{ + tcb_t * current = get_current_tcb(); + +#if defined(CONFIG_DEBUGGER_KDB) && defined(CONFIG_DEBUG_BREAKIN) + /* We might happen to get into a loop catching exceptions. */ + kdebug_check_breakin(); +#endif + + /* + ** + ** General Protection Fault + ** + */ + if (frame->fault_code == 13) + { + /* + * A GP(0) could mean that we have a segment register with + * zero contents, either because the user did a reload + * (valid), or because of some strange bi-effects of using the + * SYSEXIT instruction (see comment in exception.S). + */ + if ( frame->error_code == 0 ) + { + word_t fs, gs; + asm (" mov %%fs, %w0 \n" + " mov %%gs, %w1 \n" + :"=r"(fs), "=r"(gs)); + + if ( (frame->ds & 0xffff) == 0 || (frame->es & 0xffff) == 0 || + fs == 0 || gs == 0 ) + { + TRACEPOINT (SEGREG_RELOAD, kdebug_dump_frame (frame)); + reload_user_segregs (); + frame->ds = frame->es = (frame->cs & 0xffff) == X86_UCS + ? X86_UDS : X86_KDS; + frame->es = X86_UDS; + return; + } + } + +#if defined(CONFIG_ENABLE_SMALL_AS) +# if defined(CONFIG_IA32_FEATURE_SEP) + /* + * Check if we caught an exception when doing the LRET. + */ + dword_t user_eip = get_user_ip(current); + + if ( user_eip >= (dword_t) sysexit_tramp && + user_eip < (dword_t) reenter_sysexit ) + { + /* + * If we faulted at the LRET instruction (i.e., still in + * user level) we must IRET to the kernel due to the user + * space code segment limitation. We must also disable + * interrupts since we can not be allowed to be preempted + * in the reenter-trampoline. + */ + frame->cs = X86_KCS; + frame->eflags &= ~X86_EFL_IF; + frame->ecx = (dword_t) get_user_sp(current); + frame->fault_address = (dword_t) reenter_sysexit; + return; + } +# endif /* defined(CONFIG_IA32_FEATURE_SEP) */ + +#endif + + + /* Do we have to emulate/virtualize something? Analyze the + * instruction that caused the exception. The function should + * return TRUE if no further processing is required. */ + if (handle_faulting_instruction(current, frame) == TRUE) + return; + + /* + * IDT emulation. + */ + + if ( (frame->error_code & 2) && (current->excpt) ) + { + TRACEPOINT(IDT_FAULT, + printf("IDT fault: tcb=%p excpt=%d\n", + current, frame->error_code >> 3)); + + /* + * Validate that we can safely push an iframe on the user + * stack. Current->excpt is already checked during + * emulation of the LIDT instruction. + */ + + if ( (dword_t) frame->user_stack > USER_AREA_MAX || + (dword_t) frame->user_stack <= 4 * sizeof(dword_t) ) + { + enter_kdebug("IDT emulation user stack out of bounds"); + goto Unhandled_fault; + } + + /* + * Validate that we do not access user memory outside of + * the small space boundaries. + */ + + dword_t offset = 0; +#if defined(CONFIG_ENABLE_SMALL_AS) + smallid_t sid = current->space->smallid (); + if (sid.is_valid ()) + { + if ( ((dword_t) frame->user_stack <= sid.bytesize ()) && + ((dword_t) (current->excpt + (13 * 8) + 4) + 4 <= + sid.bytesize ()) ) + { + offset = sid.offset (); + } + else + small_space_to_large (current->space); + } +#endif + + /* + * Grab the fault handler location from the thread's IDT. + */ + + dword_t *ex = (dword_t *) (current->excpt + offset + (13*8)); + dword_t fault_handler = (ex[0] & 0xffff) | (ex[1] & 0xffff0000); + + /* + * Create a fake fault frame and trap into the fault handler. + */ + + dword_t *usp = frame->user_stack + (offset / sizeof(dword_t)); + *(--usp) = frame->eflags; + *(--usp) = frame->cs; + *(--usp) = frame->fault_address; + *(--usp) = frame->error_code; + frame->fault_address = fault_handler; + frame->user_stack = usp - (offset / sizeof(dword_t)); + return; + } + } + + + /* + ** + ** Processor Extension not Available + ** + */ + if (frame->fault_code == 7) + if (handle_nm_exception(current) == TRUE) + return; + + + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( frame->fault_code == 12 || frame->fault_code == 13 ) + { + /* + * If a GP(0) or SS(0) is raised it might happen to be a small + * address space accessing an address outside of its segment + * boundaries. + */ + if (frame->error_code == 0 && current->space->is_small ()) + { + small_space_to_large (current->space); + return; + } + } +#endif + +Unhandled_fault: + + printf("exception (%d)\n", frame->fault_code); + kdebug_dump_frame(frame); + enter_kdebug(); +} + + +#if defined(CONFIG_ENABLE_PVI) + +void handle_pending_irq(void){ + + tcb_t *current = get_current_tcb(); + tcb_t *max_priority = current; + tcb_t *owner; + + // printf("handle_pending_irq %x\n", pending_irq); + + + for (dword_t num = 0; num < MAX_PENDING_IRQS; num++){ + + if (pending_irq & PENDING_IRQ_BIT(num)){ + // printf("handle_pending_irq number %x\n", num); + + owner = interrupt_owner[num]; + + /* if no one is associated - we simply drop the interrupt */ + if (owner) + { + if (IS_WAITING(owner) && + ((owner->partner.raw == (num + 1)) || l4_is_nil_id(owner->partner))) + { + owner->intr_pending = (num + 1) | IRQ_IN_SERVICE; + // printf("enqueue ready owner %x, me is %x\n", owner->myself.raw, current->myself.raw); + thread_enqueue_ready(owner); + owner->thread_state = TS_LOCKED_RUNNING; + + if (max_priority->priority < owner->priority) + max_priority = owner; + + } + else + owner->intr_pending = num + 1; + + } + } + } + + if (current != get_idle_tcb()){ + // printf("enqueue ready current %x\n", current->myself.raw); + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + } + + if (pending_irq & PENDING_TIMER_IRQ){ + // printf("handle pending timer interrupt; max_priority = %x, current = %x, resources=%x\n", max_priority->myself.raw, current->myself.raw, current->resources); + + enable_8259A_irq(8); + pending_irq = 0; + +#if (defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB)) && defined(CONFIG_DEBUG_BREAKIN) + kdebug_check_breakin(); +#endif + +#if defined(CONFIG_SMP) + /* only cpu 0 maintains the clock */ + if (get_cpu_id() == 0) +#endif + kernel_info_page.clock += TIME_QUANTUM; + + current->current_timeslice -= TIME_QUANTUM; + + if (max_priority == current){ + tcb_t * wakeup = parse_wakeup_queue(current->priority, kernel_info_page.clock); + if (wakeup) + { + dispatch_thread(wakeup); + return; + } + + if (current->current_timeslice <= 0) + { + spin1(78); + current->current_timeslice = current->timeslice; + dispatch_thread(find_next_thread()); + } + + return; + } + } + + pending_irq = 0; + + if (max_priority != current){ + /* make sure runnable threads are in the ready queue */ + switch_to_thread(max_priority, current); + } + +} +#endif /* CONFIG_ENABLE_PVI */ + + diff --git a/kernel/src/x86/.#io_mapping.c.1.2 b/kernel/src/x86/.#io_mapping.c.1.2 new file mode 100644 index 0000000..0736c0c --- /dev/null +++ b/kernel/src/x86/.#io_mapping.c.1.2 @@ -0,0 +1,1250 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: x86/io_mapping.c + * Description: Implementation of mapping database for IO fpages + * + * @LICENSE@ + * + * $Id: io_mapping.c,v 1.2 2002/05/21 15:39:29 stoess Exp $ + * + ********************************************************************/ + +#include + +#if defined(CONFIG_IO_FLEXPAGES) + +#include +#include +#include +#include + +#if defined(CONFIG_AUTO_IO_MAP) +#define IOPBM_DEFAULT_VALUE (0) +#else +#define IOPBM_DEFAULT_VALUE (~0) +#endif + +#define MIN(a,b) (a> 12) & 0x0000FFFF)) +#define IOFP_LD_SIZE(x) ((dword_t) (((x) >> 2) & 0x0000003F)) +#define IOFP_SIZE(x) ((dword_t) (1 << IOFP_LD_SIZE(x))) + +#define IOMDB_LO_MASK 0xFFFF0000 +#define IOMDB_TID_MASK 0x000000FF + +#define IOMDB_HI_MASK 0xFFFF8000 +#define IOMDB_DUMMY_MASK 0x00004000 +#define IOMDB_DEPTH_MASK 0x00003FFF +#define IOMDB_SUP_DEPTH 0x00004000 + +#define FLUSH_OWN_SPACE (1<<31) + +// #define IO_MDB_DEBUG 1 + +/* The Kernel Page Directory */ +static space_t *kspace; + +/* The virtual address of the default iopbm */ +static dword_t iopbm_virt; + +/* The physical address of the default iopbm */ +static ptr_t iopbm_phys; + +/* The Pagetable containing the entry to the IOPM */ +static pgent_t *iopbm_pgt; + +/* The TSS */ +extern x86_tss_t __tss; + + + +/* IO Mapping Node */ +class io_mnode_t +{ +public: + dword_t w1; /* Lower Bound (16), TaskID (8) */ + dword_t w2; /* Higher Bound (17), Dummy Marker (1), + Tree Depth (14) */ + io_mnode_t *next, *prev; /* Next/Prev Node in Mapping Tree */ + io_mnode_t *next_st, *prev_st; /* Next/Prev Node in Tasks List */ + + io_mnode_t *parent; /* Parent */ + + dword_t get_lo(void) + { return (w1 >> 16); } + + void set_lo(dword_t l) + { w1 = (w1 & IOMDB_TID_MASK) | (l << 16); } + + l4_threadid_t get_tid(void) + { return (l4_threadid_t) { raw : { ( (w1 & IOMDB_TID_MASK) << L4_X0_THREADID_BITS + L4_X0_VERSION_BITS)}};} + + void set_tid(l4_threadid_t t) + { w1 = (w1 & IOMDB_LO_MASK) | ( (t.raw >> L4_X0_THREADID_BITS + L4_X0_VERSION_BITS ) & IOMDB_TID_MASK );} + + dword_t get_hi(void) + { return (w2 >> 15); } + + void set_hi(dword_t h) + { w2 = (w2 & (IOMDB_DEPTH_MASK | IOMDB_DUMMY_MASK) ) | (h << 15); } + + + dword_t get_dummy(void) + { return (w2 & IOMDB_DUMMY_MASK); } + + void set_dummy(void) + { w2 |= IOMDB_DUMMY_MASK; } + + dword_t get_depth(void) + { return (w2 & IOMDB_DEPTH_MASK); } + + void set_depth(dword_t s) + { w2 = (w2 & (IOMDB_HI_MASK | IOMDB_DUMMY_MASK)) | (s & IOMDB_DEPTH_MASK) ; } + + void set_values(dword_t lo, dword_t hi, l4_threadid_t tid, dword_t depth, byte_t dummy){ + w1 = (lo << 16) | ((tid.raw >> L4_X0_THREADID_BITS + L4_X0_VERSION_BITS) & IOMDB_TID_MASK); + w2 = ((hi << 15) | (dummy ? IOMDB_DUMMY_MASK : 0)) | (depth & IOMDB_DEPTH_MASK); + } + + void enq_thread_list(io_mnode_t *before){ + this->next_st = before; + this->prev_st = before->prev_st; + before->prev_st = this; + this->prev_st->next_st = this; + } + + void deq_thread_list(){ + this->next_st->prev_st = this->prev_st; + this->prev_st->next_st = this->next_st; + + } + + void enq_subtree(io_mnode_t *after){ + this->next = after->next; + this->prev = after; + this->next->prev = this; + after->next = this; + } + + void deq_subtree(){ + this->next->prev = this->prev; + this->prev->next = this->next; + } + +}; + + + +/* The Initial Sigma0 node */ +static io_mnode_t sigma0_io_space; + +/* The IO MDB Terminator */ +static io_mnode_t io_mdb_end; + + +/* + * Lock mechanism: + * Implemented by a binary semaphore + * TODO: This could be crap + */ + + +/* The Semaphore */ +static dword_t io_mdb_lock; + +#if 0 +static void io_mdb_p(void){ + __asm__ __volatile__ ( + "1: \n\t" + "lock;" + "btsl $0, %0 \n\t" + "jc 1b \n\t" + : + :"m"(io_mdb_lock)); + +} + + + +static void io_mdb_v(void){ + __asm__ __volatile__ ( + "lock;" + "btrl $0, %0 \n\t" + : + :"m"(io_mdb_lock)); +} +#else +#define io_mdb_p() +#define io_mdb_v() +#endif + + +/* + * int get_iopbm() + * + * returns the first valid node of a task + */ + +static inline io_mnode_t *get_iospace(tcb_t *task){ + + dword_t *pgd = task->space->pagedir(); + return ((io_mnode_t *) pgd[IO_SPACE_IDX])->next_st; +} + +/* + * int get_iopbm() + * + * Sets the PGT entry to IO-Space + */ + +static inline void set_iospace(tcb_t *task, io_mnode_t *node){ + + dword_t *pgd = task->space->pagedir(); + pgd[IO_SPACE_IDX] = (dword_t) node; +} + +/* + * int get_iopbm() + * + * returns the physical address of the iopbm of a task + */ + +static inline ptr_t get_iopbm(space_t *space){ + + return (ptr_t) space->pgent(pgdir_idx(iopbm_virt))->subtree(space, 0)->\ + next(space, pgtab_idx(iopbm_virt), 0)->address(space, 0); + +} + +/* + * int install_iopbm() + * + * installs an intialised 8k Region as IOPBM + * + */ + + +static int install_iopbm(tcb_t *task, dword_t new_iopbm){ + + + /* + * Allocate a Pagetable. + * Do not use ->make_subtree, as we have to + * allocate and set up the pagetable _before_ + * installing it + */ + pgent_t *pgt_new = (pgent_t *) kmem_alloc(PAGE_SIZE); + + if (pgt_new == NULL){ + panic("install_iopbm(): out of memory\n"); + } + + /* Copy all entries from Kernel Page Table */ + pgent_t *k = iopbm_pgt; + pgent_t *n = pgt_new; + + for (int i=0; i<1024; i++){ + n->copy(task->space, 1, k, kspace, 1); + k = k->next(kspace, 1, 1); + n = n->next(task->space, 1, 1); + } + + + /* Set the two special entries */ + pgt_new->next(task->space, pgtab_idx(iopbm_virt), 0)->\ + set_entry(task->space, virt_to_phys(new_iopbm), 0, 0); + pgt_new->next(task->space, pgtab_idx(iopbm_virt), 0)->\ + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + pgt_new->next(task->space, pgtab_idx(iopbm_virt + 0x1000), 0)->\ + set_entry(task->space, virt_to_phys( new_iopbm + 0x1000), 0, 0); + pgt_new->next(task->space, pgtab_idx(iopbm_virt + 0x1000), 0)->\ + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + + /* Install new Pagetable (writable) */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_entry(task->space, (dword_t) virt_to_phys( (ptr_t) pgt_new), 1, 0); + + + /* Set Flags */ + task->space->pgent(pgdir_idx(iopbm_virt))-> + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + if (task == get_current_tcb()){ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + } + + return 0; + + +} + +/* + * void release_iopbm() + * + * releases the IOPBM of a task and sets the pointers back to the default-IOPBM + * + */ + +static void release_iopbm(tcb_t *task){ + + + /* Get the special pagetable */ + ptr_t iopbm = get_iopbm(task->space); + + if (iopbm == iopbm_phys) + return; + + iopbm = phys_to_virt(iopbm); + + pgent_t *pgt = task->space->pgent(pgdir_idx(iopbm_virt))->subtree(task->space, 0); + + /* Insert the default PGT */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_entry(task->space, (dword_t) virt_to_phys( (ptr_t) iopbm_pgt), 1, 0); + + /* Set Flags */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_flags(task->space,0, PAGE_VALID | PAGE_WRITABLE); + + /* Release the Pagetable */ + kmem_free((ptr_t) pgt, PAGE_SIZE); + + /* Release the IOPBM */ + kmem_free(iopbm, X86_IOPERMBITMAP_SIZE / 8); + + + /* Flush the corresponding TLB entries */ + if (task == get_current_tcb()){ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + } + + +} + +/* + * int zero_iopbm() + * + * returns 0 on success + * -1 on error + */ + +static int zero_iopbm(tcb_t *task, dword_t port, dword_t size) +{ + dword_t count; + + // printf("zero_iopbm(): port=%x, size=%x, tid=%x\n", port, size, task->myself.raw); + + ptr_t iopbm = get_iopbm(task->space); + +#if !defined(CONFIG_AUTO_IO_MAP) + + /* + * If the task had no mappings before, it has the default IOPBM (which is set to ~0 in case + * of no implicit mapping). Create a new one, set it to 0 between port and port + size, + * and to ~0 else + */ + + if (iopbm == iopbm_phys){ + + + ptr_t new_iopbm, tmp; + + new_iopbm = kmem_alloc(X86_IOPERMBITMAP_SIZE / 8); + + if (new_iopbm == NULL){ + panic("zero_iopbm(): out of memory\n"); + } + + if (install_iopbm(task, (dword_t) new_iopbm)){ + printf("zero_iopbm(): install_iopbm failed\n"); + return -1; + } + + tmp = new_iopbm; + /* Set the bits in our new IOPBM */ + + /* Set the first set of bits to ~0, until we reach the dword of the port */ + + count = port >> 5; + + for (dword_t i=0; i < count; i++) + *(new_iopbm++) = ~0; + + + /* Zero the first dword, in which the port has its bit */ + count = MIN(size , 32 - (port & 0x1F) ); + *(new_iopbm++) = ~(( (dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Zero dwords between first and last dword */ + while( size >= 32){ + *(new_iopbm++) = 0; + size -= 32; + } + + /* Zero the last dword, in which port+size has its bits */ + if (size){ + *(new_iopbm++) = ~( (dword_t)~0 >> (32 - size)); + } + + /* The remainder of the bits is to set to 1 */ + while(new_iopbm < tmp + 2048){ + *(new_iopbm++) = ~0; + } + + return 0; + + } /* if (iopbm == iopbm_phys) */ + else +#endif /* !defined(CONFIG_AUTO_IO_MAP) */ + iopbm = phys_to_virt(iopbm); + + /* Jump to the right location */ + iopbm += (port >> 5); + + /* Zero the first dword, in which the port has its bit */ + count = MIN(size , 32 - (port & 0x1F) ); + + *(iopbm++) &= ~(( (dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Zero dwords between first and last dword */ + while( size >= 32){ + *(iopbm++) = 0; + size -= 32; + } + + /* Zero the last dword, in which port+size has its bits */ + if (size){ + *(iopbm++) &= ~((dword_t)~0 >> (32 - size)); + } + + return 0; +} + +/* + * int set_iopbm() + * + * returns 0 on success + * -1 on error + */ + +static int set_iopbm(tcb_t *task, dword_t port, dword_t size){ + + int count; + ptr_t iopbm; + + iopbm = get_iopbm(task->space); + + // printf("set_iopbm(): port=%x, size=%x, tid=%x\n", port, size, task->myself.raw); + +#if defined(CONFIG_AUTO_IO_MAP) + + /* + * Check if mapper has the default iopbm which is set to 0 everywhere in case of + * implicit mapping enabled. + */ + + if (iopbm == iopbm_phys){ + + iopbm = kmem_alloc(X86_IOPERMBITMAP_SIZE / 8); + + if (iopbm == NULL){ + panic("set_iopbm(): out of memory\n"); + } + + if (install_iopbm(task, (dword_t) iopbm)){ + // printf("set_iopbm(): install_iopbm failed\n"); + return -1; + } + + } + else +#endif + iopbm = phys_to_virt(iopbm); + /* Set the bits in the IOPBM */ + + iopbm += (port >> 5); + + /* Set the first dword, in which the port has its bit */ + + count = MIN(size , 32 - (port & 0x1F) ); + *(iopbm++) |= (((dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Set dwords between first and last dword */ + while( size >= 32){ + *(iopbm++) = ~0; + size -= 32; + } + + /* Set the last dword, in which port+size has its bits */ + if (size){ + *(iopbm++) |= ( (dword_t)~0 >> (32 - size)); + } + + return 0; + +} + + +#if defined(IO_MDB_DEBUG) +void dump_io_mdb(void){ + io_mnode_t *n = &sigma0_io_space; + while (n){ + printf("io_mnode: lo=%x, hi=%x, tid=%x, depth=%x, addr=%x, parent=%x\n",\ + n->get_lo(), n->get_hi(), n->get_tid(), n->get_depth(), n, n->parent); + n = n->next; + } + +} +#else +void dump_io_mdb(void){} +#endif + +/* + * int unmap_subtree() + * + * modifies (and removes if needed) the subtree below in order to unmap the + * given region out of the subtree + * + */ + +static int unmap_subtree(io_mnode_t *root, dword_t lo, dword_t hi, dword_t mapmask){ + + tcb_t *flushee; + io_mnode_t *n; + + io_mnode_t *n_left_end; + dword_t split_depth; + + /* + * split_depth marks the tree depth of an eventual split, set it to infinite + * in case of splitting the nodes, the depth is the upper bound for splitting + */ + split_depth = IOMDB_SUP_DEPTH; + n_left_end = NULL; + + mapmask &= FLUSH_OWN_SPACE; + + n = mapmask ? root : root->next; + + /* Modify/Remove Subtree */ + while (n->get_depth() > root->get_depth() || mapmask){ + + // printf("n_first->node: %x-%x depth=%x, tid=%x\n", n->get_lo(), + // n->get_hi(), n->get_depth(), n->get_tid()); + + + /* Set mapmask to 0 as we have to remove ourselves only once */ + mapmask = 0; + flushee = tid_to_tcb(n->get_tid()); + + /* Check what we have to do: */ + if (lo <= n->get_lo()){ + + if (hi >= n->get_hi()){ + + // printf("unmap_subtree(): begins before, ends after-> free\n"); + /* We can free the node to flush, as its region is a subset of the io_fp we want to flush */ + + /* Chain out of task list */ + n->deq_thread_list(); + + /* Chain out of subtree */ + n->deq_subtree(); + + if (set_iopbm(flushee, n->get_lo(), n->get_hi() - n->get_lo())){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + /* If the node is not part of a split subtree, set split mark to infinite */ + if (n->get_depth() <= split_depth){ + + split_depth = IOMDB_SUP_DEPTH; + } + + /* Free Node */ + { + io_mnode_t *tmp = n->prev; + mdb_free_buffer((ptr_t) n, sizeof(io_mnode_t)); + n = tmp; + } + } + + else{ + /* io_fp begins before node to flush and ends in or before it */ + printf("unmap_subtree(): begins before, ends in or before\n"); + + if (hi > n->get_lo()){ + + /* io_fp begins before and ends in it, set the IOPBM and resize the node */ + if (set_iopbm(flushee, n->get_lo(), hi - n->get_lo())){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + n->set_lo(hi); + } + + /* If the node is not part of a split subtree, set split mark to infinite */ + if (n->get_depth() <= split_depth){ + + split_depth = IOMDB_SUP_DEPTH; + } + + } + + } + + else{ + /* (lo > n->get_lo()) */ + + if (hi > n->get_hi()){ + + /* io_fp begins in or after node to flush and ends after it */ + // printf("unmap_subtree(): begins in or after, ends after\n"); + + if (lo < n->get_hi()){ + + /* io_fp begins in node to flush: resize it */ + if (set_iopbm(flushee, lo, n->get_hi() - lo)){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + n->set_hi(lo); + + } + + /* If we are in a split subtree, we have to place this node on the left subtree */ + if (n->get_depth() > split_depth){ + + /* Store next node for loop */ + io_mnode_t *n_tmp = n->next; + + /* Chain out of tree */ + n->deq_subtree(); + + /* Chain in tree */ + n->enq_subtree(n_left_end); + + /* New end of left subtree */ + n_left_end = n; + + /* Restore node for loop */ + n = n_tmp->next->prev; + } + + else{ + split_depth = IOMDB_SUP_DEPTH; + } + + } + + else{ + + /* + * io_fp begins and ends in the node to flush - this is the more + * complicated part + * + * - split subtree + * - allocate a new node + * - chain in new node an store it + * - take care about splitting 'til we reach the end of this + * subtree + * + */ + // printf("unmap_subtree(): begins in, ends in ->split\n"); + + if (set_iopbm(flushee, lo, hi - lo)){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + /* The new node is left node */ + io_mnode_t *n_left = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_left == NULL){ + enter_kdebug("unmap_subtree(): out of memory"); + } + + n_left->set_values(n->get_lo(), lo, n->get_tid(), n->get_depth(), 0); + n->set_lo(hi); + + + /* Chain in task list */ + n_left->enq_thread_list(n); + + /* Are we yet in a subtree which has been splitted ? */ + if (n->get_depth() > split_depth){ + + /* Chain in left node */ + n_left->enq_subtree(n_left_end); + + /* + * Parent of left node is either parent of last node or last + * node itself + */ +#warning js: review + n_left->parent = (n_left_end->get_depth() < n_left->get_depth()) ?\ + n_left_end : n_left->parent; + + /* New end of the left part of the split subtree */ + n_left_end = n_left; + + } + + else{ + + /* Chain left node in subtree before n */ + n_left->enq_subtree(n->prev); + + /* Parent of left node is parent of right node */ + n_left->parent = n->parent; + + /* + * Store the beginning depth of the split and the end of the + * left split tree + */ + + split_depth = n->get_depth(); + n_left_end = n_left; + } + } + + } + n = n->next; + + } /* while (n->get_depth() > n_first->get_depth() */ + + return 0; + +} + +/* + * int grant_subtree() + * + * copies the subtree below root valid for granting into a new subtree and + * returns new root + */ + +static io_mnode_t *grant_subtree(io_mnode_t *root, io_mnode_t *dest, tcb_t *to, dword_t lo, dword_t hi){ + + io_mnode_t *n, *new_root, *n_new, *n_cur; + + + /* Allocate new root */ + new_root = n_cur = n_new = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (new_root == NULL){ + panic("grant_subtree(): out of memory"); + } + + /* Setup new root: */ + new_root->set_values(lo, hi, to->myself, root->get_depth(), 0); + new_root->parent = root->parent; + + /* Chain in new root in thread list after dest */ + new_root->enq_thread_list(dest->next_st); + + /* Grant Subtree */ + n = root->next; + + while (n->get_depth() > root->get_depth()){ + if (n->get_lo() < new_root->get_hi() && n->get_hi() > new_root->get_lo()){ + + /* Allocate new children */ + n_new = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_new == NULL){ + panic("grant_subtree(): out of memory"); + } + + /* Setup new child */ + n_new->set_values(MAX(n->get_lo(), new_root->get_lo()),\ + MIN(n->get_hi(), new_root->get_hi()),\ + n->get_tid(),\ + n->get_depth(),\ + 0); + n_new->parent = new_root; + + + /* Chain in in created subtree */ + n_new->prev = n_cur; + n_cur->next = n_new; + + /* + * Chain in in thread list after n + * At the moment, we have two mapping nodes representing the same + * region: + * the old in the subtree below root and the new one below + * new_root. + * We unmap the old one later. But as the old subtree could be + * splitted, we might then have to switch the new nodes in the + * thread list later (*). + */ + n_new->enq_thread_list(n->next_st); +#warning js: revie n_cur, should be assigned n_new; + n_cur = n; + + } + n = n->next; + + } + + + /* OK, now unmap the old one */ + + /* Parent of new child will be root->prev */ + root = root->prev; + + /* Unmap subtree below parent */ + if (unmap_subtree(root->next, lo, hi, FLUSH_OWN_SPACE)){ + printf("grant_subtree(): unmap_subtree failed\n"); + return NULL; + } + + /* Chain in created subtree in mapping tree */ + new_root->prev = root; + n_new->next = root->next; + root->next = new_root; + n_new->next->prev = n_new; + + + /* + * (*) Now parse the new subtree and switch nodes in thread list + * Actually, this is not very nice, but it works + */ + n = new_root; + + do{ + if (n->prev_st->get_hi() > n->get_lo()){ + + /* Found a split subtree, therefore switch those two nodes */ + io_mnode_t *tmp = n->prev_st; + + tmp->prev_st->next_st = n; + n->next_st->prev_st = tmp; + + tmp->next_st = n->next_st; + n->next_st = tmp; + + n->prev_st = tmp->prev_st; + tmp->prev_st = n; + + } + n = n->next; + + + } while(n->get_depth() > new_root->get_depth()); + + + + return new_root; +} + +/* + * void io_mdb_init() + */ + +void io_mdb_init(void){ + + // printf("io_mdb_init()"); + /* Store the virtual address of the IOPBM */ + iopbm_virt = (dword_t) __tss.io_bitmap; + + /* Get physical Address of the default IOPBM */ + kspace = get_kernel_space(); + + /* Get physical address of the default IOPBM */ + iopbm_phys = get_iopbm(kspace); + + /* This is the Pagetable containing the entry to the IOPM */ + iopbm_pgt = kspace->pgent(pgdir_idx(iopbm_virt))->subtree(kspace,0); + + +#if defined(CONFIG_IA32_FEATURE_PGE) + /* Set the pagetable entries for IOPBM to non-global if PGE enabled */ + iopbm_pgt->next(kspace, pgtab_idx(iopbm_virt))->set_flags(kspace, 0, PAGE_VALID | PAGE_WRITABLE); + iopbm_pgt->next(kspace, pgtab_idx(iopbm_virt + 0x1000))->set_flags(kspace, 0, PAGE_VALID | PAGE_WRITABLE); + + /* Flush the corresponding TLB entries */ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + +#endif + + /* Set the default IOPBM Bits to the default value */ + + for (int i=0; i < 2048; i++) + ((ptr_t)(iopbm_virt))[i] = IOPBM_DEFAULT_VALUE; + +#if defined(CONFIG_ENABLE_PVI) + /* Enable PVI Bit */ +#warning Setting PVI bit in CR4 will not work with vmware + enable_pvi(); +#endif + + /* Clear lock */ + io_mdb_lock = 0; +} + +/* + * void io_mdb_init_sigma0(); + * + * implicit map of 64k IO-Space to sigma0 on its creation + * (we can't do this during io_mdb_init as no sigma0 exists at this time) + * + */ +void io_mdb_init_sigma0(void){ + + + /* Dummy node */ + io_mnode_t *n = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n->set_values(0, 0, L4_SIGMA0_ID, 0, 1); + + + /* dummy node is beginning of io_space */ + set_iospace(sigma0, n); + + n->parent = NULL; + + io_mnode_t *start = &sigma0_io_space; + io_mnode_t *end = &io_mdb_end; + + /* Setup our initial sigma0-node */ + start->set_values(0, (1<<16), L4_SIGMA0_ID, 0, 0); + start->parent = start; + + /* Setup the IO-MDB Terminator */ + end->set_values(0, 0, L4_SIGMA0_ID, 0, 0); + + + /* Enqueue in Subtree */ + start->next = end; + end->prev = start; + start->prev = end->next = NULL; + + /* Enqueue in Thread List */ + start->prev_st = start->next_st = n; + n->next_st = n->prev_st = start; + + dword_t ufl = get_user_flags(sigma0); + /* Set IOPL to 3 */ + ufl |= (3 << 12); + set_user_flags(sigma0, ufl); +} + + +/* + * void io_mdb_task_new(); + * + * dummy node creation + * implicit map of 64k IO-Space (if configured) + * + */ + +void io_mdb_task_new(tcb_t *pager, tcb_t *task){ + + /* Dummy node */ + io_mnode_t *n = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n->set_values(0, 0, task->myself, 0, 1); + + /* dummy node is beginning of io_space */ + set_iospace(task, n); + + n->next_st = n->prev_st = n; + + n->parent = NULL; + +#if defined(CONFIG_AUTO_IO_MAP) + + /* Create implicit mapping node n_i */ + io_mnode_t *c; + c = get_iospace(pager); + + /* + * Check: + * if the calling task is already protected from accessing IO-Ports, + * the new task will not get access to any ports at all. + */ + + if (c->get_lo() != 0 || c->get_hi() != (1 << 16)) + return; + + io_mnode_t *n_i = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_i == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n_i->set_values(0, (1<<16), task->myself, c->get_depth() + 1, 0); + n_i->parent = n; + + /* Paseeren */ + io_mdb_p(); + + /* Chain in in Subtree */ + n_i->enq_subtree(c); + + /* Verlaaten */ + io_mdb_v(); + + /* Chain in Task List (before n, which is after n) */ + n_i->enq_thread_list(n); + + dump_io_mdb(); + enter_kdebug(); +#endif +} + +/* + * void io_mdb_task_delete(); + * + * removing crap on task deletion + * + * TODO: unmap 64K ! + */ + +void io_mdb_delete_iospace(tcb_t *tcb){ + + + release_iopbm(tcb); + + io_mnode_t *n = get_iospace(tcb); + + if (n == NULL) + return; + + while (!n->get_dummy()){ + n->deq_subtree(); + n = n->next_st; + mdb_free_buffer((ptr_t) n->prev_st, sizeof(io_mnode_t)); + + } + /* Free dummy node */ + mdb_free_buffer((ptr_t) n, sizeof(io_mnode_t)); + + set_iospace(tcb, (io_mnode_t *) NULL); +} + +/* + * int map_io_fpage() + * + * maps an IO-Fpage + * + * returns 0 on success + * -1 on error + */ + +int map_io_fpage(tcb_t *from, tcb_t *to, fpage_t io_fp){ + + io_mnode_t *parent, *dest, *tmp; + dword_t hi, lo; + + if (IOFP_SIZE(io_fp.raw) > (1<<16)){ + printf("map_io_fpage(): wrong size\n"); + return -1; + } + + /* Get mappers and mappees first io node and jump over dummy node */ + parent = get_iospace(from); + dest = get_iospace(to); + + /* paseeren */ + io_mdb_p(); + + + while(!parent->get_dummy()){ + + lo = IOFP_PORT(io_fp.raw); + hi = lo + IOFP_SIZE(io_fp.raw); + + /* is parent an associated mapping node to fpage (i.e. is their intersection not empty) ? */ + if (parent->get_lo() < hi){ + + if (parent->get_hi() > lo){ + + // printf("map_io_fpage(): parent->get_lo = %x, parent->get_hi = + // %x\n",parent->get_lo(), parent->get_hi()); + + + /* Check parents, to avoid recursive mappings */ + for (io_mnode_t *p = parent; p->get_tid().x0id.task != L4_SIGMA0_ID.x0id.task; p = p->parent){ + if (p->get_tid().x0id.task == to->myself.x0id.task){ + printf("map_io_fpage(): no recursive mappings"); + } + break; + } + + + /* Calculate the actual lower and higher bound to map */ + lo = MAX(IOFP_PORT(io_fp.raw), parent->get_lo()); + hi = MIN((IOFP_PORT(io_fp.raw) + IOFP_SIZE(io_fp.raw)), parent->get_hi()); + + /* + * Unmap region out of destination's IO-AS and search for the + * entry of the new mapping + */ + + + while(!dest->get_dummy()){ + if (dest->get_lo() < hi){ + /* Could be that we loose the node, save next */ + tmp = dest->next_st; + if (dest->get_hi() > lo){ + // printf("map_io_fpage: unmap_subtree()\n"); + if (unmap_subtree(dest, lo, hi, FLUSH_OWN_SPACE)){ + printf("map_io_fpage(): unmap_subtree failed\n"); + return -1; + } + } + dest = tmp; + } + else break; + } + + /* The entry of the new mapping node */ + dest = dest->prev_st; + + io_mnode_t *child; + + if (io_fp.fpage.grant){ + /* grant subtree */ + + // printf("map_io_fpage(): grant operation\n"); + if ((child = grant_subtree(parent, dest, to, lo, hi)) == NULL){ + printf("map_io_fpage(): grant_subtree failed\n"); + return -1; + } + + } + + else{ + /* Map */ + + /* Create the mapping */ + child = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (child == NULL){ + panic("map_io_fpage(): out of memory"); + } + + /* Setup child */ + child->set_values(lo, hi, to->myself, parent->get_depth() + 1, 0); + child->parent = parent; + child->enq_subtree(parent); + + /* Hook child into mappees thread list after dest */ + child->enq_thread_list(dest->next_st); + + } + + + /* Zero IOPBM */ + if (zero_iopbm(to, child->get_lo(), child->get_hi() - child->get_lo())){ + printf("map_io_fpage(): zero_iopbm failed\n"); + return -1; + + } + + + } /* if (parent->get_hi() > lo) */ + + /* Next mapping node */ + parent = parent->next_st; + + } /* if (parent->get_lo() < hi) */ + + /* if parent node begins after fpage, done */ + else break; + } + + dump_io_mdb(); + + /* Verlaaten */ + io_mdb_v(); + + return 0; +} +/* + * int unmap_io_fpage() + * + * unmaps an IO-Fpage + * + */ + +void unmap_io_fpage(tcb_t *from, fpage_t io_fp, dword_t mapmask){ + + io_mnode_t *parent, *tmp; + dword_t hi, lo; + + + lo = IOFP_PORT(io_fp.raw); + hi = lo + IOFP_SIZE(io_fp.raw); + + if (IOFP_SIZE(io_fp.raw) > (1<<16)){ + printf("unmap_io_fpage(): wrong size\n"); + return; + } + + + /* Get mappers first io node */ + parent = get_iospace(from); + + // printf("unmap_io_fpage: lo = %x, hi = %x\n", lo, hi); + + /* Paseeren */ + io_mdb_p(); + + while(!parent->get_dummy()){ + + /* is parent an associated mapping node ? */ + if (parent->get_lo() < hi){ + + /* Could be that we loose parent */ + tmp = parent->next_st; + if (parent->get_hi() > lo){ + // printf("unmap_io_fpage: parent->get_lo = %x, parent->get_hi = + // %x\n", parent->get_lo(), parent->get_hi()); + if (unmap_subtree(parent, lo, hi, mapmask)){ + // printf("unmap_io_fpage(): unmap_subtree failed\n"); + return; + } + } + parent = tmp; + } + + else break; + } + + + dump_io_mdb(); + /* Verlaaten */ + io_mdb_v(); + +} + +#endif /* (CONFIG_IO_FLEXPAGES) */ diff --git a/kernel/src/x86/.cvsignore b/kernel/src/x86/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/x86/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/x86/Makefile b/kernel/src/x86/Makefile new file mode 100644 index 0000000..7f1ab5e --- /dev/null +++ b/kernel/src/x86/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 200, 2001, Karlsruhe University +## +## File path: x86/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.20 2002/05/13 13:04:30 stoess Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libarch.a +OBJ_SRC = +LIB_SRC = init.c exception.S memory.c resources.c interrupt.c \ + io_mapping.c smp.c smpipc.c smp-boot.S + +###################################################################### +# includes +include ../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/x86/exception.S b/kernel/src/x86/exception.S new file mode 100755 index 0000000..7c222cc --- /dev/null +++ b/kernel/src/x86/exception.S @@ -0,0 +1,1105 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: x86/exception.S + * Description: Syscall and interrupt/exception entry points for the + * x86. + * + * @LICENSE@ + * + * $Id: exception.S,v 1.67 2002/05/13 15:52:30 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#include +#include +#include + +#if (__GNUC__ >= 3) +# define SYS_IPC _Z7sys_ipc13l4_threadid_tjj +# define SYS_ID_NEAREST _Z14sys_id_nearest13l4_threadid_t +# define SYS_LTHREAD_EX_REGS _Z19sys_lthread_ex_regsjjj13l4_threadid_t +# define SYS_SCHEDULE _Z12sys_schedule16schedule_param_t13l4_threadid_t +# define SYS_THREAD_SWITCH _Z17sys_thread_switch13l4_threadid_t +# define SYS_TASK_NEW _Z12sys_task_new13l4_threadid_tjS_jj +# define SYS_FPAGE_UNMAP _Z15sys_fpage_unmap7fpage_tj + +# define EXCEPTION_HANDLER _Z17exception_handlerP17exception_frame_t +# define IRQ_HANDLER _Z11irq_handlerP17exception_frame_t +# define TIMER_IRQ_HANDLER _Z17timer_irq_handlerP17exception_frame_t +# define PAGEFAULT_HANDLER _Z9pagefaultjjjjj + +# define ABORT_IPC _Z9abort_ipcv +# define SWITCH_TO_ROOTTASK _Z18switch_to_roottaskv +# define SWITCH_TO_SIGMA0 _Z16switch_to_sigma0v +# define SWITCH_TO_USER _Z14switch_to_userv + +#define APIC_HANDLER_LINT0 _Z18apic_handler_lint0v +#define APIC_HANDLER_LINT1 _Z18apic_handler_lint1v +#define APIC_HANDLER_ERROR _Z18apic_handler_errorv +#define APIC_HANDLER_SPURIOUS _Z25apic_handler_spurious_intv +#define APIC_HANDLER_PERFCTR _Z20apic_handler_perfctrjPj +#define HANDLE_PERFCTR_BOUNCE _Z26handle_perfctr_bounce_backP17exception_frame_t +#define SMP_HANDLER_COMMAND_IPI _Z23smp_handler_command_ipiv + +#else /* __GNUC__ < 3 */ + +# define SYS_IPC sys_ipc__FG13l4_threadid_tUiUi +# define SYS_ID_NEAREST sys_id_nearest__FG13l4_threadid_t +# define SYS_LTHREAD_EX_REGS sys_lthread_ex_regs__FUiUiUiG13l4_threadid_t +# define SYS_SCHEDULE sys_schedule__FG16schedule_param_tG13l4_threadid_t +# define SYS_THREAD_SWITCH sys_thread_switch__FG13l4_threadid_t +# define SYS_TASK_NEW sys_task_new__FG13l4_threadid_tUiT0UiUi +# define SYS_FPAGE_UNMAP sys_fpage_unmap__FG7fpage_tUi + +# define EXCEPTION_HANDLER exception_handler__FP17exception_frame_t +# define IRQ_HANDLER irq_handler__FP17exception_frame_t +# define TIMER_IRQ_HANDLER timer_irq_handler__FP17exception_frame_t +# define PAGEFAULT_HANDLER pagefault__FUiUiUiUiUi + +# define ABORT_IPC abort_ipc__Fv +# define SWITCH_TO_ROOTTASK switch_to_roottask__Fv +# define SWITCH_TO_SIGMA0 switch_to_sigma0__Fv +# define SWITCH_TO_USER switch_to_user__Fv + +#define APIC_HANDLER_LINT0 apic_handler_lint0__Fv +#define APIC_HANDLER_LINT1 apic_handler_lint1__Fv +#define APIC_HANDLER_ERROR apic_handler_error__Fv +#define APIC_HANDLER_SPURIOUS apic_handler_spurious_int__Fv +#define APIC_HANDLER_PERFCTR apic_handler_perfctr__FUiPUi +#define HANDLE_PERFCTR_BOUNCE handle_perfctr_bounce_back__FP17exception_frame_t +#define SMP_HANDLER_COMMAND_IPI smp_handler_command_ipi__Fv +#endif + +#if defined(CONFIG_USERMODE_NOIRQ) +# define MAYBE_STI +#else +# define MAYBE_STI sti +#endif + +#if defined(CONFIG_MEASURE_INT_LATENCY) +# define STORE_TIME \ + mov 0xf00f0390, %eax ;\ + mov %eax, interrupted_time ;\ + rdtsc ;\ + mov %eax, interrupted_rdtsc + + .data + .align 16 + .globl interrupted_rdtsc + .globl interrupted_time +interrupted_rdtsc: .long 0 +interrupted_time: .long 0 + .text + +#else +# define STORE_TIME +#endif + +#if defined(CONFIG_ENABLE_SMALL_AS) +#define set_kds(_reg) \ + mov $X86_KDS, %_reg ;\ + mov %_reg, %ds + +#define reset_ds(_num) \ + mov _num(%esp), %eax ;\ + add $0x8, %eax ;\ + mov %eax, %ds + +#define set_uds(_reg) \ + mov $X86_UDS, %_reg ;\ + mov %_reg, %ds +#else +#define set_kds(_reg) +#define reset_ds(_num) +#define set_uds(_reg) +#endif + +#if defined(CONFIG_KEEP_LAST_BRANCHES) +#define clr_dbgctl_lbr() \ + mov $0x1d9, %ecx ; \ + rdmsr ; \ + andl $0xfffffffe, %eax ; \ + wrmsr + +#define set_dbgctl_lbr() \ + mov $0x1d9, %ecx ; \ + rdmsr ; \ + orl $0x1, %eax ; \ + wrmsr +#else +#define clr_dbgctl_lbr() +#define set_dbgctl_lbr() +#endif + + +#define ke(text) \ + int $3 ; \ + jmp 1f ; \ + .ascii text ; \ +1: + +#define ENTRY(name) \ + .globl name; \ + .p2align 4; \ + name##: + +#define EXCEPTION_EC(num)\ + pusha;\ + pushl %ds;\ + pushl %es;\ + set_kds(eax);\ + pushl $##num;\ + pushl %esp;\ + clr_dbgctl_lbr();\ + call EXCEPTION_HANDLER;\ + set_dbgctl_lbr();\ + addl $8, %esp;\ + popl %es;\ + popl %ds;\ + popa;\ + addl $4, %esp;\ + iret + + +#define DEF_EXC_EC(num, entry) \ + ENTRY(entry) EXCEPTION_EC(num) + +#define EXCEPTION(num)\ + pushl $0;\ + pusha;\ + pushl %ds;\ + pushl %es;\ + set_kds(eax);\ + pushl $##num;\ + pushl %esp;\ + clr_dbgctl_lbr();\ + call EXCEPTION_HANDLER;\ + set_dbgctl_lbr();\ + addl $8, %esp;\ + popl %es;\ + popl %ds;\ + popa;\ + addl $4, %esp;\ + iret + + +#define DEF_EXC(num, entry) \ + ENTRY(entry) EXCEPTION(num) + +#define APIC_SMP_CMD_ENTRY \ + ENTRY(apic_smp_command_ipi)\ + pusha;\ + set_kds(eax);\ + call SMP_HANDLER_COMMAND_IPI;\ + reset_ds(36);\ + popa;\ + iret + +#define DEF_INTR(num) \ + ENTRY(hwintr_##num) ; \ + pushl $0 ; \ + pusha ; \ + pushl %ds ; \ + pushl %es ; \ + set_kds(eax) ; \ + STORE_TIME ; \ + pushl $##num ; \ + pushl %esp ; \ + call IRQ_HANDLER ; \ + addl $8, %esp ; \ + popl %es ; \ + popl %ds ; \ + popa ; \ + addl $4, %esp ; \ + iret + +.text + +DEF_EXC(0, int_0) +DEF_EXC(4, int_4) +DEF_EXC(5, int_5) +DEF_EXC(6, int_6) +DEF_EXC(7, int_7) +DEF_EXC_EC(8, int_8) +DEF_EXC(9, int_9) +DEF_EXC_EC(10, int_10) +DEF_EXC_EC(11, int_11) +DEF_EXC_EC(12, int_12) +DEF_EXC(16, int_16) +DEF_EXC_EC(17, int_17) +DEF_EXC_EC(18, int_18) +DEF_EXC(19, int_19) + +DEF_INTR(0) +DEF_INTR(1) +DEF_INTR(2) +DEF_INTR(3) +DEF_INTR(4) +DEF_INTR(5) +DEF_INTR(6) +DEF_INTR(7) +DEF_INTR(8) +DEF_INTR(9) +DEF_INTR(10) +DEF_INTR(11) +DEF_INTR(12) +DEF_INTR(13) +DEF_INTR(14) +DEF_INTR(15) + + +ENTRY(int_13) + pusha + pushl %ds + pushl %es + set_kds(eax) + pushl $13 + pushl %esp + clr_dbgctl_lbr() + call EXCEPTION_HANDLER + set_dbgctl_lbr() + addl $8, %esp + popl %es + popl %ds + popa + addl $4, %esp + iret + +ENTRY(int_14) + /* At this point we have the standard exception frame with an error + code on our stack. We need only the error code and the instruction + pointer in the pagefault handler. But we have to save eax, ecx and + edx because the called C function would clobber them. Thus we have + three more arguments for the pagefault handling function (that are + ignored): + + void pagefault(dword_t edx, dword_t ecx, dword_t eax, + dword_t errcode, dword_t ip); + */ + pushl %eax + pushl %ecx + pushl %edx + set_kds(eax) + clr_dbgctl_lbr() + call PAGEFAULT_HANDLER + set_dbgctl_lbr() + reset_ds(20) + popl %edx + popl %ecx + popl %eax + addl $4, %esp + iret +ENTRY(timer_irq) + pushl $0 + pusha + pushl %ds + pushl %es + set_kds(eax) + pushl $0 + pushl %esp + call TIMER_IRQ_HANDLER + addl $8, %esp + popl %es + popl %ds + popa + addl $4, %esp + iret + +#ifdef CONFIG_X86_APIC +ENTRY(apic_lint0) + pusha + set_kds(eax) + call APIC_HANDLER_LINT0 + reset_ds(36) + popa + iret + +ENTRY(apic_lint1) + pusha + set_kds(eax) + call APIC_HANDLER_LINT1 + reset_ds(36) + popa + iret + +ENTRY(apic_error) + pusha + set_kds(eax) + call APIC_HANDLER_ERROR + reset_ds(36) + popa + iret + +ENTRY(apic_spurious_int) + pusha + set_kds(eax) + call APIC_HANDLER_SPURIOUS + reset_ds(36) + popa + iret + + +#if defined(CONFIG_ENABLE_PROFILING) +ENTRY(apic_perfctr) + pusha + pushl %ds + pushl %es + set_kds(eax) + lea 48(%esp), %eax // EFlags + push %eax + push 44(%esp) // Fault address + call APIC_HANDLER_PERFCTR + addl $8, %esp + popl %es + popl %ds + popa + iret + +ENTRY(perfctr_bounce_back) + pushl $0x0 // Error code + pusha + pushl %ds + pushl %es + set_kds(eax) + pushl $0x0 // Fault code + pushl %esp + call HANDLE_PERFCTR_BOUNCE + addl $8, %esp + popl %es + popl %ds + popa + addl $4, %esp + iret +#endif /* CONFIG_ENABLE_PROFILING */ + +#endif /* CONFIG_X86_APIC */ + +#if defined(CONFIG_SMP) +/* entry point for smp command IPIs */ +APIC_SMP_CMD_ENTRY +#endif + +/* syscalls */ + + .section .ipc-s +/* + ipc + precondition: + snd_desc: eax + timeout: ecx + msg_w0: edx + msg_w1: ebx + msg_w2: edi + rcv_desc: ebp + dest: esi + + postcondition + msg_dope: eax + msg_w0: edx + msg_w1: ebx + msg_w2: edi + source: esi +*/ +ENTRY(int_48) + pushl %ebp + pushl %eax + pushl %esi + set_kds(ebp) + +#if 0 + /* save registers into tcb */ + lea -L4_TOTAL_TCB_SIZE+12+24+16(%esp), %esp + pushl %ecx + pushl %edi + pushl %ebx + pushl %edx + lea L4_TOTAL_TCB_SIZE-12-24(%esp), %esp + call SYS_IPC + addl $12, %esp +#else + /* save registers into tcb */ + movl %esp, %eax + andl $L4_TCB_MASK, %eax + movl %edx, 0(%eax) + movl %ebx, 4(%eax) + movl %edi, 8(%eax) + movl %ecx, 12(%eax) + call SYS_IPC + addl $12, %esp +#endif + + set_uds(ebp) + iret + +#if defined(CONFIG_IA32_FEATURE_SEP) +/* + ipc + precondition: + snd_desc: eax + msg_w0: edx + msg_w1: ebx + msg_w2: edi + dest: esi + user sp: ecx + timeout: (ecx+0x0c) + rcv_desc: (ecx+0x08) + user ip: (ecx+0x00) + + postcondition + msg_dope: eax + msg_w0: edx + msg_w1: ebx + msg_w2: edi + source: esi +*/ + + +/* + * Define to create a full interrupt stack frame upon sysenter. +*/ +//#define CREATE_STACKFRAME + +/* + * Define to enable possibly slightly faster code which is not safe to + * be preempted (e.g., profiled) due to strange ESP usage. + */ +//#define PREEMPTION_UNSAFE_CODE + + +#if defined(CONFIG_ENABLE_SMALL_AS) + +/* +** +** ================================================== +** SYSENTER/SYSEXIT IPC CODE FOR SMALL ADDRESS SPACES +** ================================================== +** +*/ + .globl return_from_sys_ipc_small + +ENTRY(ipc_sysenter_small) + popl %esp + +#if defined(CREATE_STACKFRAME) + pushl $X86_UDS /* User SS */ + pushl %ecx /* User ESP */ + pushl $0x00 /* User EFlags */ + pushl $X86_UCS /* User CS */ + pushl (%ecx) /* User EIP */ +#else + subl $4, %esp + pushl %ecx /* User ESP */ + subl $8, %esp + pushl (%ecx) /* User EIP */ +#endif + + pushl 8(%ecx) /* rcv desc */ + pushl %eax /* snd desc */ + pushl %esi /* dest id */ + movl 12(%ecx), %ecx + +#if defined(CONFIG_IPC_FASTPATH) + + /* + * Fastpath IPC code + */ + +#define L4_TIDTCB_MASK 0xE0FFFC00 +#define L4_TASK_MASK 0x00FF0000 +#define to_tcb %eax +#define current %ebp + + orl %ebp, %eax /* eax = snd_desc | rcv_desc */ + orl %ecx, %eax /* eax = snd_desc | rcv_desc | timeout */ + + /* + * If have no snd_desc, no rcv_desc, and no timeout it means that + * we have a short send, short receive, timeout never IPC (i.e., + * fastpath IPC). + */ + jne ipc_slowpath_to_small + + /* Calculate TCB address of sender and receiver. */ + movl %esi, to_tcb + orl $TCB_AREA, to_tcb + andl $L4_TIDTCB_MASK, to_tcb + movl %ss:OFS_TCB_MYSELF(to_tcb), %ecx // Load in advance + mov %esp, current + andl $L4_TCB_MASK, current + + /* Check if destination is valid (to_tcb->mysels == dest). */ + cmpl %ecx, %esi + jne ipc_slowpath_small + + /* + * Check: - Is destination WAITING? + * - Is destination handling an IPC copy pagefault? + * - Does destination require any resources? + * - Do we have have an interrupt pending? + */ + movl %ss:OFS_TCB_THREAD_STATE(to_tcb), %ecx + add $1, %ecx + orl %ss:OFS_TCB_UNWIND_IPC_SP(to_tcb), %ecx + orl %ss:OFS_TCB_RESOURCES(to_tcb), %ecx + orl %ss:OFS_TCB_INTR_PENDING(current), %ecx + jne ipc_slowpath_small + + /* Does destination perform an open-wait (to_tcb->partner == 0). */ + orl %ss:OFS_TCB_PARTNER(to_tcb), %ecx + je 1f + + /* Does destination wait for us (to_tcb->partner == myself). */ + cmpl %ss:OFS_TCB_MYSELF(current), %ecx + jne ipc_slowpath_small + +1: /* + * If we reach this point we're performing the fastpath IPC. + */ + + /* Set current->partner = dest */ + movl %esi, %ss:OFS_TCB_PARTNER(current) + + /* Set current->msg_desc = 0 */ + xorl %esi, %esi + movl %esi, %ss:OFS_TCB_MSG_DESC(current) + + /* Set current->state = WAITING, to_tcb->state = RUNNING */ + subl $1, %esi + movl %esi, %ss:OFS_TCB_THREAD_STATE(current) + movl $6, %ss:OFS_TCB_THREAD_STATE(to_tcb) + + /* Create stack frame to use if slow path IPC is used for reply. */ + pushl $ipc_fastpath_ret_small + movl %esp, %ss:OFS_TCB_STACK(current) + + /* Set the SOURCE return parameter of receiver. */ + movl %ss:OFS_TCB_MYSELF(current), %esi + + /* Calculate stack top of destination thread. */ + leal %ss:L4_TOTAL_TCB_SIZE-4(to_tcb), %esp + + /* Check if sender and receiver reside in same task. */ + xorl to_tcb, current + testl $L4_TASK_MASK, current + je 5f + + /* Check small space ID of target thread (from inside pagedir). */ + movl %ss:OFS_TCB_SPACE(to_tcb), %ecx + addl $(KERNEL_OFFSET + SPACE_ID_IDX*4), %ecx + movl %ss:(%ecx), %eax + movl %ss:__is_small, %ebp + cmpb $0xff, %al + je 3f + + testl %ebp, %ebp + jne 2f + movl $1, %ss:__is_small + +2: /* Get segment descriptors from within page directory. */ + movl %ss:4(%ecx), %eax + movl %ss:8(%ecx), %ecx + + /* Reload segment descriptior table. */ +#if !defined(PREEMPTION_UNSAFE_CODE) + movl $gdt, %ebp + movl %eax, %ss:32(%ebp) + movl %ecx, %ss:36(%ebp) + orl $0x800, %ecx + movl %eax, %ss:24(%ebp) + movl %ecx, %ss:28(%ebp) +#else + movl %esp, %ebp + movl $(gdt+40), %esp + pushl %ecx + pushl %eax + orl $0x800, %ecx + pushl %ecx + pushl %eax + movl %ebp, %esp +#endif + + /* Reload segment selectors. */ + movl $X86_UDS, %ecx + mov %ecx, %ds + mov %ecx, %es + mov %ecx, %fs + mov %ecx, %gs + jmp 5f + +3: /* Check if we previously ran in a small space. */ + movl %ss:__is_small, %ebp + testl %ebp, %ebp + je 4f + + /* Reload 3GB segment descriptors. */ +#if !defined(PREEMPTION_UNSAFE_CODE) + movl $gdt, %ebp + movl $0x0000ffff, %ss:24(%ebp) + movl $0x00cbfb00, %ss:28(%ebp) + movl $0x0000ffff, %ss:32(%ebp) + movl $0x00cbf300, %ss:36(%ebp) +#else + movl %esp, %ebp + movl $(gdt+40), %esp + pushl $0x00cbf300 + pushl $0x0000ffff + pushl $0x00cbfb00 + pushl $0x0000ffff + movl %ebp, %esp +#endif + + /* Reload segment selectors. */ + movl $X86_UDS, %ecx + mov %ecx, %ds + mov %ecx, %es + mov %ecx, %fs + mov %ecx, %gs + + /* Reload page directory pointer. */ +4: movl OFS_TCB_PAGEDIR_CACHE-L4_TOTAL_TCB_SIZE+4(%esp), %ecx + movl %ecx, %cr3 + movl $0, %ss:__is_small + +5: /* Reload esp0 in TSS. */ + movl %esp, %ss:__tss + 4 + + movl -8(%esp), %ecx /* User ESP */ + movl %edx, %ebp /* Save msg.w0 */ + lea sysexit_tramp_keepds, %edx /* EIP for trampoline */ + xorl %eax, %eax /* Return value */ + sysexit + +ipc_slowpath_small: + xorl %ecx, %ecx /* Restore timeout value. */ + +ipc_slowpath_to_small: +#endif /* CONFIG_IPC_FASTPATH */ + + set_kds(eax) /* It is now safe to set kernel ds */ + + /* Save registers into tcb */ + movl %esp, %eax + andl $L4_TCB_MASK, %eax + movl %edx, 0(%eax) /* dw0 */ + movl %ebx, 4(%eax) /* dw1 */ + movl %edi, 8(%eax) /* dw2 */ + movl %ecx, 12(%eax) /* timeout */ + + call SYS_IPC +return_from_sys_ipc_small: + + movl 24(%esp), %ecx /* User ESP */ + movl %edx, %ebp /* Save msg.w0 */ + lea sysexit_tramp, %edx /* EIP for trampoline */ + sysexit + + /* should never be reached */ + ke("ipc_sysenter fell off") + # does not return + +#if defined(CONFIG_IPC_FASTPATH) +ipc_fastpath_ret_small: + movl %esp, %ecx + andl $L4_TIDTCB_MASK, %ecx + movl $6, OFS_TCB_THREAD_STATE(%ecx) /* set to running */ + movl OFS_TCB_IPC_BUFFER+0(%ecx), %ebp /* dw0 */ + movl OFS_TCB_IPC_BUFFER+4(%ecx), %ebx /* dw1 */ + movl OFS_TCB_IPC_BUFFER+8(%ecx), %edi /* dw2 */ + movl OFS_TCB_MSG_DESC(%ecx), %eax /* msg_desc */ + movl OFS_TCB_PARTNER(%ecx), %esi /* set sender */ + addl $L4_TOTAL_TCB_SIZE - 4, %ecx + + movl 24(%esp), %ecx /* User ESP */ + movl %edx, %ebp /* Save msg.w0 */ + lea sysexit_tramp, %edx /* EIP for trampoline */ + sysexit +#endif /* CONFIG_IPC_FASTPATH */ + + /* + * Trampoline for entering userlevel in a safe manner. + */ + .section .utramp, "ax", @progbits + .type sysexit_tramp, @function + .globl sysexit_tramp +sysexit_tramp: + movl %ebp, %edx /* Restore msg.w0 */ + movl $X86_UDS, %ebp + mov %ebp, %ds + mov %ebp, %ss + MAYBE_STI + lret $8 + +#if defined(CONFIG_IPC_FASTPATH) + .p2align 4 + .type sysexit_tramp_keepds, @function + .globl sysexit_tramp_keepds +sysexit_tramp_keepds: + movl %ebp, %edx /* Restore msg.w0 */ + movl $X86_UDS, %ebp + mov %ebp, %ss + MAYBE_STI + lret $8 +#endif /* CONFIG_IPC_FASTPATH */ + + + /* + * If we caught a GP doing the LRET instruction (i.e., invalid + * code segment) we return through an IRET which sets the proper + * code segment. If we got a pagefault during the LRET, the IRET + * back into the trampoline will fail because it is not accessible + * with CS=0x1b. In both cases we reenter user-level through this + * stub. + */ + .p2align 4 + .globl reenter_sysexit +reenter_sysexit: + set_uds(ebp) + movl (%ecx), %ebp /* Get EIP */ + addl $16, %ecx /* Adjust for user ESP */ + + pushl $X86_UDS /* User SS */ + pushl %ecx /* User ESP */ + pushl $X86_USER_FLAGS /* User EFlags */ + pushl $X86_UCS /* User CS */ + pushl %ebp /* User EIP */ + iret + + .previous +#endif /* CONFIG_ENABLE_SMALL_AS */ + + .globl return_from_sys_ipc + + + + +/* +** +** ================================================== +** SYSENTER/SYSEXIT IPC CODE FOR LARGE ADDRESS SPACES +** ================================================== +** +*/ + +ENTRY(ipc_sysenter) + mov (%esp),%esp + +#if defined(CREATE_STACKFRAME) + pushl $X86_UDS /* User SS */ + pushl %ecx /* User ESP */ + pushl $0x00 /* User EFlags */ + pushl $X86_UCS /* User CS */ + pushl (%ecx) /* User EIP */ +#else + subl $4, %esp + pushl %ecx /* User ESP */ + subl $8, %esp + pushl (%ecx) /* User EIP */ +#endif + + pushl 8(%ecx) /* rcv desc */ + pushl %eax /* snd desc */ + pushl %esi /* dest id */ + movl 12(%ecx),%ecx + +#if defined(CONFIG_IPC_FASTPATH) + +#define L4_TIDTCB_MASK 0xE0FFFC00 +#define to_tcb %eax +#define current %ebp + + orl %ebp, %eax /* eax = snd_desc | rcv_desc */ + orl %ecx, %eax /* eax = snd_desc | rcv_desc | timeout */ + + /* + * If have no snd_desc, no rcv_desc, and no timeout it means that + * we have a short send, short receive, timeout never IPC (i.e., + * fastpath IPC). + */ + jne ipc_slowpath_to + + /* Calculate TCB address of sender and receiver. */ + movl %esi, to_tcb + orl $TCB_AREA, to_tcb + andl $L4_TIDTCB_MASK, to_tcb + mov %esp, current + andl $L4_TCB_MASK, current + + cmpl OFS_TCB_MYSELF(to_tcb), %esi + jne ipc_slowpath /* to_tcb->myself != dest */ + movl OFS_TCB_THREAD_STATE(to_tcb), %ecx + add $1,%ecx + orl OFS_TCB_UNWIND_IPC_SP(to_tcb),%ecx + orl OFS_TCB_RESOURCES(to_tcb),%ecx + orl OFS_TCB_INTR_PENDING(current), %ecx + jne ipc_slowpath /* ! waiting */ + + /* COND: ecx == 0 */ + orl OFS_TCB_PARTNER(to_tcb), %ecx /* to_tcb->partner -> ecx */ + je 1f /* open wait */ + cmpl OFS_TCB_MYSELF(current), %ecx + jne ipc_slowpath /* to_tcb->partner != myself */ + /* if we reach that point we perform the fast ipc */ +1: + movl %esi,OFS_TCB_PARTNER(current) /* current->partner = dest */ + xorl %esi,%esi + movl %esi,OFS_TCB_MSG_DESC(current) /* current->msg_desc = 0 */ + subl $1,%esi + movl %esi,OFS_TCB_THREAD_STATE(current) /* cur->state = WAITING */ + movl $6,OFS_TCB_THREAD_STATE(to_tcb) /* to_tcb->state = RUNNING */ + + /* create "nice" stack frame for slow path switch */ + pushl $ipc_fastpath_ret + movl %esp, OFS_TCB_STACK(current) /* save stack */ + + movl OFS_TCB_MYSELF(current),%esi /* set sender */ + xorl %eax,%ebp + testl $0xFF0000,%ebp /* same X.0 task ? */ + je 2f + movl OFS_TCB_SPACE(to_tcb), %ecx + /* switch pagetable */ + movl %ecx, %cr3 +2: + + /* we don't care about the other guys stack :) */ + addl $L4_TOTAL_TCB_SIZE - 4, %eax + movl %eax, __tss + 4 + movl %edx,%ebp /* save dw0 around sysexit */ + movl -8(%eax),%ecx /* user esp */ + movl -20(%eax),%edx /* user eip */ + addl $16, %ecx + subl $2,%edx + subl %eax,%eax + sti + sysexit + +ipc_slowpath: + xorl %ecx,%ecx /* restore timeout */ +ipc_slowpath_to: +#endif /* CONFIG_IPC_FASTPATH */ + + /* Save registers into tcb */ + movl %esp, %eax + andl $L4_TCB_MASK, %eax + movl %edx, 0(%eax) /* dw0 */ + movl %ebx, 4(%eax) /* dw1 */ + movl %edi, 8(%eax) /* dw2 */ + movl %ecx, 12(%eax) /* timeout */ + + call SYS_IPC +return_from_sys_ipc: + mov %edx,%ebp + + movl 24(%esp), %ecx + movl 12(%esp), %edx + addl $16, %ecx + subl $2, %edx /* Adjust for the ebp->edx instruction. */ + MAYBE_STI /* Fake POPF. Interrupts will still be + disabled during the SYSEXIT instruction. */ + + /* + * We usually run on UDS when doing SYSEXIT. Only when we have a + * pagefault during IPC will we run with KDS (int_14 will reset + * %ds according to the value of %cs on the iframe). This will + * result in running with CPL=3, RPL=3, and DPL=0 upon returning + * to user-level. Such behavior, however, is not allowed by the + * architecture, and is prevented by 1) doing proper privilege + * checks upon segment register reloading, and 2) having the IRET + * instruction enforce non-valid data segment registers (i.e., + * segment registers with DPL <= than both CPL and RPL) to get + * a zero value. + * + * For the SYSEXIT instruction the story is somewhat different + * and is not documented in the Intel specifications. A SYSEXIT + * instruction will not enforce a zero value into any segment + * registers. It will instead magically load the correct value + * (the same as %ss) into the register one instruction after + * returning to user-level. The instruction which is executed + * with the wrong segment register values will still have internally + * correct values (i.e., DPLs set to 3). + * + * The IPC path here works fine for most cases. Only when we + * run with a small space kernel, no small spaces have yet been + * created, we do a sysenter long IPC, catch a pagefault during + * IPC copy, return to user-level, and is interrupted on the first + * instruction do we have a problem. This will cause KDS value + * to visible in the %ds upon kernel entry, pushed on the stack, + * popped off the stack before IRET, and the zero value to be + * enforced into %ds. Next time any data is accessed through %ds, + * we will catch a GP(0). See interrupt.c for the handling of + * this exception. + */ + sysexit + + /* Should never be reached. */ + ke("ipc_sysenter fell off") + # does not return + +#if defined(CONFIG_IPC_FASTPATH) +ipc_fastpath_ret: + movl %esp, %ecx + andl $L4_TIDTCB_MASK, %ecx + movl $6, OFS_TCB_THREAD_STATE(%ecx) /* set to running */ + movl OFS_TCB_IPC_BUFFER+0(%ecx), %ebp /* dw0 */ + movl OFS_TCB_IPC_BUFFER+4(%ecx), %ebx /* dw1 */ + movl OFS_TCB_IPC_BUFFER+8(%ecx), %edi /* dw2 */ + movl OFS_TCB_MSG_DESC(%ecx), %eax /* msg_desc */ + movl OFS_TCB_PARTNER(%ecx), %esi /* set sender */ + addl $L4_TOTAL_TCB_SIZE - 4, %ecx + movl -20(%ecx), %edx /* user eip */ + movl -8(%ecx), %ecx /* user esp */ + addl $16, %ecx + subl $2, %edx + sti + sysexit +#endif /* CONFIG_IPC_FASTPATH */ + + /* + * Alternate exit stub used if some thread did an ex_regs on us + * before we returned to user-level. Needed because the ex_regs + * possibly changed the the user-esp to something not containing + * a proper return address. + */ + .globl alternate_sys_ipc_return +alternate_sys_ipc_return: + addl $12, %esp + movl $X86_UCS, 4(%esp) + movl $X86_USER_FLAGS, 8(%esp) + movl $X86_UDS, 16(%esp) + set_uds(ebp) + iret + + +#endif /* defined(CONFIG_IA32_FEATURE_SEP) */ + .text + + +ENTRY(int_49) + pushl %esi + set_kds(eax) + call SYS_ID_NEAREST + ke("sys_id_nearest returned") + # does not return + +ENTRY(int_50) + pushl %ecx + pushl %eax + set_kds(eax) + call SYS_FPAGE_UNMAP + addl $8, %esp + set_uds(edx) + iret + +ENTRY(int_51) + pushl %esi + set_kds(eax) + call SYS_THREAD_SWITCH + ke("sys_thread_switch returned") + # does not return + +ENTRY(int_52) + pushl %esi + pushl %eax + set_kds(eax) + call SYS_SCHEDULE + ke("sys_schedule returned") + # does not return + +/* + lthread_ex_regs + precondition: + tid: eax + esp: ecx + eip: edx + pager: esi + + postcondition: + tid: eax + esp: ecx + eip: edx + pager: esi +*/ +ENTRY(int_53) + pushl %esi + pushl %ecx + pushl %edx + pushl %eax + set_kds(eax) + call SYS_LTHREAD_EX_REGS + # does not return + +/* + create_thread + precondition: + master: eax + esp: ecx + eip: edx + pager: ebx + tid: esi + + postcondition: + none yet +*/ +ENTRY(int_54) + pushl %ecx + pushl %edx + pushl %ebx + pushl %eax + pushl %esi + set_kds(eax) + call SYS_TASK_NEW + + + + +ENTRY(ABORT_IPC) + set_uds(eax) + /* load the ipc error code into eax */ + popl %eax + iret + +ENTRY(SWITCH_TO_ROOTTASK) + mov $X86_UDS, %eax + mov %ax, %ds + mov %ax, %es + mov %ax, %gs +#if defined(CONFIG_TRACEBUFFER) + mov $X86_TBS, %eax +#endif + mov %ax, %fs + + /* load the address of the multiboot info structure into ebx */ + popl %ebx + /* this signals a valid mbi address in eax */ + movl $0x2BADB002,%eax + iret + +ENTRY(SWITCH_TO_SIGMA0) + mov $X86_UDS, %eax + mov %ax, %ds + mov %ax, %es + mov %ax, %gs +#if defined(CONFIG_TRACEBUFFER) + mov $X86_TBS, %eax +#endif + mov %ax, %fs + /* load the address of the kernel_info_page into eax */ + popl %eax + subl $KERNEL_OFFSET, %eax + iret + +/* this is the general entry point for all user threads */ +ENTRY(SWITCH_TO_USER) + mov $X86_UDS, %eax + mov %ax, %ds + mov %ax, %es + mov %ax, %gs +#if defined(CONFIG_TRACEBUFFER) + mov $X86_TBS, %eax +#endif + mov %ax, %fs + addl $4, %esp + iret diff --git a/kernel/src/x86/exception.o b/kernel/src/x86/exception.o new file mode 100644 index 0000000..2f090eb Binary files /dev/null and b/kernel/src/x86/exception.o differ diff --git a/kernel/src/x86/i586/.cvsignore b/kernel/src/x86/i586/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/x86/i586/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/x86/i586/Makefile b/kernel/src/x86/i586/Makefile new file mode 100644 index 0000000..ad12f53 --- /dev/null +++ b/kernel/src/x86/i586/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: x86/i586/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.6 2001/11/22 13:39:07 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = null.S + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/x86/i586/null.S b/kernel/src/x86/i586/null.S new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/x86/i586/startup.S b/kernel/src/x86/i586/startup.S new file mode 100644 index 0000000..e357ad3 --- /dev/null +++ b/kernel/src/x86/i586/startup.S @@ -0,0 +1,67 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/i586/startup.S + * Description: Startup code for Pentium family processors. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.16 2001/11/22 13:39:07 skoglund Exp $ + * + ********************************************************************/ +.globl _start +.section .init + +#include +#include +#include + +#if (__GNUC__ >= 3) +# define INIT_PAGING _Z11init_pagingv +# define INIT _Z4initv +#else +# define INIT_PAGING init_paging__Fv +# define INIT init__Fv +#endif + +_start: + /* Save the multiboot info structure pointer (ebx) to physical + address of kernel_arg. We assume that the kernel IS multibooted. + This value is later on passed to the root task */ + /* UD: Actually, we should save the mbi flags as well - just for the + case where we AREN'T multibooted. */ + movl %ebx, kernel_arg - KERNEL_OFFSET + cli /* disable int's */ + cld /* clear direction flag */ + mov %ds, %ax + mov %ax, %es + mov %ax, %fs + jmp 1f +1: + nop + nop + mov %ax, %gs + mov %ax, %ss + + /* load temporary stack pointer */ + lea _mini_stack-4, %esp + /* set up paging */ + call INIT_PAGING + + + /* still running in 1:1 mapped area + jump to the top level init function */ + jmp INIT + + + .space 1024 + .globl _mini_stack +_mini_stack: + + .section .mb_header + .align 4 +_mb_header: + .long 0x1BADB002 /* magic */ + .long 0x00000000 /* flags */ + .long - 0x00000000 - 0x1BADB002 /* check */ diff --git a/kernel/src/x86/i686/.cvsignore b/kernel/src/x86/i686/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/x86/i686/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/x86/i686/Makefile b/kernel/src/x86/i686/Makefile new file mode 100644 index 0000000..c1eb830 --- /dev/null +++ b/kernel/src/x86/i686/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: x86/i686/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.6 2001/11/22 13:39:08 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = null.S + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/x86/i686/libplatform.a b/kernel/src/x86/i686/libplatform.a new file mode 100644 index 0000000..2ebb5dc Binary files /dev/null and b/kernel/src/x86/i686/libplatform.a differ diff --git a/kernel/src/x86/i686/null.S b/kernel/src/x86/i686/null.S new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/x86/i686/null.o b/kernel/src/x86/i686/null.o new file mode 100644 index 0000000..d01b653 Binary files /dev/null and b/kernel/src/x86/i686/null.o differ diff --git a/kernel/src/x86/i686/startup.S b/kernel/src/x86/i686/startup.S new file mode 100644 index 0000000..eb9a2fe --- /dev/null +++ b/kernel/src/x86/i686/startup.S @@ -0,0 +1,67 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/i686/startup.S + * Description: Startup code for PentiumPro family processors. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.20 2001/11/22 13:39:08 skoglund Exp $ + * + ********************************************************************/ +.globl _start +.section .init + +#include +#include +#include + +#if (__GNUC__ >= 3) +# define INIT_PAGING _Z11init_pagingv +# define INIT _Z4initv +#else +# define INIT_PAGING init_paging__Fv +# define INIT init__Fv +#endif + +_start: + /* Save the multiboot info structure pointer (ebx) to physical + address of kernel_arg. We assume that the kernel IS multibooted. + This value is later on passed to the root task */ + /* UD: Actually, we should save the mbi flags as well - just for the + case where we AREN'T multibooted. */ + movl %ebx, kernel_arg - KERNEL_OFFSET + cli /* disable int's */ + cld /* clear direction flag */ + mov %ds, %ax + mov %ax, %es + mov %ax, %fs + jmp 1f +1: + nop + nop + mov %ax, %gs + mov %ax, %ss + + /* load temporary stack pointer */ + lea _mini_stack-4, %esp + /* set up paging */ + call INIT_PAGING + + + /* still running in 1:1 mapped area + jump to the top level init function */ + jmp INIT + + + .space 1024 + .globl _mini_stack +_mini_stack: + + .section .mb_header + .align 4 +_mb_header: + .long 0x1BADB002 /* magic */ + .long 0x00000000 /* flags */ + .long - 0x00000000 - 0x1BADB002 /* check */ diff --git a/kernel/src/x86/i686/startup.o b/kernel/src/x86/i686/startup.o new file mode 100644 index 0000000..7e73fec Binary files /dev/null and b/kernel/src/x86/i686/startup.o differ diff --git a/kernel/src/x86/init.c b/kernel/src/x86/init.c new file mode 100644 index 0000000..a1c52e0 --- /dev/null +++ b/kernel/src/x86/init.c @@ -0,0 +1,944 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University + * + * File path: x86/init.c + * Description: x86 specific initialization code. + * + * @LICENSE@ + * + * $Id: init.c,v 1.82 2002/05/13 13:04:31 stoess Exp $ + * + ********************************************************************/ +#include +#include + +#include +#include +#include +#include +#include +#include + +/* relocate to init section */ +void init_arch_1() L4_SECT_INIT; +void init_paging() L4_SECT_INIT; +void setup_idt() L4_SECT_INIT; +void setup_tss() L4_SECT_INIT; +void setup_excp_vector() L4_SECT_INIT; +void activate_excp_vector() L4_SECT_INIT; +void calc_processor_speed() L4_SECT_INIT; + +void init_map_4k(dword_t * pdir, dword_t addr, dword_t val) L4_SECT_INIT; +void init_map_4mb(dword_t * pdir, dword_t addr, dword_t val) L4_SECT_INIT; + +void dump_idt() L4_SECT_INIT; +void dump(void *address, int size) L4_SECT_INIT; + +/* initial memory we need for pagetable setup */ +#define KERNEL_PAGE(x) ((dword_t*)&init_kernel_mem[PAGE_SIZE * x]) +dword_t * kernel_ptdir_root = NULL; +unsigned char init_kernel_mem[PAGE_SIZE * (KERNEL_INIT_PAGES)] __attribute__((aligned(4096))); + +/* cpu-local pagetables */ +#if defined(CONFIG_SMP) +void init_cpu_local_data(); +dword_t * boot_ptdir; +#endif + +// cpu-local stuff +x86_tss_t __tss L4_SECT_CPULOCAL; +seg_desc_t gdt[GDT_SIZE] L4_SECT_CPULOCAL; +dword_t __is_small L4_SECT_CPULOCAL = 0; +tcb_t* fpu_owner L4_SECT_CPULOCAL = NULL; + + +/* The interrupt descriptor table */ +idt_desc_t idt[IDT_SIZE]; + + +#define BUGSCREEN(x) \ +do { \ + for (volatile ptr_t p = (ptr_t) 0xb8000; p < (ptr_t) 0xb8000 + 40*25; p++) \ + *p = (x * 0x00010001) | (0x97 * 0x01000100U); \ + *((volatile ptr_t) 0xb8000 + 40*12 + 19) = 'L' | (0xF4 << 8) | (('4' | (0xF4 << 8)) << 16); \ + *((volatile ptr_t) 0xb8000 + 40*12 + 20) = 'K' | (0xF0 << 8) | (('a' | (0xF0 << 8)) << 16); \ + wbinvd(); \ + while(1); \ +} while (0) + +/* architecture specific initialization + * invoked by src/init.c before anything is done + * but running on virtual addresses + */ +void init_arch_1() +{ + init_irqs(); + + calc_processor_speed(); + + /* + * init real-time clock + */ + + /* set rtc to 512 Hz */ + while(in_rtc(0x0a) & 0x80); + + out_rtc(0x0A, (in_rtc(0x0a) & 0xf0) | 0x07); + out_rtc(0x0b, in_rtc(0x0b) | 0x48); + + /* reset intr line */ + in_rtc(0x0c); + + +} + + +void init_arch_2() +{ +#if defined(CONFIG_X86_P4_BTS) || defined(CONFIG_X86_P4_PEBS) + init_tracestore(); +#endif +#if defined(CONFIG_SMP) + boot_cpu = get_apic_cpu_id(); + + /* for SMP we have to re-allocate the kernel space + * since it is not compatible with space_t assumptions + */ + printf("copying kernel pagedir\n"); + char * pdir = (char*)kmem_alloc(PAGE_SIZE * CONFIG_SMP_MAX_CPU); + for (int i = 0; i < CONFIG_SMP_MAX_CPU; i++) + memcpy((dword_t*)(pdir + i * PAGE_SIZE), + kernel_ptdir_root, PAGE_SIZE); + + /* switch to newly allocated pagetable */ + set_current_pagetable(virt_to_phys((dword_t*)(pdir + boot_cpu * PAGE_SIZE))); + + /* free old one */ + //kmem_free(kernel_ptdir_root, PAGE_SIZE); + + /* store new space */ + kernel_ptdir_root = (dword_t*)pdir; + + /* set boot page table for APs */ + boot_ptdir = get_current_pagetable(); + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("boot cpu is %d\n", boot_cpu); +#endif +#endif /* CONFIG_SMP */ + +#if defined(CONFIG_IO_FLEXPAGES) + /* Initialize IO mapping database */ + io_mdb_init(); +#endif + +} + + +/* post processing (e.g., flushing page-table entries) */ +void init_arch_3() +{ + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("CPU features: %x\n", get_cpu_features()); +#endif + +#if defined(CONFIG_SMP) + /* init_arch_3 is only executed by the boot cpu */ + boot_cpu = get_apic_cpu_id(); + + init_cpu_local_data(); + + smp_startup_processors(); +#endif + + /* Kmem is initialized now. */ + __zero_page = kmem_alloc(PAGE_SIZE); + zero_memory(__zero_page, PAGE_SIZE); + + /* Flush init section. */ + //kernel_ptdir[0] = 0; + + flush_tlb(); + +#if !defined(CONFIG_X86_APIC) + /* Do not give out the timer interrupt. */ + interrupt_owner[0] = get_idle_tcb(); + interrupt_owner[2] = get_idle_tcb(); + interrupt_owner[8] = get_idle_tcb(); +#endif +} + + +INLINE void init_zero_memory(void * address, int size) +{ + dword_t *tmp = (dword_t*)address; + size /= 4; + while(size--) + *tmp++ = 0; + +} + +void wait_for_second_tick() +{ + // wait that update bit is off + while(in_rtc(0x0a) & 0x80); + + // read second value + byte_t secstart = in_rtc(0); + + // now wait until seconds change + while (secstart == in_rtc(0)); +} + +static void setup_apic_timer(dword_t tickrate) L4_SECT_INIT; +static void setup_apic_timer(dword_t tickrate) +{ + /* divide by 1 */ + set_local_apic(X86_APIC_TIMER_DIVIDE, (get_local_apic(X86_APIC_TIMER_DIVIDE) & ~0xf) | 0xb); + set_local_apic(X86_APIC_TIMER_COUNT, tickrate); + + /* set timer periodic and enable it */ + set_local_apic(X86_APIC_LVT_TIMER, (get_local_apic(X86_APIC_LVT_TIMER) & ~(APIC_IRQ_MASK)) | 0x20000); +} + +void calc_processor_speed() +{ + qword_t cpu_cycles; +#if defined(CONFIG_X86_APICTIMER) + dword_t bus_cycles; +#endif + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("calculating processor speed...\n"); +#endif + +#if defined(CONFIG_X86_APICTIMER) + /* set timer to divide-1 mode and reload with a large value */ + setup_apic_timer(0xFFFFFFFF); +#endif + + wait_for_second_tick(); +#if defined(CONFIG_X86_APICTIMER) + bus_cycles = get_local_apic(X86_APIC_TIMER_CURRENT); +#endif + cpu_cycles = rdtsc(); + wait_for_second_tick(); +#if defined(CONFIG_X86_APICTIMER) + bus_cycles -= get_local_apic(X86_APIC_TIMER_CURRENT); +#endif + cpu_cycles = rdtsc() - cpu_cycles; + + kernel_info_page.processor_frequency = (dword_t) cpu_cycles; +#if defined(CONFIG_X86_APICTIMER) + kernel_info_page.bus_frequency = bus_cycles; +#endif + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("cpu speed: %d Hz\n", kernel_info_page.processor_frequency); +#if defined(CONFIG_X86_APICTIMER) + printf("bus speed: %d Hz\n", kernel_info_page.bus_frequency); +#endif +#endif +#if defined(CONFIG_X86_APICTIMER) + setup_apic_timer(kernel_info_page.bus_frequency / (1000000/TIME_QUANTUM)); +#endif +} + + +/********************************************************************** + * + * architecture initialization - before anything else + * + **********************************************************************/ + + +void init_map_4k(dword_t * pdir, dword_t addr, dword_t val) +{ + dword_t *ptab = (dword_t *) pdir[pgdir_idx(addr)]; + + /* Check if there is a second level pagetable. */ + if ( !IS_PAGE_VALID((dword_t) ptab) ) + { +#if 0 + /* Allocate second level table. */ + ptab = (dword_t *) virt_to_phys(kmem_alloc(PAGE_SIZE)); + pdir[pgdir_idx(addr)] = ((dword_t) ptab) | PAGE_KERNEL_TBITS; +#else + BUGSCREEN('I'); +#endif + } + ptab = (dword_t*)(((dword_t)ptab) & PAGE_MASK); + ptab[pgtab_idx(addr)] = val; +} + +void init_map_4mb(dword_t * pdir, dword_t addr, dword_t val) +{ +#if defined(CONFIG_IA32_FEATURE_PSE) + pdir[addr >> PAGEDIR_BITS] = val | PAGE_SUPER; +#else +#error superpages not supported on this platform - emulation please... +#endif +} + + +#if defined(CONFIG_IA32_FEATURE_SEP) +INLINE void setup_sysenter_msrs() +{ + /* uses external symbols __tss and ipc_sysenter */ + __asm__ __volatile__ + ( + "/* set up the sysenter MSRs */ \n\t" + "mov $0x174,%%ecx \n\t" + "mov $8,%%eax \n\t" + "sub %%edx,%%edx \n\t" + "wrmsr /* SYSENTER_CS_MSR */ \n\t" + + "mov $0x176,%%ecx \n\t" + "mov $ipc_sysenter,%%eax \n\t" + "sub %%edx,%%edx \n\t" + "wrmsr /* SYSENTER_EIP_MSR */ \n\t" + + "mov $0x175,%%ecx \n\t" + "mov $__tss + 4,%%eax \n\t" + "sub %%edx,%%edx \n\t" + "wrmsr /* SYSENTER_ESP_MSR */ \n\t" + : : : "eax", "edx", "ecx"); +} +#endif + +#define PRINTTEXT(x) init_print_string(7, x) +#define PRINTINFO(x) init_print_string(2, x) +static int pos = 0; +static void init_putc(const char color, char s) L4_SECT_INIT; +INLINE void init_print_string(const char color, const char * s) +{ + char * __s = s <= (char*)KERNEL_VIRT ? (char*)s : virt_to_phys((char*)s); + while(*__s) + init_putc(color, *__s++); +} + +static void init_putc(const char color, char s) +{ +#define INIT_SCREEN(x) (((char*)0xb8000)[x]) +#define POS (*virt_to_phys(&pos)) + switch (s) + { + case '\n': + do { + INIT_SCREEN(POS++) = ' '; + INIT_SCREEN(POS++) = color; + } while(POS % 160); + break; + default: + INIT_SCREEN(POS++) = s; + INIT_SCREEN(POS++) = color; + } +} + +INLINE int has_cpuid() +{ + dword_t flags1, flags2; + asm("pushf \n" + "pop %0 \n" + "mov %0, %1 \n" + "xorl %2, %0 \n" + "push %0 \n" + "popf \n" + "pushf \n" + "pop %0 \n" + : "=r"(flags1), "=r"(flags2) + : "i"(1 << 21) + : "cc" ); + return flags1 != flags2; +} + +static dword_t check_cpu_features() L4_SECT_INIT; +static dword_t check_cpu_features() +{ + dword_t cpu_features = 0; + static const char* features[] L4_SECT_ROINIT = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", + "cx8", "apic", "?", "sep", "mtrr", "pge", "mca", "cmov", + "pat", "pse-36", "psn", "cflsh", "?", "ds", "acpi", "mmx", + "fxsr", "sse", "sse2", "ss", "?", "tm", "?", "?" }; + + /* first check if we have the cpuid instruction */ + if (has_cpuid()) + cpu_features = get_cpu_features(); + + if ((cpu_features & CPU_FEATURE_MASK) != CPU_FEATURE_MASK) + { + if (!cpu_features) { + PRINTINFO("The CPUID instruction is not supported.\n"); + goto abort; + } + + PRINTINFO("Your processor does not support the following features:\n"); + for (int i = 0; i < 32; i++) + if (((1 << i) & CPU_FEATURE_MASK) && !((1 << i) & cpu_features)) + { + PRINTTEXT(features[i]); + PRINTTEXT(" "); + } + PRINTINFO("\n"); + goto abort; + } + + dword_t version; + asm("cpuid\n" : "=a"(version) : "0"(1) : "ebx", "ecx", "edx"); +#if CONFIG_ARCH_X86_P4 + /* check that we are really running on a P4 */ + if (((version >> 8) & 0xf) != 0xf) { + PRINTINFO("Your processor is not an Intel Pentium4\n"); + goto abort; + } +#endif + + /* everything is fine - lets get the baby going */ + return cpu_features; + + abort: + PRINTINFO("\nThis configuration of L4Ka/Hazelnut cannot boot on your system.\n"); + PRINTTEXT("For more information on supported hardware refer to\n" + " http://l4ka.org/projects/hazelnut\n" + "Your system is halted now.\n"); + + /* write back screen... but only on 486 and higher! */ + if (cpu_features) + wbinvd(); + + while(1) + { /* wait forever */ }; +} + + +void init_paging() +{ + /* clear screen */ + for (volatile ptr_t p = (ptr_t) 0xb8000; p < (ptr_t) 0xb8000 + 40*25; p++) + *p = (' ' | (0x07 << 8)) * 0x00010001; + + check_cpu_features(); + + /* write back + invalidate cache */ + wbinvd(); + + /* from kmemory.c */ + extern dword_t kmem_start; + extern dword_t kmem_end; + + dword_t _kmem_start, _kmem_end; + +#if defined(CONFIG_TRACEBUFFER) + (*(dword_t*)(virt_to_phys(&kernel_info_page.main_mem_high)))-=4*1024*1024; +#endif + + /* get end of phys mem from kernel_info_page */ + _kmem_end = phys_to_virt(*(dword_t*)(virt_to_phys(&kernel_info_page.main_mem_high))); + +#if defined(CONFIG_TRACEBUFFER) + tracebuffer_t *_tracebuffer = (tracebuffer_t*)((_kmem_end + 0x3fffff) & (~0x3fffff)); + extern tracebuffer_t *tracebuffer; + + (*(dword_t*)(virt_to_phys(&tracebuffer))) = (dword_t)_tracebuffer; +#endif + +#define MAXMEM (240*1024*1024) + /* limit to a maximum of 240MB - we don't map the last 16M */ + if (virt_to_phys(_kmem_end) > MAXMEM-PAGE_SIZE) + _kmem_end = phys_to_virt(MAXMEM-PAGE_SIZE); + /* guess the amount of memory needed for startup - currently 8MB hardcoded */ + _kmem_start = _kmem_end - 8*1024*1024; + /* SMP machines seem to lack some pages at the end of physical memory */ + _kmem_start += 64*1024; _kmem_start &= ~(1*1024*1024 - 1); + + /* check if there's memory */ + (*(volatile ptr_t) virt_to_phys(_kmem_start)) = 0x14101973; + wbinvd(); + if ((*(volatile ptr_t) virt_to_phys(_kmem_start)) != 0x14101973) + BUGSCREEN('1'); + + /* write values to kmem's variables - we run still without an MMU */ + *virt_to_phys(&kmem_start) = _kmem_start; + *virt_to_phys(&kmem_end) = _kmem_end; + + init_zero_memory(init_kernel_mem, PAGE_SIZE * KERNEL_INIT_PAGES); + + /* We have to operate on physical addresses. */ + dword_t *pdir_root = virt_to_phys(KERNEL_PAGE(0)); + dword_t *ptab_kernel1 = virt_to_phys(KERNEL_PAGE(1)); + + + /* Map init section. */ + for (int i = 0; i < MAXMEM; i+=0x00400000) + init_map_4mb(pdir_root, i, i | PAGE_KERNEL_INIT_SECT); + + /* install 2nd level pagetable for the first 4M */ + pdir_root[pgdir_idx(KERNEL_VIRT)] = + (dword_t) ptab_kernel1 | PAGE_KERNEL_TBITS; + + /* map the whole 4M as 4k pages */ + for ( dword_t addr = KERNEL_OFFSET; + addr < KERNEL_OFFSET + 0x00400000; + addr += PAGE_SIZE ) + init_map_4k(pdir_root, addr, virt_to_phys(addr) | PAGE_KERNEL_BITS); + + /* Map kernel dynamic memory. */ + for ( dword_t addr = 0xf0400000; + addr < 0xff000000; + addr += 0x00400000 ) + init_map_4mb(pdir_root, addr, (virt_to_phys(addr) & PAGEDIR_MASK) | PAGE_KERNEL_BITS); + +#if defined(CONFIG_TRACEBUFFER) + init_map_4mb(pdir_root, (dword_t)_tracebuffer, (virt_to_phys((dword_t)_tracebuffer) & PAGEDIR_MASK) | PAGE_KERNEL_BITS | PAGE_USER); +#endif + + /* Map video memory. */ + init_map_4k(pdir_root, KERNEL_VIDEO, virt_to_phys(KERNEL_VIDEO) | PAGE_KERNEL_BITS | PAGE_CACHE_DISABLE); + + /* Map hercules too... */ + init_map_4k(pdir_root, KERNEL_VIDEO_HERC, virt_to_phys(KERNEL_VIDEO_HERC) | PAGE_KERNEL_BITS | PAGE_CACHE_DISABLE); + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* User-level trampoline for ipc_sysexit. */ + extern dword_t _start_utramp[], _start_utramp_p[]; + init_map_4k(pdir_root, (dword_t) _start_utramp, + (dword_t) _start_utramp_p | PAGE_USER_BITS); + + /* We need user access in the pdir entry. */ + pdir_root[pgdir_idx(KERNEL_VIRT)] |= PAGE_USER; +#endif + +#if defined(CONFIG_X86_APIC) || defined(CONFIG_MEASURE_INT_LATENCY) + ptab_kernel1[pgtab_idx(KERNEL_LOCAL_APIC)] = + X86_LOCAL_APIC_BASE | PAGE_APIC_BITS; +#endif +#ifdef CONFIG_X86_APIC + ptab_kernel1[pgtab_idx(KERNEL_IO_APIC)] = + X86_IO_APIC_BASE | PAGE_APIC_BITS; +#endif + +#if defined(CONFIG_IA32_FEATURE_PSE) + /* Turn on super pages. */ + enable_super_pages(); +#endif +#if defined(CONFIG_IA32_FEATURE_PGE) + enable_global_pages(); +#endif +#if defined(CONFIG_IA32_FEATURE_SEP) + setup_sysenter_msrs(); +#endif +#if defined(CONFIG_IA32_FEATURE_FXSR) + enable_osfxsr(); +#endif + +#if defined(CONFIG_PERFMON) + asm( + /* enable rdpmc instr in user mode */ + "mov %%cr4,%%eax\n" + "orl $(1 << 8), %%eax\n" + "mov %%eax,%%cr4\n" + : : : "eax"); +#endif + + /* Load ptroot. */ + set_current_pagetable(pdir_root); + + /* Turn on paging and pray. */ + enable_paged_mode(); + + /* store kernel pdir -- we have virtual mem now */ + kernel_ptdir_root = phys_to_virt(pdir_root); + + /* disable the FPU */ + disable_fpu(); + +#if defined(CONFIG_TRACEBUFFER) + _tracebuffer->current = 0; + _tracebuffer->magic = TBUF_MAGIC; + _tracebuffer->counter = 0; + _tracebuffer->threshold = 1000; + +#if defined(CONFIG_PERFMON) + asm ( + "mov $390, %%ecx \n" // disable PMCs + "xor %%edx, %%edx \n" + "xor %%eax, %%eax \n" + "wrmsr \n" + "inc %%ecx \n" + "wrmsr \n" + + "mov $193, %%ecx \n" // clear PMCs + "wrmsr \n" + "inc %%ecx \n" + "wrmsr \n" + + "mov $390, %%ecx \n" // init PMCs + "mov $0x4100C0, %%eax \n" // ENABLE + USER + INST_RETIRED + "wrmsr \n" + "inc %%ecx \n" + "mov $0x4200C0, %%eax \n" // ENABLE + KRNL + INST_RETIRED + "wrmsr \n" + + : + : + : "eax", "ecx", "edx" + ); +#endif +#endif +} + +void dump_idt() +{ + printf("idt-dump: idt at %x\n", idt); + for (int i = 0; i < (IDT_SIZE) ; i++) { + if (idt[i].x.d.p) + printf("%d -> %4x:%x , dpl=%d, type=%d (%x:%x)\n", i, + idt[i].x.d.sel, + idt[i].x.d.offset_low | (idt[i].x.d.offset_high << 16), + idt[i].x.d.dpl, idt[i].x.d.type, + idt[i].x.raw[0], idt[i].x.raw[1]); + } +} + +void dump(void *address, int size) +{ + for (int i = 0; i < (size / 4); i++) + printf("%x ", ((dword_t*)address)[i]); +} + + +INLINE void add_int_gate(int index, void (*address)()) +{ + ASSERT(index < IDT_SIZE); + idt[index].set(address, IDT_DESC_TYPE_INT, 0); +} + +INLINE void add_syscall_gate(int index, void (*address)()) +{ + ASSERT(index < IDT_SIZE); + idt[index].set(address, IDT_DESC_TYPE_INT, 3); +} + +INLINE void add_trap_gate(int index, void (*address)()) +{ + ASSERT(index < IDT_SIZE); + idt[index].set(address, IDT_DESC_TYPE_TRAP, 0); +} + +void setup_idt() +{ + /* clear IDT */ + init_zero_memory(idt, sizeof(idt)); + + /* trap gates */ + add_int_gate(0, int_0); + add_int_gate(1, int_1); + add_int_gate(2, int_2); + add_syscall_gate(3, int_3); + add_int_gate(4, int_4); + add_int_gate(5, int_5); + add_int_gate(6, int_6); + add_int_gate(7, int_7); + add_int_gate(8, int_8); + add_int_gate(9, int_9); + add_int_gate(10, int_10); + add_int_gate(11, int_11); + add_int_gate(12, int_12); + add_int_gate(13, int_13); + add_int_gate(14, int_14); + // 15 undefined + add_int_gate(16, int_16); + add_int_gate(17, int_17); + add_int_gate(18, int_18); + add_int_gate(19, int_19); + + /* hardware interrupts */ + add_int_gate(32, hwintr_0); + add_int_gate(33, hwintr_1); + add_int_gate(34, hwintr_2); + add_int_gate(35, hwintr_3); + add_int_gate(36, hwintr_4); + add_int_gate(37, hwintr_5); + add_int_gate(38, hwintr_6); + add_int_gate(39, hwintr_7); +#if defined(CONFIG_X86_APICTIMER) + add_int_gate(40, hwintr_8); +#else + add_int_gate(40, timer_irq); +#endif + add_int_gate(41, hwintr_9); + add_int_gate(42, hwintr_10); + add_int_gate(43, hwintr_11); + add_int_gate(44, hwintr_12); + add_int_gate(45, hwintr_13); + add_int_gate(46, hwintr_14); + add_int_gate(47, hwintr_15); + + /* trap gates -- we use automatic int disable mechanism :-) */ + add_syscall_gate(48, int_48); + add_syscall_gate(49, int_49); + add_syscall_gate(50, int_50); + add_syscall_gate(51, int_51); + add_syscall_gate(52, int_52); + add_syscall_gate(53, int_53); + add_syscall_gate(54, int_54); + +#ifdef CONFIG_X86_APIC + add_int_gate(APIC_LINT0_INT_VECTOR, apic_lint0); + add_int_gate(APIC_LINT1_INT_VECTOR, apic_lint1); +#if defined(CONFIG_X86_APICTIMER) + add_int_gate(APIC_TIMER_INT_VECTOR, timer_irq); +#endif + add_int_gate(APIC_ERROR_INT_VECTOR, apic_error); + add_int_gate(APIC_SPURIOUS_INT_VECTOR, apic_spurious_int); +# if defined(CONFIG_ENABLE_PROFILING) + add_int_gate(APIC_PERFCTR_INT_VECTOR, apic_perfctr); +# endif +#endif + +#ifdef CONFIG_SMP + //add_int_gate(APIC_SMP_CONTROL_IPI, apic_smp_control_ipi); + add_int_gate(APIC_SMP_COMMAND_IPI, apic_smp_command_ipi); +#endif + + //dump(idt, IDT_SIZE); + //spin(); + +} + +void setup_tss() +{ + init_zero_memory(&__tss, TSS_SIZE); + /* This defines the stack segment to use when we switch TO privilege + level 0 */ + __tss.ss0 = X86_KDS; + /* The TSS contains a pointer to the base of the IO permission bitmap. + This pointer is relative to the start of the TSS */ + __tss.iopbm_offset = ((dword_t) __tss.io_bitmap) - (dword_t) &__tss; + /* The last byte in x86_tss_t (effectively the first byte behind the + IO permission bitmap) is a stopper for the IO permission bitmap. + It must be 0xFF (see IA32-RefMan, Part 1, Chapter Input/Output) */ + __tss.stopper = 0xFF; +} + +void setup_gdt() +{ + /* clear GDT */ + init_zero_memory(gdt, sizeof(gdt)); + + /* + * Fill the GDT. We also set the user segments to 4GB. They will + * be set to 3GB when needed (i.e., when small spaces are enabled). + */ +# define MB (1024*1024) +# define GB (MB*1024) +# define gdt_idx(x) ((x) >> 3) + gdt[gdt_idx(X86_KCS)].set_seg(0, ~0, 0, GDT_DESC_TYPE_CODE); + gdt[gdt_idx(X86_KDS)].set_seg(0, ~0, 0, GDT_DESC_TYPE_DATA); + gdt[gdt_idx(X86_UCS)].set_seg(0, ~0, 3, GDT_DESC_TYPE_CODE); + gdt[gdt_idx(X86_UDS)].set_seg(0, ~0, 3, GDT_DESC_TYPE_DATA); + + /* the TSS + The last byte in x86_tss_t is a stopper for the IO permission bitmap. + That's why we set the limit in the GDT to one byte less than the actual + size of the structure. (IA32-RefMan, Part 1, Chapter Input/Output) */ + gdt[gdt_idx(X86_TSS)].set_sys(&__tss, sizeof(__tss)-1, 0, GDT_DESC_TYPE_TSS); + /* kdb data - phys_mem */ + gdt[gdt_idx(X86_KDB)].set_seg((ptr_t) KERNEL_OFFSET, GB*1, 0, GDT_DESC_TYPE_DATA); + +#ifdef CONFIG_TRACEBUFFER + gdt[gdt_idx(X86_TBS)].set_seg((ptr_t) tracebuffer, 4*MB, 3, GDT_DESC_TYPE_DATA); +#endif +} + +void activate_gdt() +{ + /* create a temporary GDT descriptor to load the GDTR from */ + sys_desc_t gdt_desc = {sizeof(gdt), (ptr_t)gdt, 0} ; + + asm("lgdt %0 \n" /* load descriptor table */ + "ljmp %1,$1f \n" /* refetch code segment descr. */ + "1: \n" /* by jumping across segments */ + : + : "m"(gdt_desc), "i" (X86_KCS) + ); + + /* set the segment registers from the freshly installed GDT + and load the Task Register with the TSS via the GDT */ + asm("mov %0, %%ds \n" /* reload data segment */ + "mov %0, %%es \n" /* need valid %es for movs/stos */ + "mov %1, %%ss \n" /* reload stack segment */ +#ifdef CONFIG_TRACEBUFFER + "mov %2, %%fs \n" /* tracebuffer segment */ +#endif + "movl %3, %%eax \n" + "ltr %%ax \n" /* load install TSS */ + : + : "r"(X86_UDS), "r"(X86_KDS), "r"(X86_TBS), "r"(X86_TSS) + : "eax"); +} + +void activate_idt() +{ + + // and finally the idt + sys_desc_t idt_desc = {sizeof(idt), (ptr_t) idt, 0}; + + asm ("lidt %0" + : + : "m"(idt_desc) + ); +} + +/* map and setup excp. vector */ +void setup_excp_vector() +{ + setup_idt(); + + setup_tss(); + + setup_gdt(); + + activate_gdt(); + activate_idt(); +} + + + +#if defined(CONFIG_SMP) +void init_cpu_local_data() +{ + get_idle_tcb()->cpu = get_apic_cpu_id(); + current_max_prio = MAX_PRIO; + fpu_owner = NULL; +} + +void init_smp() L4_SECT_INIT; +void init_smp() +{ +#if defined(CONFIG_IA32_FEATURE_PSE) + /* Turn on super pages. */ + enable_super_pages(); +#endif +#if defined(CONFIG_IA32_FEATURE_PGE) + enable_global_pages(); +#endif +#if defined(CONFIG_IA32_FEATURE_SEP) + setup_sysenter_msrs(); +#endif +#if defined(CONFIG_IA32_FEATURE_FXSR) + enable_osfxsr(); +#endif + +#if defined(CONFIG_PERFMON) + asm( + /* enable rdpmc instr in user mode */ + "mov %%cr4,%%eax\n" + "orl $(1 << 8), %%eax\n" + "mov %%eax,%%cr4\n" + : : : "eax"); + +#endif + set_current_pagetable(*virt_to_phys(&boot_ptdir)); + enable_paged_mode(); + + /********************************************************************** + * + * carefull -- no virtual memory accesses before that point + * + **********************************************************************/ + + int cpu = get_apic_cpu_id(); + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("moin - processor %d is alive...\n", cpu); +#endif + + extern char _start_cpu_local; + extern char _end_cpu_local; + + pgent_t * ref_pgent = get_kernel_space()->pgent(pgdir_idx((dword_t)&_start_cpu_local), boot_cpu); + pgent_t * cpu_pgent = get_kernel_space()->pgent(pgdir_idx((dword_t)&_start_cpu_local), cpu); + +//#if defined(CONFIG_DEBUG_SANITY) + if (! ref_pgent->is_valid(get_kernel_space(), 1)) + { + printf("init_smp: initial pagetable broken"); + spin(1); + } +//#endif + pgent_t * cpu_ptab = (pgent_t*)kmem_alloc(PAGE_SIZE); + pgent_t * ref_ptab = ref_pgent->subtree(get_kernel_space(), 1); + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("smp: create cpu-local ptab ((%p, %p)->(%p, %p))\n", + get_kernel_space()->pagedir(boot_cpu), ref_ptab, + get_kernel_space()->pagedir(cpu), cpu_ptab); +#endif + + memcpy((dword_t*)cpu_ptab, (dword_t*)ref_ptab, PAGE_SIZE); + + /* adapt pagetable for cpu-local area */ + cpu_pgent->x.raw = ((dword_t)virt_to_phys(cpu_ptab)) | PAGE_KERNEL_TBITS; + + /* now re-map cpu-local area */ + cpu_ptab = cpu_ptab->next(get_kernel_space(), pgtab_idx((dword_t)&_start_cpu_local)); + int numpages = ((dword_t)(&_end_cpu_local)-(dword_t)(&_start_cpu_local))/PAGE_SIZE; + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("remapping %d pages for cpu-local data @ %p\n", + numpages, &_start_cpu_local); +#endif + + for (int i = 0; i < numpages; i++, cpu_ptab->next(get_kernel_space(), 1)) + { + ptr_t page = kmem_alloc(PAGE_SIZE); + cpu_ptab->x.raw = ((dword_t)virt_to_phys(page)) | PAGE_KERNEL_BITS; + } +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("cpu %d: switching to pagetable %x\n", + cpu, get_kernel_space()->pagedir_phys(cpu)); +#endif + set_current_pagetable(get_kernel_space()->pagedir_phys(cpu)); + +#if defined(CONFIG_IA32_FEATURE_PGE) + /* with global bits on we have to explicitely flush the cpu-local + * pages (we do not know if we already touched them) + */ + for (dword_t addr = (dword_t)&_start_cpu_local; + addr < (dword_t)&_end_cpu_local; addr += PAGE_SIZE) + flush_tlbent((ptr_t)addr); +#endif + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("cpu %d: switched to cpu-specific pagetable (%p)\n", + cpu, get_current_pagetable()); +#endif + + /* now setup exception vector etc. */ + setup_gdt(); + setup_tss(); + + activate_gdt(); + activate_idt(); + + /* apic initialization */ + setup_local_apic(); + setup_apic_timer(kernel_info_page.bus_frequency / (1000000/TIME_QUANTUM)); +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("AP apic initialization done...\n"); +#endif + + /* cpu-local initialization - afterwards we can use get_cpu_id() */ + init_cpu_local_data(); + + /* deactivate fpu */ + disable_fpu(); + + /* now switch to idle to start the other guys */ + switch_to_initial_thread(create_idle_thread()); +} +#endif diff --git a/kernel/src/x86/init.o b/kernel/src/x86/init.o new file mode 100644 index 0000000..a4dbc28 Binary files /dev/null and b/kernel/src/x86/init.o differ diff --git a/kernel/src/x86/interrupt.c b/kernel/src/x86/interrupt.c new file mode 100644 index 0000000..502b766 --- /dev/null +++ b/kernel/src/x86/interrupt.c @@ -0,0 +1,1575 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001-2002, Karlsruhe University + * + * File path: x86/interrupt.c + * Description: Interrupt and exceptiond handling and initialization + * for the x86. + * + * @LICENSE@ + * + * $Id: interrupt.c,v 1.64 2002/05/31 11:51:44 stoess Exp $ + * + ********************************************************************/ +#include +#include +#include +#include +#include + +#if defined(CONFIG_IO_FLEXPAGES) +#include +#include +#endif + +#if defined(CONFIG_ENABLE_PVI) +/* Virtual Interrupts Indicator*/ +dword_t pending_irq; +#define IRQ_IN_SERVICE (1<<31) + +#define MAX_PENDING_IRQS 16 +#define PENDING_IRQ_BIT(x) (1 << x) +#define PENDING_TIMER_IRQ (1 << 31) + +void handle_pending_irq(void); + +#endif /* CONFIG_ENABLE_PVI */ + + +#ifndef CONFIG_X86_APIC + +#ifdef CONFIG_MEASURE_INT_LATENCY +#include +#endif + +#ifdef CONFIG_X86_INKERNEL_PIC +static byte_t pic1_mask, pic2_mask; +#endif + + +/********************************************************************** + * + * 8259A - standard PIC + * + **********************************************************************/ + +static void disable_8259A_irq(unsigned int irq) +{ + if (irq & 8) PIC2_MASK(irq - 8); + else PIC1_MASK(irq); +} + +static void enable_8259A_irq(unsigned int irq) +{ + if (irq & 8) PIC2_UNMASK(irq - 8); + else PIC1_UNMASK(irq); +} + +static int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1<> 8)); +} + +/* + * Careful! The 8259A is a fragile beast, it pretty + * much _has_ to be done exactly like this (mask it + * first, _then_ send the EOI, and the order of EOI + * to the two 8259s is important! + */ +static void mask_and_ack_8259A(unsigned int irq) +{ + if (irq & 8) { + PIC2_MASK(irq - 8); + outb(X86_PIC2_CMD, 0x60 + (irq&7)); /* Specific EOI to slave */ + outb(X86_PIC1_CMD, 0x62); /* Specific EOI to cascade */ + } else { + PIC1_MASK(irq); + outb(X86_PIC1_CMD, 0x60 + (irq)); + } +} + +static void mask_8259A(unsigned int irq) +{ + if (irq & 8) { + PIC2_MASK(irq - 8); + outb(X86_PIC1_CMD, 0x62); /* Specific EOI to cascade */ + } else { + PIC1_MASK(irq); + } +} + +void init_irqs() +{ + printf("%s\n", __FUNCTION__); + + /* first mask all interrupts */ + PIC1_SET_MASK(0xff); + PIC2_SET_MASK(0xff); + + /* setup pic (directly copied from Jochen's init)*/ + outb(X86_PIC1_CMD, 0x11); + outb(X86_PIC1_DATA, 0x20); /* start at idt entry 0x20 */ + outb(X86_PIC1_DATA, 0x04); + outb(X86_PIC1_DATA, 0x01); /* mode - *NOT* fully nested */ + outb(X86_PIC1_CMD, 0xc1); /* prio 8..15, 3..7, 0, 1 */ + + outb(X86_PIC2_CMD, 0x11); + outb(X86_PIC2_DATA, 0x28); /* start at idt entry 0x28 */ + outb(X86_PIC2_DATA, 0x02); + outb(X86_PIC2_DATA, 0x01); /* not fully nested */ + outb(X86_PIC2_CMD, 0xc7); /* prios... */ + + outb(X86_PIC1_CMD, 0x0A); + outb(X86_PIC2_CMD, 0x0A); + + /* enable timer irq (int 8) and init PIC mask cache */ + PIC1_SET_MASK(0xfb); + PIC2_SET_MASK(0xfe); + + outb(X86_PIC1_CMD, 0x60); + + /* enable nmi */ + in_rtc(0); + outb(0x61, inb(0x61) & ~(0xC)); + +#if defined(CONFIG_ENABLE_PVI) + pending_irq = 0; +#endif +} + + +void mask_interrupt(unsigned int number) +{ + disable_8259A_irq(number); +} + +void unmask_interrupt(unsigned int number) +{ +#ifdef CONFIG_X86_INKERNEL_PIC + enable_8259A_irq(number); +#endif +} + + + +void irq_handler(exception_frame_t *frame) +{ + + /* We do not need special handling for the timer IRQ here, + because this is done by timer_irq_handler(). */ + + TRACEPOINT_1PAR(INTERRUPT, frame->fault_code, + printf("irq_handler: irq #%d\n", frame->fault_code)); + +#ifdef CONFIG_X86_INKERNEL_PIC + mask_and_ack_8259A(frame->fault_code); +#else + disable_8259A_irq(frame->fault_code); +#endif + +#if defined(CONFIG_ENABLE_PVI) + + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we tag the interrupt bit in + * the fiels to handle it later. + */ + if(((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0)){ + + frame->eflags |= X86_EFL_VIP; + + tcb_t *current = get_current_tcb(); + current->resources |= TR_PVI; + + /* Save pending interrupt */ + pending_irq |= (1<< (frame->fault_code)); + + // printf("IRQ Handler irq=%x, enq irq_pending %x\n", frame->fault_code, + // pending_irq); + + return; + } +#endif /* CONFIG_ENABLE_PVI */ + + // printf("%s - irq: %d, tcb=%p\n", __FUNCTION__, frame->fault_code, get_current_tcb()); + // printf("IRQ %d pending\n ", frame->fault_code); + + handle_interrupt(frame->fault_code); +} + + +#else /* CONFIG_X86_APIC */ + +/********************************************************************** + * + * APIC and IO-APIC + * + **********************************************************************/ + +#include + +#warning APIC experimental + +void apic_setup_timer(int tickrate) L4_SECT_INIT; +void setup_local_apic() L4_SECT_INIT; + + +/* + * Function for accessing PCI configuration space with type 1 accesses + */ +static byte_t pci_read_config_byte(byte_t bus, byte_t devfn, byte_t where) +{ + byte_t value; + outl(0xCF8, (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3))); + value = inb(0xCFC + (where&3)); + return value; +} + +/* store information about io-apic interrupts */ +static apic_redir_t io_apic_intr[MAX_IOAPIC_INTR]; +/* A table for getting the IO-APIC line for an IRQ number */ +static byte_t irq_to_ioapicline_map[16]; +static void setup_io_apic() L4_SECT_INIT; + +#include INC_ARCH(mps-14.h) + +#if defined(CONFIG_DEBUG_TRACE_INIT) +#define Dprintf(x...) printf(x) +#else +#define Dprintf(x...) +#endif + +void setup_io_apic() +{ + /* check for io apic */ + apic_version_t io_apic_version; + + io_apic_version.raw = get_io_apic(X86_IOAPIC_VERSION); + + if (io_apic_version.ver.version != 0x11) { + printf("Panic: no io APIC detected. syshalt."); + asm("hlt\n"); + } + + Dprintf("io-apic max lvt: %d\n", io_apic_version.ver.max_lvt); + + int num_irqs = io_apic_version.ver.max_lvt + 1; + + /* first mask all interrupts on the PIC */ + outb(X86_PIC1_DATA, 0xff); + outb(X86_PIC2_DATA, 0xff); + + /* set apic to symmetric mode */ + outb(0x22, 0x70); + outb(0x23, 0x01); + + + /* initialize the array */ + for (int i = 0; i < num_irqs; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + entry->vector = 0; + entry->delivery_mode = APIC_DEL_FIXED; + entry->dest_mode = APIC_DEST_PHYS; + entry->trigger_mode = 0; + entry->polarity = 0; + entry->mask = IOAPIC_IRQ_MASKED; + entry->dest.physical.physical_dest = 0; /* send everything to apic 0 */ + } + + + intel_mp_floating_t *f; + byte_t isabus_id = 0xFE; + byte_t ioapic_id = 0xFE; + for (f = (intel_mp_floating_t*) 0xF0000; + f < (intel_mp_floating_t*) 0x100000; + f = (intel_mp_floating_t*) (((dword_t) f) + 0x10)) + if (f->signature == MPS_MPF_SIGNATURE) + { +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("SMP: Found MPS signature at %x\n", f); + printf("SMP: Version 1.%c\n", '0' + f->specification); + if (f->feature[0] != 0) + { + printf("SMP: Default config requested. No idea how!\n"); + f = (intel_mp_floating_t*) 0x100000; + break; + }; +#endif + mp_config_table_t *t = (mp_config_table_t*) f->physptr; + + if (t->signature == MPS_MPC_SIGNATURE) + { + Dprintf("SMP: Found MPC table at %x\n", t); + Dprintf("SMP: Length: %x\n", t->length); + Dprintf("SMP: Enties: %d\n", t->entries); + Dprintf("SMP: Local APIC at %x\n", t->lapic); + + union e_t { + byte_t type; + mpc_config_processor_t cpu; + mpc_config_bus_t bus; + mpc_config_ioapic_t ioapic; + mpc_config_intsrc_t irq; + mpc_config_lintsrc lint; + } *e = (union e_t *) (t + 1); + + for (int inc=0, i = t->entries; + i--; + e = (union e_t *) ((dword_t) e + inc)) + switch (e->type) + { + case MP_PROCESSOR: + Dprintf("SMP: Cpu: %d %cP\n", + e->cpu.apicid, + (e->cpu.cpuflag & 2) ? 'B':'A'); + inc = sizeof(e->cpu); +#if defined(CONFIG_SMP) + extern dword_t processor_map; + processor_map |= (1 << e->cpu.apicid); +#endif + break; + case MP_BUS: + Dprintf("SMP: Bus: %d %c%c%c%c%c%c\n", + e->bus.busid, + e->bus.bustype[0], e->bus.bustype[1], + e->bus.bustype[2], e->bus.bustype[3], + e->bus.bustype[4], e->bus.bustype[5]); + if ((e->bus.bustype[0] == 'I') && + (e->bus.bustype[1] == 'S') && + (e->bus.bustype[2] == 'A')) + { + + isabus_id = e->bus.busid; + Dprintf("SMP: ISA Bus is %2x\n", isabus_id); + }; + inc = sizeof(e->bus); + break; + case MP_IOAPIC: + Dprintf("SMP: IOAPIC: id=%2x, flags=%02, ver=%2x @ %p\n", + e->ioapic.apicid, e->ioapic.flags, + e->ioapic.apicver, e->ioapic.apicaddr); + /* keep the IOAPICs id */ + if (e->ioapic.flags & 1) + ioapic_id = e->ioapic.apicid; + inc = sizeof(e->ioapic); + break; + case MP_INTSRC: + Dprintf("SMP: IRQ: %2x %4x %2x %2x %2x %2x\n", + e->irq.irqtype, e->irq.irqflag, + e->irq.srcbus, e->irq.srcbusirq, + e->irq.dstapic, e->irq.dstirq); + if (e->irq.irqtype == 0) + /* set up ISA irqs - if we know the ISA bus already */ + if (e->irq.dstapic == ioapic_id) + { + apic_redir_t *entry = &io_apic_intr[e->irq.dstirq]; + /* PCI defaults to level-triggered, active low */ + int dpo = 1, dtm = 1; + if (e->irq.srcbus == isabus_id) + { + Dprintf("SMP: ISA irq 0x%2x is on APIC pin 0x%2x\n", + e->irq.srcbusirq, e->irq.dstirq); + entry->vector = e->irq.srcbusirq + 0x20; + irq_to_ioapicline_map[e->irq.srcbusirq] = e->irq.dstirq; + /* ISA defaults to edge-triggered, active high */ + dpo = 0; + dtm = 0; + }; + /* (irqflag & 0x3) - polarity + = 0 - default, = 1 - active high, = 2 - reserved, = 3 - active low + IO-APIC: 0 - active high, 1 - active low */ + entry->polarity = ((int []){ dpo, 0, 0, 1})[e->irq.irqflag & 3]; + /* ((irqflag >> 2) & 0x3) - trigger mode + = 0 - default, = 1 - edge, = 2 - reserved, = 3 - level + IO-APIC: 0 - edge, 1 - level */ + entry->trigger_mode = ((int []){ dtm, 0, 0, 1})[(e->irq.irqflag >> 2) & 3]; + }; + inc = sizeof(e->irq); + break; + case MP_LINTSRC: + Dprintf("SMP: LINT: %2x %4x %2x %2x %2x %2x\n", + e->lint.irqtype, e->lint.irqflag, + e->lint.srcbus, e->lint.srcbusirq, + e->lint.dstapic, e->lint.dstlint); + inc = sizeof(e->lint); + break; +#if defined(CONFIG_DEBUG_TRACE_INIT) + default: + printf("SMP: Unknown type %2x. Aborting\n", e->type); + i = 0; + break; +#endif + }; + + } +#if defined(CONFIG_DEBUG_TRACE_INIT) + else + { + printf("MPC shall be at %x\n", f->physptr); + printf("mpc.sig: %x should be %x\n", + t->signature, MPS_MPC_SIGNATURE); + } +#endif + /* exit from scan loop */ + break; + } + +#if defined(CONFIG_DEBUG_TRACE_INIT) + /* when we can't find anything useful go with very hacky defaults */ + if ( f >= (intel_mp_floating_t*) 0x100000) + { + printf("SMP: couldn't find MPS floating structure.\n" + "SMP: Doing default setup.\n"); + + /* initialize the ISA interrupts - line 0 is unused */ + for (int i = 1; i < 16; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + entry->vector = i + 0x20; /* hw irqs start at 0x20 */ + entry->trigger_mode = 0; + entry->polarity = 0; + irq_to_ioapicline_map[i] = i; + } + /* IRQ0 is linked to input line 2 - link that back to IRQ0 */ + io_apic_intr[2].vector = 0x20; + irq_to_ioapicline_map[0] = 2; + } +#endif + + + { + /* try to figure out the mapping of PCI INT# to ISA IRQ# + - PCI INT#A is wired to IO-APIC's INT16 input + - PCI INT#B is wired to IO-APIC's INT17 input + - PCI INT#C is wired to IO-APIC's INT18 input + - PCI INT#D is wired to IO-APIC's INT19 input */ + + /* arry to temporarily store the apicpin_to_irq mapping */ + char ioapicline_to_irq[4] = { 0 , 0, 0, 0 }; + + /* scan BIOS area for the "$PIR" signature of the PCI IRQ Routing table */ + struct irq_routing_table *r; + for (r = (irq_routing_table*) 0xF0000; + r < (irq_routing_table*) 0x100000; + r = (irq_routing_table*) (((dword_t) r) + 0x10)) + if (r->signature == MPS_PIRT_SIGNATURE) + { + Dprintf("IRQ: Found PCI IRQ routing information at %p\n", r); + +#if defined(CONFIG_DEBUG_TRACE_INIT) + int slots = (r->size - sizeof(irq_routing_table))/sizeof(irq_info); + printf("IRQ: %d slots in table\n", slots); + + for (int i = slots; i--;) + { + printf("IRQ: %d: bus=%02x dev=%02x link=(%02x,%02x,%02x,%02x) slot=%02x\n", + i, + r->slots[i].bus, r->slots[i].devfn, + r->slots[i].irq[0].link, + r->slots[i].irq[1].link, + r->slots[i].irq[2].link, + r->slots[i].irq[3].link, + r->slots[i].slot); + + }; +#endif + + /* do we know how to handle the IRQ router ? */ + switch((r->rtr_vendor << 16) | (r->rtr_device)) + { + case 0x80867000: + { + Dprintf("IRQ: Router is Intel PIIX4\n"); + + /* The PIIX stores the mapping in its PCI config space at + offsets 0x60-0x63 for INTA-INTD. + See 82371AB (PIIX4) specification, section 4.1.10, p.59 */ + for (int i = 0; i < 4; i++) + { + int irq; + irq = pci_read_config_byte(r->rtr_bus, r->rtr_devfn, 0x60 + i); + /* bit 7 = 0 marks valid entries */ + if ((irq & 0x80) == 0) + { + ioapicline_to_irq[i] = irq; + Dprintf("IRQ: INT#%c routed to vector %d\n", 'A' + i, irq); + } + } + }; break; + case 0x11660200: + { + Dprintf("IRQ: Router is ServerWorks\n"); + + /* port 0xc00 is index register + port 0xc01 is data register */ + for (int i = 0; i < 4; i++) + { + int irq; + outb(0xc00, i | 0x10); + irq = inb(0xc01); + Dprintf("IRQ: Got back %02x for %02x\n", irq + 0x66, i); + { + ioapicline_to_irq[i] = irq; + Dprintf("IRQ: INT#%c routed to vector %d\n", 'A' + i, irq); + } + } + }; break; +#if defined(CONFIG_DEBUG_TRACE_INIT) + default: + { + printf("IRQ: Unknown PCI IRQ router %4x:%4x on %2x:%2x ... :-(\n", + r->rtr_vendor, r->rtr_device, r->rtr_bus, r->rtr_devfn); + }; break; +#endif + } + } + + /* with the information gathered configure the PCI inputs of the IO-APIC */ + for (int i = 16; i < 20; i++) + { + char irq; + apic_redir_t *entry = &io_apic_intr[i]; + irq = ioapicline_to_irq[i-16]; + if (irq == 0) + continue; /* no entry */ + entry->vector = irq + 0x20; /* hw irqs start at 0x20 */ + irq_to_ioapicline_map[irq] = i; + }; + + } + + /* write the entries to the IO-APIC */ + for (int i = 0; i < num_irqs; i++) + { + apic_redir_t *entry = &io_apic_intr[i]; + set_io_apic(X86_IOAPIC_REDIR0 + (i*2) + 0, *(((dword_t*)entry) + 0)); + set_io_apic(X86_IOAPIC_REDIR0 + (i*2) + 1, *(((dword_t*)entry) + 1)); +#if 0 + printf("ioredir(%d): %x, %x\n", i, + get_io_apic(X86_IOAPIC_REDIR0 + 0 + (i*2)), + get_io_apic(X86_IOAPIC_REDIR0 + 1 + (i*2))); +#endif + } +} + + +/* + * initializes the local apic + * the timer setup happens in apic_second_tick after + * measuring the duration of one second + */ +void setup_local_apic() +{ + dword_t tmp; + + /* enable local apic */ + tmp = get_local_apic(X86_APIC_SVR); + tmp |= 0x100; /* enable APIC */ + tmp &= ~(0x200); /* enable focus processor */ + ASSERT((APIC_SPURIOUS_INT_VECTOR & 0xf) == 0xf); + tmp |= APIC_SPURIOUS_INT_VECTOR; /* spurious interrupt = 0xff */ + set_local_apic(X86_APIC_SVR, tmp); + + /* set prio to accept all */ + tmp = get_local_apic(X86_APIC_TASK_PRIO); + tmp &= ~0xff; + set_local_apic(X86_APIC_TASK_PRIO, tmp); + + /* flat mode */ + tmp = get_local_apic(X86_APIC_DEST_FORMAT); + tmp |= 0xf0000000; + set_local_apic(X86_APIC_DEST_FORMAT, tmp); + + /* set lint0 as extINT - keep disabled for now */ + set_local_apic(X86_APIC_LVT_LINT0, 0x18000 | APIC_LINT0_INT_VECTOR); + /* set lint1 as NMI */ + set_local_apic(X86_APIC_LVT_LINT1, 0x08000 | APIC_DEL_NMI); + /* set error handler - keep disabled for now */ + set_local_apic(X86_APIC_LVT_ERROR, 0x18000 | APIC_ERROR_INT_VECTOR); + /* set timer handler - keep it disabled for now */ + set_local_apic(X86_APIC_LVT_TIMER, APIC_TIMER_INT_VECTOR | APIC_IRQ_MASK); + +#if defined(CONFIG_ENABLE_PROFILING) +# if defined(CONFIG_PROFILING_WITH_NMI) + /* Set perfctr as NMI */ + set_local_apic(X86_APIC_PERF_COUNTER, 0x0400 | APIC_PERFCTR_INT_VECTOR); +# else + /* Set perfctr as Fixed */ + set_local_apic(X86_APIC_PERF_COUNTER, 0x0000 | APIC_PERFCTR_INT_VECTOR); +# endif +#endif + + /* Enable NMI */ + in_rtc(0); + outb(0x61, inb(0x61) & ~(0xC)); +} + +void init_irqs() +{ +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("%s\n", __FUNCTION__); +#endif + + /* first mask all interrupts on the pic */ + outb(X86_PIC1_DATA, 0xff); + outb(X86_PIC2_DATA, 0xff); + + /* set apic to symetric mode */ + outb(0x22, 0x70); + outb(0x23, 0x01); + +#if defined(CONFIG_DEBUG_TRACE_INIT) + printf("local APIC-id: %x\n", get_local_apic(X86_APIC_ID)); + printf("local APIC-Version: %x\n", get_local_apic(X86_APIC_VERSION)); + printf("local APIC SVR: %x\n", get_local_apic(X86_APIC_SVR)); + + printf("io APIC-id: %x\n", get_io_apic(X86_IOAPIC_ID)); + printf("io APIC-Version: %x\n", get_io_apic(X86_IOAPIC_VERSION)); +#endif + + /* check for local apic */ + if ((get_local_apic(X86_APIC_VERSION) & 0xf0) != 0x10) { + printf("Panic: no local APIC detected. syshalt."); + asm("hlt\n":); + } + setup_local_apic(); + + /* initialize io apic interrupts */ + setup_io_apic(); +} + +/* timer is handled in apic_handle_timer */ +void irq_handler(exception_frame_t *frame) +{ + //printf("irq %d\n", frame->fault_code); + + TRACEPOINT_1PAR(INTERRUPT, frame->fault_code, + printf("irq_handler: irq #%d\n", frame->fault_code)); + + /* edge triggered irq's can be simply ack'd + * level triggered have to be masked first. + * they are re-enabled in the ipc path + */ + if (io_apic_intr[irq_to_ioapicline_map[frame->fault_code]].trigger_mode == IOAPIC_TRIGGER_LEVEL) + { + //printf("mask_irq %d\n", frame->fault_code); + io_apic_mask_irq(irq_to_ioapicline_map[frame->fault_code]); + } + apic_ack_irq(); + +#if defined(CONFIG_ENABLE_PVI) + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we tag the interrupt bit in + * the field to handle it later. + */ + if( ((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0) ) + + { + tcb_t *current = get_current_tcb(); + /* set VIP flag - sti will cause #GP */ + frame->eflags |= X86_EFL_VIP; + current->resources |= TR_PVI; + + /* Save pending interrupt */ + pending_irq |= (1 << frame->fault_code); + + /* Bail out - keep the actual IRQ handling for later */ + return; + } +#endif /* CONFIG_ENABLE_PVI */ + + handle_interrupt(frame->fault_code); +} + +void apic_handler_lint0() +{ + enter_kdebug("apic_handler_lint0"); + apic_ack_irq(); +} + +void apic_handler_lint1() +{ + enter_kdebug("apic_handler_lint1"); + apic_ack_irq(); +} + +void apic_handler_error() +{ + enter_kdebug("apic_handler_error"); + apic_ack_irq(); +} + +void apic_handler_spurious_int() +{ + enter_kdebug("apic_handler_spurious"); + apic_ack_irq(); +} + +void apic_handler_timer() +{ + apic_ack_irq(); + handle_timer_interrupt(); +} + + +void mask_interrupt(unsigned int number) +{ + //printf("mask_interrupt %d\n", number); + io_apic_mask_irq(irq_to_ioapicline_map[number]); +} + +void unmask_interrupt(unsigned int number) +{ + //printf("unmask_interrupt %d\n", number); + io_apic_unmask_irq(irq_to_ioapicline_map[number]); +} + + +#endif /* CONFIG_X86_APIC */ + + + +void timer_irq_handler(exception_frame_t *frame) +{ + +#if defined(CONFIG_ENABLE_PVI) + + /* + * If IOPL == 3, we're either sigma0 or idle; in this case we'll handle the + * the interrupt. + * Otherwise we check the VIF bit. If it is 0, we bear the interrupt in mind + * and handle it later. + */ + + if( ((frame->eflags & X86_EFL_IOPL(3)) == 0) + && ((frame->eflags & X86_EFL_VIF) == 0) ){ + + // printf("enq timer interrupt, eip=%x\n", frame->fault_address); + // enter_kdebug("timer_irq"); + + mask_and_ack_8259A(8); + /* reset timer intr line */ + in_rtc(0x0c); + + frame->eflags |= X86_EFL_VIP; + pending_irq |= PENDING_TIMER_IRQ; + + tcb_t *current = get_current_tcb(); + current->resources |= TR_PVI; + return; + } + +#endif /* CONFIG_ENABLE_PVI */ + +#if !defined(CONFIG_X86_APICTIMER) + mask_and_ack_8259A(8); + /* reset timer intr line */ + in_rtc(0x0c); + enable_8259A_irq(8); +#else + apic_ack_irq(); +#endif /* CONFIG_X86_APICTIMER */ + handle_timer_interrupt(); +} + + +#define TRACEPOINT_INSTR(instruction...) \ + TRACEPOINT(INSTRUCTION_EMULATION, \ + { printf("instruction emulation @ %p: ", \ + frame->fault_address); \ + printf(##instruction); }) + + +static int handle_faulting_instruction(tcb_t* current, + exception_frame_t* frame) +{ + /* This function returns TRUE if the fault was handled, FALSE otherwise. + current pointer to current TCB + frame pointer to exception frame + instr pointer to first byte of instruction that caused the exception + */ + + unsigned char * instr = (unsigned char *) frame->fault_address; + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* + * Translate fault address so that we can access it using + * kernel segments. + */ + + smallid_t sid = current->space->smallid (); + if (sid.is_valid () && ((dword_t) instr < sid.bytesize ())) + instr += sid.offset (); +#endif + +#if defined(CONFIG_ENABLE_PVI) + if ( (frame->eflags & X86_EFL_VIP) && (frame->eflags & X86_EFL_VIF)){ + // printf("PVI2: tid=%x, eflags=%x\n", current->myself.raw, frame->eflags); + // enter_kdebug(); + /* Set VIF flag, clear VIP flag */ + frame->eflags |= X86_EFL_VIF; + frame->eflags &= ~X86_EFL_VIP; + current->resources &= ~TR_PVI; + + /* Handle pending interrupts */ + if (pending_irq){ + handle_pending_irq(); + } + return TRUE; + + } +#endif + switch (instr[0]) { + + case 0x0f: + switch (instr[1]) { + case 0x01: + if ( instr[2] != 0x18 ) break; + /* + * 0F 01 18 lidt (%eax) + * + * Currently, we only support LIDT emulation where the + * IDT descriptor address is in EAX. Other ways to + * load IDT are not detected and result in a GP + * exception. + */ + if ( frame->eax < USER_AREA_MAX - 6 ) + { + dword_t idt = frame->eax + 2; +#if defined(CONFIG_ENABLE_SMALL_AS) + if (sid.is_valid () && (idt < sid.bytesize ())) + idt += sid.offset (); +#endif + idt = *(dword_t *) idt; + if ( idt >= (USER_AREA_MAX - 32*8) ) + idt = 0; + current->excpt = idt; + TRACEPOINT_INSTR("lidt (idt-desc: %x, idt: %x)\n", + frame->eax, idt); + } + frame->fault_address += 3; + return TRUE; + + + case 0x09: + /* + * 0F 09 /r wbinvd + * + * wbinvd emulation is turned off by default but can + * be enabled if _really_ necessary + */ + + TRACEPOINT_INSTR("wbinvd\n"); +#if defined(CONFIG_X86_WBINVD_EMULATION) + __asm__("wbinvd\n\r"); +#endif + frame->fault_address += 2; + return TRUE; + + case 0x21: + case 0x23: + { + /* + * 0F 21 /r mov %dreg, %reg + * 0F 23 /r mov %reg, %dreg + * + * Virtualize debug registers. Registers DR4 and DR5 + * are not accessible and only task local breakpoints + * can be enabled. + * + * HERE BE DRAGONS! This code is by no means + * thoroughly tested and will not work properly in + * conjunction with KDB breakpoints. + */ +# define MOVDR_GENREG (&frame->eax)[0-(instr[2] & 0x7)] + dword_t val = MOVDR_GENREG; + dword_t dreg = (instr[2] >> 3) & 0x7; + + if ( dreg == 4 || dreg == 5 ) + break; + + if ( instr[1] == 0x21 ) + /* Get register contents from TCB. */ + MOVDR_GENREG = current->priv[0].dbg.dr[dreg]; + else + { + if ( dreg == 7 ) val &= ~0xaa; + + if ( current->resources & TR_DEBUG_REGS ) + { + TRACEPOINT_INSTR("mov reg, dr%d\n", dreg); + switch (dreg) { + case 0: asm("mov %0, %%dr0" : :"r"(val)); break; + case 1: asm("mov %0, %%dr1" : :"r"(val)); break; + case 2: asm("mov %0, %%dr2" : :"r"(val)); break; + case 3: asm("mov %0, %%dr3" : :"r"(val)); break; + case 6: asm("mov %0, %%dr6" : :"r"(val)); break; + case 7: asm("mov %0, %%dr7" : :"r"(val)); break; + } + } + + /* Store register contents into TCB. */ + current->priv[0].dbg.dr[dreg] = val; + + if ( dreg == 7 ) + if ( val & 0x33 ) + { + if ( !(current->resources & TR_DEBUG_REGS) ) + /* + * Debug registers are beeing enabled. + * Load contents of all debug + * registers from TCB. + */ + load_debug_regs((ptr_t) ¤t->priv[0].dbg); + current->resources |= TR_DEBUG_REGS; + } + else + current->resources &= ~TR_DEBUG_REGS; + } + enter_kdebug("debug register access"); + frame->fault_address += 3; + return TRUE; + } + + case 0x30: + case 0x32: + /* + * 0F 30 wrmsr + * 0F 32 rdmsr + * + * Virtualize accesses to model specific registers. + * We must check the validity of the register number + * too, or we might end up shooting ourself in the + * foot. + */ + switch (frame->ecx & 0xffff) { +#if defined(CONFIG_ARCH_X86_I686) + case IA32_PERFCTR0: + case IA32_PERFCTR1: + case IA32_EVENTSEL0: + case IA32_EVENTSEL1: +#elif defined(CONFIG_ARCH_X86_I586) + case IA32_TSC: + case IA32_CESR: + case IA32_CTR0: + case IA32_CTR1: +#elif defined(CONFIG_ARCH_X86_P4) + default: +#else + case 0xffffffff: +#endif + if ( instr[1] == 0x30 ) + { + TRACEPOINT_INSTR("wrmsr (eax=%x, edx=%x, %ecx=%x)\n", + frame->eax, frame->edx, frame->ecx); + asm volatile ("wrmsr" : : + "a"(frame->eax), + "d"(frame->edx), + "c"(frame->ecx)); + } + else + { + asm volatile ("rdmsr" + : "=a"(frame->eax), + "=d"(frame->edx) + : "c"(frame->ecx)); + TRACEPOINT_INSTR("rdmsr (eax=%x, edx=%x, %ecx=%x)\n", + frame->eax, frame->edx, frame->ecx); + } + frame->fault_address += 2; + return TRUE; + } + break; + + case 0xa1: + case 0xa9: + goto pop_seg; + } + break; + + case 0x8e: + case 0x07: + case 0x17: + case 0x1f: + pop_seg: + /* + * 8E /r mov %reg, %segreg + * 07 pop %es + * 17 pop %ss + * 1F pop %ds + * 0F A1 pop %fs + * 0F A9 pop %gs + * + * Segment descriptor is being written with an invalid + * value. Reset all descriptors with the correct value + * and skip the instruction. + */ + if ( frame->fault_address >= KERNEL_VIRT ) break; + TRACEPOINT(SEGREG_RELOAD); + + asm volatile ( +#if defined(CONFIG_TRACEBUFFER) + " movl %1, %%fs \n" +#else + " movl %0, %%fs \n" +#endif + " movl %0, %%gs \n" + : + :"r"(X86_UDS), "r"(X86_TBS)); + frame->ds = frame->es = X86_UDS; + + frame->fault_address++; + if ( instr[0] == 0x8e || instr[0] == 0x0f ) + frame->fault_address++; + return TRUE; + +#if defined(CONFIG_ENABLE_SMALL_AS) + case 0xcf: + { + /* + * CF iret + * + * When returning to user-level the instruction pointer + * might happen to be outside the small space. If so, we + * must promote the space to a large one. + */ + if ( (dword_t) instr >= KERNEL_VIRT && + sid.is_valid () && + get_user_ip(current) > sid.bytesize () ) + { + small_space_to_large (current->space); + return TRUE; + } + break; + } +#endif + + case 0xf4: + /* + * F4 hlt + * + * Kernel version / API interface detection. Return the + * appropriate values in register EAX. + */ + TRACEPOINT(GET_KERNEL_VERSION, + printf("GetKernelVersion @ %x\n",frame->fault_address)); + frame->eax = ((KERNEL_VERSION_API << 24) | + (KERNEL_VERSION_KID << 20) | + (KERNEL_VERSION_VER << 16) | + (KERNEL_VERSION_SUB << 1) | 1); + frame->fault_address += 1; + return TRUE; +#if defined(CONFIG_ENABLE_PVI) + + case 0xfb: /* sti */ + { + /* + * If running in PVI Mode, sti can only cause an exception + * if a virtual interrupt is pending + */ + // printf("PVI: tid = %x, eflags=%x\n", current->myself.raw, frame->eflags); + // enter_kdebug(""); + /* Set VIF flag, clear VIP flag */ + frame->eflags |= X86_EFL_VIF; + frame->eflags &= ~X86_EFL_VIP; + current->resources &= ~TR_PVI; + + /* Handle pending interrupts */ + if (pending_irq){ + handle_pending_irq(); + } + return TRUE; + } + +#else +/* This can be used to virtualize sti/cli completely in software */ + +#if 0 + case 0xfa: /* sti */ + { + frame->eflags &= ~X86_EFL_IF; + frame->fault_address += 1; + return TRUE; + } + case 0xfb: /* sti */ + { + frame->eflags |= X86_EFL_IF; + frame->fault_address += 1; + return TRUE; + } + +#endif + +#endif /* CONFIG_ENABLE_PVI */ + +#if defined(CONFIG_IO_FLEXPAGES) + + case 0xe4: /* in %al, port imm8 (byte) */ + case 0xe6: /* out %al, port imm8 (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xe5: /* in %eax, port imm8 (dword) */ + case 0xe7: /* out %eax, port imm8 (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xec: /* in %al, port %dx (byte) */ + case 0xee: /* out %al, port %dx (byte) */ + case 0x6c: /* insb port %dx (byte) */ + case 0x6e: /* outsb port %dx (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %eax, port %dx (dword) */ + case 0xef: /* out %eax, port %dx (dword) */ + case 0x6d: /* insd port %dx (dword) */ + case 0x6f: /* outsd port %dx (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 2, 0); + printf("pagefault, addr = %x\n", io_fault.raw); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0x66: + + /* operand size override prefix */ + switch (instr[1]) + { + case 0xe5: /* in %ax, port imm8 (word) */ + case 0xe7: /* out %ax, port imm8 (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 1 , 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %ax, port %dx (word) */ + case 0xef: /* out %ax, port %dx (word) */ + case 0x6d: /* insw port %dx (word) */ + case 0x6f: /* outsw port %dx (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 1, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + } + case 0xf3: + + /* rep instruction */ + switch (instr[1]){ + case 0xe4: /* in %al, port imm8 (byte) */ + case 0xe6: /* out %al, port imm8 (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xe5: /* in %eax, port imm8 (dword) */ + case 0xe7: /* out %eax, port imm8 (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xec: /* in %al, port %dx (byte) */ + case 0xee: /* out %al, port %dx (byte) */ + case 0x6c: /* insb port %dx (byte) */ + case 0x6e: /* outsb port %dx (byte) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 0, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %eax, port %dx (dword) */ + case 0xef: /* out %eax, port %dx (dword) */ + case 0x6d: /* insd port %dx (dword) */ + case 0x6f: /* outsd port %dx (dword) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 2, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0x66: + + /* operand size override prefix */ + switch (instr[2]) + { + case 0xe5: /* in %ax, port imm8 (word) */ + case 0xe7: /* out %ax, port imm8 (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) instr[1], 1 , 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + case 0xed: /* in %ax, port %dx (word) */ + case 0xef: /* out %ax, port %dx (word) */ + case 0x6d: /* insw port %dx (word) */ + case 0x6f: /* outsw port %dx (word) */ + { + io_fpage_t io_fault = io_fpage((word_t) (frame->edx & 0xFFFF), 1, 0); + do_pagefault_ipc(current, io_fault.raw, frame->fault_address); + return TRUE; + } + } + } +#endif /* CONFIG_IO_FLEXPAGES */ + } + + /* Nothing to repair */ + return FALSE; +} + + +static int handle_nm_exception(tcb_t *current) +{ + /* the current FPU owner resides in the cpu-local section */ + extern tcb_t* fpu_owner; + + TRACEPOINT(FPU_VIRTUALIZATION, + printf("FPU: %x uses fpu at %x, owner=%p\n", + current->myself.raw, get_user_ip(current), + fpu_owner)); + + /* allow access to the FPU until the next thread switch */ + enable_fpu(); + + /* mark the FPU usage in the resources */ + current->resources |= TR_FPU; + + /* if we own the fpu just re-enable and go */ + if (fpu_owner == current) + return TRUE; + +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) +# if X86_FLOATING_POINT_ALLOC_SIZE < KMEM_CHUNKSIZE +# error FIXME: Too small allocation size for floating point state +# endif + /* save the fpu state into the fpu-owner's save area */ + if (fpu_owner != NULL) + save_fpu_state ((byte_t *) fpu_owner->priv->fpu_ptr); + + /* now reload the fpu state */ + if (current->priv->fpu_ptr) + load_fpu_state ((byte_t *) current->priv->fpu_ptr); + else + { + init_fpu(); + current->priv->fpu_ptr = (x86_fpu_state_t *) + kmem_alloc (X86_FLOATING_POINT_ALLOC_SIZE); + if (current->priv->fpu_ptr == NULL) + panic ("fpu virtualization: alloc mem for fpu state failed"); + } +#else + /* save the fpu state into the fpu-owner's tcb */ + if (fpu_owner != NULL) + save_fpu_state ((byte_t *) &fpu_owner->priv->fpu); + + /* now reload the fpu state */ + if (current->priv->fpu_used) + load_fpu_state ((byte_t *) ¤t->priv->fpu); + else + { + init_fpu(); + current->priv->fpu_used = 1; + } +#endif + + /* update the owner */ + fpu_owner = current; + + return TRUE; +} + + +#if defined(CONFIG_ENABLE_SMALL_AS) +extern "C" void sysexit_tramp(void); +extern "C" void reenter_sysexit(void); +#endif + +void exception_handler(exception_frame_t * frame) +{ + tcb_t * current = get_current_tcb(); + +#if defined(CONFIG_DEBUGGER_KDB) && defined(CONFIG_DEBUG_BREAKIN) + /* We might happen to get into a loop catching exceptions. */ + kdebug_check_breakin(); +#endif + + /* + ** + ** General Protection Fault + ** + */ + if (frame->fault_code == 13) + { + /* + * A GP(0) could mean that we have a segment register with + * zero contents, either because the user did a reload + * (valid), or because of some strange bi-effects of using the + * SYSEXIT instruction (see comment in exception.S). + */ + if ( frame->error_code == 0 ) + { + word_t fs, gs; + asm (" mov %%fs, %w0 \n" + " mov %%gs, %w1 \n" + :"=r"(fs), "=r"(gs)); + + if ( (frame->ds & 0xffff) == 0 || (frame->es & 0xffff) == 0 || + fs == 0 || gs == 0 ) + { + TRACEPOINT (SEGREG_RELOAD, kdebug_dump_frame (frame)); + reload_user_segregs (); + frame->ds = frame->es = (frame->cs & 0xffff) == X86_UCS + ? X86_UDS : X86_KDS; + frame->es = X86_UDS; + return; + } + } + +#if defined(CONFIG_ENABLE_SMALL_AS) +# if defined(CONFIG_IA32_FEATURE_SEP) + /* + * Check if we caught an exception when doing the LRET. + */ + dword_t user_eip = get_user_ip(current); + + if ( user_eip >= (dword_t) sysexit_tramp && + user_eip < (dword_t) reenter_sysexit ) + { + /* + * If we faulted at the LRET instruction (i.e., still in + * user level) we must IRET to the kernel due to the user + * space code segment limitation. We must also disable + * interrupts since we can not be allowed to be preempted + * in the reenter-trampoline. + */ + frame->cs = X86_KCS; + frame->eflags &= ~X86_EFL_IF; + frame->ecx = (dword_t) get_user_sp(current); + frame->fault_address = (dword_t) reenter_sysexit; + return; + } +# endif /* defined(CONFIG_IA32_FEATURE_SEP) */ + +#endif + + + /* Do we have to emulate/virtualize something? Analyze the + * instruction that caused the exception. The function should + * return TRUE if no further processing is required. */ + if (handle_faulting_instruction(current, frame) == TRUE) + return; + + /* + * IDT emulation. + */ + + if ( (frame->error_code & 2) && (current->excpt) ) + { + TRACEPOINT(IDT_FAULT, + printf("IDT fault: tcb=%p excpt=%d\n", + current, frame->error_code >> 3)); + + /* + * Validate that we can safely push an iframe on the user + * stack. Current->excpt is already checked during + * emulation of the LIDT instruction. + */ + + if ( (dword_t) frame->user_stack > USER_AREA_MAX || + (dword_t) frame->user_stack <= 4 * sizeof(dword_t) ) + { + enter_kdebug("IDT emulation user stack out of bounds"); + goto Unhandled_fault; + } + + /* + * Validate that we do not access user memory outside of + * the small space boundaries. + */ + + dword_t offset = 0; +#if defined(CONFIG_ENABLE_SMALL_AS) + smallid_t sid = current->space->smallid (); + if (sid.is_valid ()) + { + if ( ((dword_t) frame->user_stack <= sid.bytesize ()) && + ((dword_t) (current->excpt + (13 * 8) + 4) + 4 <= + sid.bytesize ()) ) + { + offset = sid.offset (); + } + else + small_space_to_large (current->space); + } +#endif + + /* + * Grab the fault handler location from the thread's IDT. + */ + + dword_t *ex = (dword_t *) (current->excpt + offset + (13*8)); + dword_t fault_handler = (ex[0] & 0xffff) | (ex[1] & 0xffff0000); + + /* + * Create a fake fault frame and trap into the fault handler. + */ + + dword_t *usp = frame->user_stack + (offset / sizeof(dword_t)); + *(--usp) = frame->eflags; + *(--usp) = frame->cs; + *(--usp) = frame->fault_address; + *(--usp) = frame->error_code; + frame->fault_address = fault_handler; + frame->user_stack = usp - (offset / sizeof(dword_t)); + return; + } + } + + + /* + ** + ** Processor Extension not Available + ** + */ + if (frame->fault_code == 7) + if (handle_nm_exception(current) == TRUE) + return; + + + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( frame->fault_code == 12 || frame->fault_code == 13 ) + { + /* + * If a GP(0) or SS(0) is raised it might happen to be a small + * address space accessing an address outside of its segment + * boundaries. + */ + if (frame->error_code == 0 && current->space->is_small ()) + { + small_space_to_large (current->space); + return; + } + } +#endif + +Unhandled_fault: + + printf("exception (%d)\n", frame->fault_code); + kdebug_dump_frame(frame); + enter_kdebug(); +} + + +#if defined(CONFIG_ENABLE_PVI) + +void handle_pending_irq(void){ + + tcb_t *current = get_current_tcb(); + tcb_t *max_priority = current; + tcb_t *owner; + + // printf("handle_pending_irq %x\n", pending_irq); + + + for (dword_t num = 0; num < MAX_PENDING_IRQS; num++){ + + if (pending_irq & PENDING_IRQ_BIT(num)){ + // printf("handle_pending_irq number %x\n", num); + + owner = interrupt_owner[num]; + + /* if no one is associated - we simply drop the interrupt */ + if (owner) + { + if (IS_WAITING(owner) && + ((owner->partner.raw == (num + 1)) || l4_is_nil_id(owner->partner))) + { + owner->intr_pending = (num + 1) | IRQ_IN_SERVICE; + // printf("enqueue ready owner %x, me is %x\n", owner->myself.raw, current->myself.raw); + thread_enqueue_ready(owner); + owner->thread_state = TS_LOCKED_RUNNING; + + if (max_priority->priority < owner->priority) + max_priority = owner; + + } + else + owner->intr_pending = num + 1; + + } + } + } + + if (current != get_idle_tcb()){ + // printf("enqueue ready current %x\n", current->myself.raw); + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + } + + if (pending_irq & PENDING_TIMER_IRQ){ + // printf("handle pending timer interrupt; max_priority = %x, current = %x, resources=%x\n", max_priority->myself.raw, current->myself.raw, current->resources); + + enable_8259A_irq(8); + pending_irq = 0; + +#if (defined(CONFIG_DEBUGGER_KDB) || defined(CONFIG_DEBUGGER_GDB)) && defined(CONFIG_DEBUG_BREAKIN) + kdebug_check_breakin(); +#endif + +#if defined(CONFIG_SMP) + /* only cpu 0 maintains the clock */ + if (get_cpu_id() == 0) +#endif + kernel_info_page.clock += TIME_QUANTUM; + + current->current_timeslice -= TIME_QUANTUM; + + if (max_priority == current){ + tcb_t * wakeup = parse_wakeup_queue(current->priority, kernel_info_page.clock); + if (wakeup) + { + dispatch_thread(wakeup); + return; + } + + if (current->current_timeslice <= 0) + { + spin1(78); + current->current_timeslice = current->timeslice; + dispatch_thread(find_next_thread()); + } + + return; + } + } + + pending_irq = 0; + + if (max_priority != current){ + /* make sure runnable threads are in the ready queue */ + switch_to_thread(max_priority, current); + } + +} +#endif /* CONFIG_ENABLE_PVI */ + + diff --git a/kernel/src/x86/interrupt.o b/kernel/src/x86/interrupt.o new file mode 100644 index 0000000..a7bc93c Binary files /dev/null and b/kernel/src/x86/interrupt.o differ diff --git a/kernel/src/x86/io_mapping.c b/kernel/src/x86/io_mapping.c new file mode 100644 index 0000000..b392822 --- /dev/null +++ b/kernel/src/x86/io_mapping.c @@ -0,0 +1,1249 @@ +/********************************************************************* + * + * Copyright (C) 2002, Karlsruhe University + * + * File path: x86/io_mapping.c + * Description: Implementation of mapping database for IO fpages + * + * @LICENSE@ + * + * $Id: io_mapping.c,v 1.2 2002/05/21 15:39:29 stoess Exp $ + * + ********************************************************************/ + +#include + +#if defined(CONFIG_IO_FLEXPAGES) + +#include +#include +#include +#include + +#if defined(CONFIG_AUTO_IO_MAP) +#define IOPBM_DEFAULT_VALUE (0) +#else +#define IOPBM_DEFAULT_VALUE (~0) +#endif + +#define MIN(a,b) (a> 12) & 0x0000FFFF)) +#define IOFP_LD_SIZE(x) ((dword_t) (((x) >> 2) & 0x0000003F)) +#define IOFP_SIZE(x) ((dword_t) (1 << IOFP_LD_SIZE(x))) + +#define IOMDB_LO_MASK 0xFFFF0000 +#define IOMDB_TID_MASK 0x000000FF + +#define IOMDB_HI_MASK 0xFFFF8000 +#define IOMDB_DUMMY_MASK 0x00004000 +#define IOMDB_DEPTH_MASK 0x00003FFF +#define IOMDB_SUP_DEPTH 0x00004000 + +#define FLUSH_OWN_SPACE (1<<31) + +// #define IO_MDB_DEBUG 1 + +/* The Kernel Page Directory */ +static space_t *kspace; + +/* The virtual address of the default iopbm */ +static dword_t iopbm_virt; + +/* The physical address of the default iopbm */ +static ptr_t iopbm_phys; + +/* The Pagetable containing the entry to the IOPM */ +static pgent_t *iopbm_pgt; + +/* The TSS */ +extern x86_tss_t __tss; + + + +/* IO Mapping Node */ +class io_mnode_t +{ +public: + dword_t w1; /* Lower Bound (16), TaskID (8) */ + dword_t w2; /* Higher Bound (17), Dummy Marker (1), + Tree Depth (14) */ + io_mnode_t *next, *prev; /* Next/Prev Node in Mapping Tree */ + io_mnode_t *next_st, *prev_st; /* Next/Prev Node in Tasks List */ + + io_mnode_t *parent; /* Parent */ + + dword_t get_lo(void) + { return (w1 >> 16); } + + void set_lo(dword_t l) + { w1 = (w1 & IOMDB_TID_MASK) | (l << 16); } + + l4_threadid_t get_tid(void) + { return (l4_threadid_t) { raw : { ( (w1 & IOMDB_TID_MASK) << L4_X0_THREADID_BITS + L4_X0_VERSION_BITS)}};} + + void set_tid(l4_threadid_t t) + { w1 = (w1 & IOMDB_LO_MASK) | ( (t.raw >> L4_X0_THREADID_BITS + L4_X0_VERSION_BITS ) & IOMDB_TID_MASK );} + + dword_t get_hi(void) + { return (w2 >> 15); } + + void set_hi(dword_t h) + { w2 = (w2 & (IOMDB_DEPTH_MASK | IOMDB_DUMMY_MASK) ) | (h << 15); } + + + dword_t get_dummy(void) + { return (w2 & IOMDB_DUMMY_MASK); } + + void set_dummy(void) + { w2 |= IOMDB_DUMMY_MASK; } + + dword_t get_depth(void) + { return (w2 & IOMDB_DEPTH_MASK); } + + void set_depth(dword_t s) + { w2 = (w2 & (IOMDB_HI_MASK | IOMDB_DUMMY_MASK)) | (s & IOMDB_DEPTH_MASK) ; } + + void set_values(dword_t lo, dword_t hi, l4_threadid_t tid, dword_t depth, byte_t dummy){ + w1 = (lo << 16) | ((tid.raw >> L4_X0_THREADID_BITS + L4_X0_VERSION_BITS) & IOMDB_TID_MASK); + w2 = ((hi << 15) | (dummy ? IOMDB_DUMMY_MASK : 0)) | (depth & IOMDB_DEPTH_MASK); + } + + void enq_thread_list(io_mnode_t *before){ + this->next_st = before; + this->prev_st = before->prev_st; + before->prev_st = this; + this->prev_st->next_st = this; + } + + void deq_thread_list(){ + this->next_st->prev_st = this->prev_st; + this->prev_st->next_st = this->next_st; + + } + + void enq_subtree(io_mnode_t *after){ + this->next = after->next; + this->prev = after; + this->next->prev = this; + after->next = this; + } + + void deq_subtree(){ + this->next->prev = this->prev; + this->prev->next = this->next; + } + +}; + + + +/* The Initial Sigma0 node */ +static io_mnode_t sigma0_io_space; + +/* The IO MDB Terminator */ +static io_mnode_t io_mdb_end; + + +/* + * Lock mechanism: + * Implemented by a binary semaphore + * TODO: This could be crap + */ + + +/* The Semaphore */ +static dword_t io_mdb_lock; + +#if 0 +static void io_mdb_p(void){ + __asm__ __volatile__ ( + "1: \n\t" + "lock;" + "btsl $0, %0 \n\t" + "jc 1b \n\t" + : + :"m"(io_mdb_lock)); + +} + + + +static void io_mdb_v(void){ + __asm__ __volatile__ ( + "lock;" + "btrl $0, %0 \n\t" + : + :"m"(io_mdb_lock)); +} +#else +#define io_mdb_p() +#define io_mdb_v() +#endif + + +/* + * int get_iopbm() + * + * returns the first valid node of a task + */ + +static inline io_mnode_t *get_iospace(tcb_t *task){ + + dword_t *pgd = task->space->pagedir(); + return ((io_mnode_t *) pgd[IO_SPACE_IDX])->next_st; +} + +/* + * int get_iopbm() + * + * Sets the PGT entry to IO-Space + */ + +static inline void set_iospace(tcb_t *task, io_mnode_t *node){ + + dword_t *pgd = task->space->pagedir(); + pgd[IO_SPACE_IDX] = (dword_t) node; +} + +/* + * int get_iopbm() + * + * returns the physical address of the iopbm of a task + */ + +static inline ptr_t get_iopbm(space_t *space){ + + return (ptr_t) space->pgent(pgdir_idx(iopbm_virt))->subtree(space, 0)->\ + next(space, pgtab_idx(iopbm_virt), 0)->address(space, 0); + +} + +/* + * int install_iopbm() + * + * installs an intialised 8k Region as IOPBM + * + */ + + +static int install_iopbm(tcb_t *task, dword_t new_iopbm){ + + + /* + * Allocate a Pagetable. + * Do not use ->make_subtree, as we have to + * allocate and set up the pagetable _before_ + * installing it + */ + pgent_t *pgt_new = (pgent_t *) kmem_alloc(PAGE_SIZE); + + if (pgt_new == NULL){ + panic("install_iopbm(): out of memory\n"); + } + + /* Copy all entries from Kernel Page Table */ + pgent_t *k = iopbm_pgt; + pgent_t *n = pgt_new; + + for (int i=0; i<1024; i++){ + n->copy(task->space, 1, k, kspace, 1); + k = k->next(kspace, 1, 1); + n = n->next(task->space, 1, 1); + } + + + /* Set the two special entries */ + pgt_new->next(task->space, pgtab_idx(iopbm_virt), 0)->\ + set_entry(task->space, virt_to_phys(new_iopbm), 0, 0); + pgt_new->next(task->space, pgtab_idx(iopbm_virt), 0)->\ + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + pgt_new->next(task->space, pgtab_idx(iopbm_virt + 0x1000), 0)->\ + set_entry(task->space, virt_to_phys( new_iopbm + 0x1000), 0, 0); + pgt_new->next(task->space, pgtab_idx(iopbm_virt + 0x1000), 0)->\ + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + + /* Install new Pagetable (writable) */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_entry(task->space, (dword_t) virt_to_phys( (ptr_t) pgt_new), 1, 0); + + + /* Set Flags */ + task->space->pgent(pgdir_idx(iopbm_virt))-> + set_flags(task->space, 0, PAGE_VALID | PAGE_WRITABLE); + + if (task == get_current_tcb()){ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + } + + return 0; + + +} + +/* + * void release_iopbm() + * + * releases the IOPBM of a task and sets the pointers back to the default-IOPBM + * + */ + +static void release_iopbm(tcb_t *task){ + + + /* Get the special pagetable */ + ptr_t iopbm = get_iopbm(task->space); + + if (iopbm == iopbm_phys) + return; + + iopbm = phys_to_virt(iopbm); + + pgent_t *pgt = task->space->pgent(pgdir_idx(iopbm_virt))->subtree(task->space, 0); + + /* Insert the default PGT */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_entry(task->space, (dword_t) virt_to_phys( (ptr_t) iopbm_pgt), 1, 0); + + /* Set Flags */ + task->space->pgent(pgdir_idx(iopbm_virt))->\ + set_flags(task->space,0, PAGE_VALID | PAGE_WRITABLE); + + /* Release the Pagetable */ + kmem_free((ptr_t) pgt, PAGE_SIZE); + + /* Release the IOPBM */ + kmem_free(iopbm, X86_IOPERMBITMAP_SIZE / 8); + + + /* Flush the corresponding TLB entries */ + if (task == get_current_tcb()){ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + } + + +} + +/* + * int zero_iopbm() + * + * returns 0 on success + * -1 on error + */ + +static int zero_iopbm(tcb_t *task, dword_t port, dword_t size) +{ + dword_t count; + + // printf("zero_iopbm(): port=%x, size=%x, tid=%x\n", port, size, task->myself.raw); + + ptr_t iopbm = get_iopbm(task->space); + +#if !defined(CONFIG_AUTO_IO_MAP) + + /* + * If the task had no mappings before, it has the default IOPBM (which is set to ~0 in case + * of no implicit mapping). Create a new one, set it to 0 between port and port + size, + * and to ~0 else + */ + + if (iopbm == iopbm_phys){ + + + ptr_t new_iopbm, tmp; + + new_iopbm = kmem_alloc(X86_IOPERMBITMAP_SIZE / 8); + + if (new_iopbm == NULL){ + panic("zero_iopbm(): out of memory\n"); + } + + if (install_iopbm(task, (dword_t) new_iopbm)){ + printf("zero_iopbm(): install_iopbm failed\n"); + return -1; + } + + tmp = new_iopbm; + /* Set the bits in our new IOPBM */ + + /* Set the first set of bits to ~0, until we reach the dword of the port */ + + count = port >> 5; + + for (dword_t i=0; i < count; i++) + *(new_iopbm++) = ~0; + + + /* Zero the first dword, in which the port has its bit */ + count = MIN(size , 32 - (port & 0x1F) ); + *(new_iopbm++) = ~(( (dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Zero dwords between first and last dword */ + while( size >= 32){ + *(new_iopbm++) = 0; + size -= 32; + } + + /* Zero the last dword, in which port+size has its bits */ + if (size){ + *(new_iopbm++) = ~( (dword_t)~0 >> (32 - size)); + } + + /* The remainder of the bits is to set to 1 */ + while(new_iopbm < tmp + 2048){ + *(new_iopbm++) = ~0; + } + + return 0; + + } /* if (iopbm == iopbm_phys) */ + else +#endif /* !defined(CONFIG_AUTO_IO_MAP) */ + iopbm = phys_to_virt(iopbm); + + /* Jump to the right location */ + iopbm += (port >> 5); + + /* Zero the first dword, in which the port has its bit */ + count = MIN(size , 32 - (port & 0x1F) ); + + *(iopbm++) &= ~(( (dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Zero dwords between first and last dword */ + while( size >= 32){ + *(iopbm++) = 0; + size -= 32; + } + + /* Zero the last dword, in which port+size has its bits */ + if (size){ + *(iopbm++) &= ~((dword_t)~0 >> (32 - size)); + } + + return 0; +} + +/* + * int set_iopbm() + * + * returns 0 on success + * -1 on error + */ + +static int set_iopbm(tcb_t *task, dword_t port, dword_t size){ + + int count; + ptr_t iopbm; + + iopbm = get_iopbm(task->space); + + // printf("set_iopbm(): port=%x, size=%x, tid=%x\n", port, size, task->myself.raw); + +#if defined(CONFIG_AUTO_IO_MAP) + + /* + * Check if mapper has the default iopbm which is set to 0 everywhere in case of + * implicit mapping enabled. + */ + + if (iopbm == iopbm_phys){ + + iopbm = kmem_alloc(X86_IOPERMBITMAP_SIZE / 8); + + if (iopbm == NULL){ + panic("set_iopbm(): out of memory\n"); + } + + if (install_iopbm(task, (dword_t) iopbm)){ + // printf("set_iopbm(): install_iopbm failed\n"); + return -1; + } + + } + else +#endif + iopbm = phys_to_virt(iopbm); + /* Set the bits in the IOPBM */ + + iopbm += (port >> 5); + + /* Set the first dword, in which the port has its bit */ + + count = MIN(size , 32 - (port & 0x1F) ); + *(iopbm++) |= (((dword_t)~0 >> (32 - count)) << (port & 0x1F)); + + size -= count; + + /* Set dwords between first and last dword */ + while( size >= 32){ + *(iopbm++) = ~0; + size -= 32; + } + + /* Set the last dword, in which port+size has its bits */ + if (size){ + *(iopbm++) |= ( (dword_t)~0 >> (32 - size)); + } + + return 0; + +} + + +#if defined(IO_MDB_DEBUG) +void dump_io_mdb(void){ + io_mnode_t *n = &sigma0_io_space; + while (n){ + printf("io_mnode: lo=%x, hi=%x, tid=%x, depth=%x, addr=%x, parent=%x\n",\ + n->get_lo(), n->get_hi(), n->get_tid(), n->get_depth(), n, n->parent); + n = n->next; + } + +} +#else +void dump_io_mdb(void){} +#endif + +/* + * int unmap_subtree() + * + * modifies (and removes if needed) the subtree below in order to unmap the + * given region out of the subtree + * + */ + +static int unmap_subtree(io_mnode_t *root, dword_t lo, dword_t hi, dword_t mapmask){ + + tcb_t *flushee; + io_mnode_t *n; + + io_mnode_t *n_left_end; + dword_t split_depth; + + /* + * split_depth marks the tree depth of an eventual split, set it to infinite + * in case of splitting the nodes, the depth is the upper bound for splitting + */ + split_depth = IOMDB_SUP_DEPTH; + n_left_end = NULL; + + mapmask &= FLUSH_OWN_SPACE; + + n = mapmask ? root : root->next; + + /* Modify/Remove Subtree */ + while (n->get_depth() > root->get_depth() || mapmask){ + + // printf("n_first->node: %x-%x depth=%x, tid=%x\n", n->get_lo(), + // n->get_hi(), n->get_depth(), n->get_tid()); + + + /* Set mapmask to 0 as we have to remove ourselves only once */ + mapmask = 0; + flushee = tid_to_tcb(n->get_tid()); + + /* Check what we have to do: */ + if (lo <= n->get_lo()){ + + if (hi >= n->get_hi()){ + + // printf("unmap_subtree(): begins before, ends after-> free\n"); + /* We can free the node to flush, as its region is a subset of the io_fp we want to flush */ + + /* Chain out of task list */ + n->deq_thread_list(); + + /* Chain out of subtree */ + n->deq_subtree(); + + if (set_iopbm(flushee, n->get_lo(), n->get_hi() - n->get_lo())){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + /* If the node is not part of a split subtree, set split mark to infinite */ + if (n->get_depth() <= split_depth){ + + split_depth = IOMDB_SUP_DEPTH; + } + + /* Free Node */ + { + io_mnode_t *tmp = n->prev; + mdb_free_buffer((ptr_t) n, sizeof(io_mnode_t)); + n = tmp; + } + } + + else{ + /* io_fp begins before node to flush and ends in or before it */ + printf("unmap_subtree(): begins before, ends in or before\n"); + + if (hi > n->get_lo()){ + + /* io_fp begins before and ends in it, set the IOPBM and resize the node */ + if (set_iopbm(flushee, n->get_lo(), hi - n->get_lo())){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + n->set_lo(hi); + } + + /* If the node is not part of a split subtree, set split mark to infinite */ + if (n->get_depth() <= split_depth){ + + split_depth = IOMDB_SUP_DEPTH; + } + + } + + } + + else{ + /* (lo > n->get_lo()) */ + + if (hi > n->get_hi()){ + + /* io_fp begins in or after node to flush and ends after it */ + // printf("unmap_subtree(): begins in or after, ends after\n"); + + if (lo < n->get_hi()){ + + /* io_fp begins in node to flush: resize it */ + if (set_iopbm(flushee, lo, n->get_hi() - lo)){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + n->set_hi(lo); + + } + + /* If we are in a split subtree, we have to place this node on the left subtree */ + if (n->get_depth() > split_depth){ + + /* Store next node for loop */ + io_mnode_t *n_tmp = n->next; + + /* Chain out of tree */ + n->deq_subtree(); + + /* Chain in tree */ + n->enq_subtree(n_left_end); + + /* New end of left subtree */ + n_left_end = n; + + /* Restore node for loop */ + n = n_tmp->next->prev; + } + + else{ + split_depth = IOMDB_SUP_DEPTH; + } + + } + + else{ + + /* + * io_fp begins and ends in the node to flush - this is the more + * complicated part + * + * - split subtree + * - allocate a new node + * - chain in new node an store it + * - take care about splitting 'til we reach the end of this + * subtree + * + */ + // printf("unmap_subtree(): begins in, ends in ->split\n"); + + if (set_iopbm(flushee, lo, hi - lo)){ + printf("unmap_subtree(): set_iopbm failed\n"); + return -1; + } + + /* The new node is left node */ + io_mnode_t *n_left = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_left == NULL){ + enter_kdebug("unmap_subtree(): out of memory"); + } + + n_left->set_values(n->get_lo(), lo, n->get_tid(), n->get_depth(), 0); + n->set_lo(hi); + + + /* Chain in task list */ + n_left->enq_thread_list(n); + + /* Are we yet in a subtree which has been splitted ? */ + if (n->get_depth() > split_depth){ + + /* Chain in left node */ + n_left->enq_subtree(n_left_end); + + /* + * Parent of left node is either parent of last node or last + * node itself + */ + + n_left->parent = (n_left_end->get_depth() < n_left->get_depth()) ?\ + n_left_end : n_left->parent; + + /* New end of the left part of the split subtree */ + n_left_end = n_left; + + } + + else{ + + /* Chain left node in subtree before n */ + n_left->enq_subtree(n->prev); + + /* Parent of left node is parent of right node */ + n_left->parent = n->parent; + + /* + * Store the beginning depth of the split and the end of the + * left split tree + */ + + split_depth = n->get_depth(); + n_left_end = n_left; + } + } + + } + n = n->next; + + } /* while (n->get_depth() > n_first->get_depth() */ + + return 0; + +} + +/* + * int grant_subtree() + * + * copies the subtree below root valid for granting into a new subtree and + * returns new root + */ + +static io_mnode_t *grant_subtree(io_mnode_t *root, io_mnode_t *dest, tcb_t *to, dword_t lo, dword_t hi){ + + io_mnode_t *n, *new_root, *n_new, *n_cur; + + + /* Allocate new root */ + new_root = n_cur = n_new = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (new_root == NULL){ + panic("grant_subtree(): out of memory"); + } + + /* Setup new root: */ + new_root->set_values(lo, hi, to->myself, root->get_depth(), 0); + new_root->parent = root->parent; + + /* Chain in new root in thread list after dest */ + new_root->enq_thread_list(dest->next_st); + + /* Grant Subtree */ + n = root->next; + + while (n->get_depth() > root->get_depth()){ + if (n->get_lo() < new_root->get_hi() && n->get_hi() > new_root->get_lo()){ + + /* Allocate new children */ + n_new = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_new == NULL){ + panic("grant_subtree(): out of memory"); + } + + /* Setup new child */ + n_new->set_values(MAX(n->get_lo(), new_root->get_lo()),\ + MIN(n->get_hi(), new_root->get_hi()),\ + n->get_tid(),\ + n->get_depth(),\ + 0); + n_new->parent = new_root; + + + /* Chain in in created subtree */ + n_new->prev = n_cur; + n_cur->next = n_new; + + /* + * Chain in in thread list after n + * At the moment, we have two mapping nodes representing the same + * region: + * the old in the subtree below root and the new one below + * new_root. + * We unmap the old one later. But as the old subtree could be + * splitted, we might then have to switch the new nodes in the + * thread list later (*). + */ + n_new->enq_thread_list(n->next_st); + n_cur = n; + + } + n = n->next; + + } + + + /* OK, now unmap the old one */ + + /* Parent of new child will be root->prev */ + root = root->prev; + + /* Unmap subtree below parent */ + if (unmap_subtree(root->next, lo, hi, FLUSH_OWN_SPACE)){ + printf("grant_subtree(): unmap_subtree failed\n"); + return NULL; + } + + /* Chain in created subtree in mapping tree */ + new_root->prev = root; + n_new->next = root->next; + root->next = new_root; + n_new->next->prev = n_new; + + + /* + * (*) Now parse the new subtree and switch nodes in thread list + * Actually, this is not very nice, but it works + */ + n = new_root; + + do{ + if (n->prev_st->get_hi() > n->get_lo()){ + + /* Found a split subtree, therefore switch those two nodes */ + io_mnode_t *tmp = n->prev_st; + + tmp->prev_st->next_st = n; + n->next_st->prev_st = tmp; + + tmp->next_st = n->next_st; + n->next_st = tmp; + + n->prev_st = tmp->prev_st; + tmp->prev_st = n; + + } + n = n->next; + + + } while(n->get_depth() > new_root->get_depth()); + + + + return new_root; +} + +/* + * void io_mdb_init() + */ + +void io_mdb_init(void){ + + // printf("io_mdb_init()"); + /* Store the virtual address of the IOPBM */ + iopbm_virt = (dword_t) __tss.io_bitmap; + + /* Get physical Address of the default IOPBM */ + kspace = get_kernel_space(); + + /* Get physical address of the default IOPBM */ + iopbm_phys = get_iopbm(kspace); + + /* This is the Pagetable containing the entry to the IOPM */ + iopbm_pgt = kspace->pgent(pgdir_idx(iopbm_virt))->subtree(kspace,0); + + +#if defined(CONFIG_IA32_FEATURE_PGE) + /* Set the pagetable entries for IOPBM to non-global if PGE enabled */ + iopbm_pgt->next(kspace, pgtab_idx(iopbm_virt))->set_flags(kspace, 0, PAGE_VALID | PAGE_WRITABLE); + iopbm_pgt->next(kspace, pgtab_idx(iopbm_virt + 0x1000))->set_flags(kspace, 0, PAGE_VALID | PAGE_WRITABLE); + + /* Flush the corresponding TLB entries */ + flush_tlbent((ptr_t)iopbm_virt); + flush_tlbent((ptr_t)(iopbm_virt + 0x1000)); + +#endif + + /* Set the default IOPBM Bits to the default value */ + + for (int i=0; i < 2048; i++) + ((ptr_t)(iopbm_virt))[i] = IOPBM_DEFAULT_VALUE; + +#if defined(CONFIG_ENABLE_PVI) + /* Enable PVI Bit */ +#warning Setting PVI bit in CR4 will not work with vmware + enable_pvi(); +#endif + + /* Clear lock */ + io_mdb_lock = 0; +} + +/* + * void io_mdb_init_sigma0(); + * + * implicit map of 64k IO-Space to sigma0 on its creation + * (we can't do this during io_mdb_init as no sigma0 exists at this time) + * + */ +void io_mdb_init_sigma0(void){ + + + /* Dummy node */ + io_mnode_t *n = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n->set_values(0, 0, L4_SIGMA0_ID, 0, 1); + + + /* dummy node is beginning of io_space */ + set_iospace(sigma0, n); + + n->parent = NULL; + + io_mnode_t *start = &sigma0_io_space; + io_mnode_t *end = &io_mdb_end; + + /* Setup our initial sigma0-node */ + start->set_values(0, (1<<16), L4_SIGMA0_ID, 0, 0); + start->parent = start; + + /* Setup the IO-MDB Terminator */ + end->set_values(0, 0, L4_SIGMA0_ID, 0, 0); + + + /* Enqueue in Subtree */ + start->next = end; + end->prev = start; + start->prev = end->next = NULL; + + /* Enqueue in Thread List */ + start->prev_st = start->next_st = n; + n->next_st = n->prev_st = start; + + dword_t ufl = get_user_flags(sigma0); + /* Set IOPL to 3 */ + ufl |= (3 << 12); + set_user_flags(sigma0, ufl); +} + + +/* + * void io_mdb_task_new(); + * + * dummy node creation + * implicit map of 64k IO-Space (if configured) + * + */ + +void io_mdb_task_new(tcb_t *pager, tcb_t *task){ + + /* Dummy node */ + io_mnode_t *n = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n->set_values(0, 0, task->myself, 0, 1); + + /* dummy node is beginning of io_space */ + set_iospace(task, n); + + n->next_st = n->prev_st = n; + + n->parent = NULL; + +#if defined(CONFIG_AUTO_IO_MAP) + + /* Create implicit mapping node n_i */ + io_mnode_t *c; + c = get_iospace(pager); + + /* + * Check: + * if the calling task is already protected from accessing IO-Ports, + * the new task will not get access to any ports at all. + */ + + if (c->get_lo() != 0 || c->get_hi() != (1 << 16)) + return; + + io_mnode_t *n_i = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (n_i == NULL){ + enter_kdebug("io_mdb_task_new(): out of memory"); + } + + n_i->set_values(0, (1<<16), task->myself, c->get_depth() + 1, 0); + n_i->parent = n; + + /* Paseeren */ + io_mdb_p(); + + /* Chain in in Subtree */ + n_i->enq_subtree(c); + + /* Verlaaten */ + io_mdb_v(); + + /* Chain in Task List (before n, which is after n) */ + n_i->enq_thread_list(n); + + dump_io_mdb(); + enter_kdebug(); +#endif +} + +/* + * void io_mdb_task_delete(); + * + * removing crap on task deletion + * + * TODO: unmap 64K ! + */ + +void io_mdb_delete_iospace(tcb_t *tcb){ + + + release_iopbm(tcb); + + io_mnode_t *n = get_iospace(tcb); + + if (n == NULL) + return; + + while (!n->get_dummy()){ + n->deq_subtree(); + n = n->next_st; + mdb_free_buffer((ptr_t) n->prev_st, sizeof(io_mnode_t)); + + } + /* Free dummy node */ + mdb_free_buffer((ptr_t) n, sizeof(io_mnode_t)); + + set_iospace(tcb, (io_mnode_t *) NULL); +} + +/* + * int map_io_fpage() + * + * maps an IO-Fpage + * + * returns 0 on success + * -1 on error + */ + +int map_io_fpage(tcb_t *from, tcb_t *to, fpage_t io_fp){ + + io_mnode_t *parent, *dest, *tmp; + dword_t hi, lo; + + if (IOFP_SIZE(io_fp.raw) > (1<<16)){ + printf("map_io_fpage(): wrong size\n"); + return -1; + } + + /* Get mappers and mappees first io node and jump over dummy node */ + parent = get_iospace(from); + dest = get_iospace(to); + + /* paseeren */ + io_mdb_p(); + + + while(!parent->get_dummy()){ + + lo = IOFP_PORT(io_fp.raw); + hi = lo + IOFP_SIZE(io_fp.raw); + + /* is parent an associated mapping node to fpage (i.e. is their intersection not empty) ? */ + if (parent->get_lo() < hi){ + + if (parent->get_hi() > lo){ + + // printf("map_io_fpage(): parent->get_lo = %x, parent->get_hi = + // %x\n",parent->get_lo(), parent->get_hi()); + + + /* Check parents, to avoid recursive mappings */ + for (io_mnode_t *p = parent; p->get_tid().x0id.task != L4_SIGMA0_ID.x0id.task; p = p->parent){ + if (p->get_tid().x0id.task == to->myself.x0id.task){ + printf("map_io_fpage(): no recursive mappings"); + } + break; + } + + + /* Calculate the actual lower and higher bound to map */ + lo = MAX(IOFP_PORT(io_fp.raw), parent->get_lo()); + hi = MIN((IOFP_PORT(io_fp.raw) + IOFP_SIZE(io_fp.raw)), parent->get_hi()); + + /* + * Unmap region out of destination's IO-AS and search for the + * entry of the new mapping + */ + + + while(!dest->get_dummy()){ + if (dest->get_lo() < hi){ + /* Could be that we loose the node, save next */ + tmp = dest->next_st; + if (dest->get_hi() > lo){ + // printf("map_io_fpage: unmap_subtree()\n"); + if (unmap_subtree(dest, lo, hi, FLUSH_OWN_SPACE)){ + printf("map_io_fpage(): unmap_subtree failed\n"); + return -1; + } + } + dest = tmp; + } + else break; + } + + /* The entry of the new mapping node */ + dest = dest->prev_st; + + io_mnode_t *child; + + if (io_fp.fpage.grant){ + /* grant subtree */ + + // printf("map_io_fpage(): grant operation\n"); + if ((child = grant_subtree(parent, dest, to, lo, hi)) == NULL){ + printf("map_io_fpage(): grant_subtree failed\n"); + return -1; + } + + } + + else{ + /* Map */ + + /* Create the mapping */ + child = (io_mnode_t *) mdb_alloc_buffer(sizeof(io_mnode_t)); + + if (child == NULL){ + panic("map_io_fpage(): out of memory"); + } + + /* Setup child */ + child->set_values(lo, hi, to->myself, parent->get_depth() + 1, 0); + child->parent = parent; + child->enq_subtree(parent); + + /* Hook child into mappees thread list after dest */ + child->enq_thread_list(dest->next_st); + + } + + + /* Zero IOPBM */ + if (zero_iopbm(to, child->get_lo(), child->get_hi() - child->get_lo())){ + printf("map_io_fpage(): zero_iopbm failed\n"); + return -1; + + } + + + } /* if (parent->get_hi() > lo) */ + + /* Next mapping node */ + parent = parent->next_st; + + } /* if (parent->get_lo() < hi) */ + + /* if parent node begins after fpage, done */ + else break; + } + + dump_io_mdb(); + + /* Verlaaten */ + io_mdb_v(); + + return 0; +} +/* + * int unmap_io_fpage() + * + * unmaps an IO-Fpage + * + */ + +void unmap_io_fpage(tcb_t *from, fpage_t io_fp, dword_t mapmask){ + + io_mnode_t *parent, *tmp; + dword_t hi, lo; + + + lo = IOFP_PORT(io_fp.raw); + hi = lo + IOFP_SIZE(io_fp.raw); + + if (IOFP_SIZE(io_fp.raw) > (1<<16)){ + printf("unmap_io_fpage(): wrong size\n"); + return; + } + + + /* Get mappers first io node */ + parent = get_iospace(from); + + // printf("unmap_io_fpage: lo = %x, hi = %x\n", lo, hi); + + /* Paseeren */ + io_mdb_p(); + + while(!parent->get_dummy()){ + + /* is parent an associated mapping node ? */ + if (parent->get_lo() < hi){ + + /* Could be that we loose parent */ + tmp = parent->next_st; + if (parent->get_hi() > lo){ + // printf("unmap_io_fpage: parent->get_lo = %x, parent->get_hi = + // %x\n", parent->get_lo(), parent->get_hi()); + if (unmap_subtree(parent, lo, hi, mapmask)){ + // printf("unmap_io_fpage(): unmap_subtree failed\n"); + return; + } + } + parent = tmp; + } + + else break; + } + + + dump_io_mdb(); + /* Verlaaten */ + io_mdb_v(); + +} + +#endif /* (CONFIG_IO_FLEXPAGES) */ diff --git a/kernel/src/x86/io_mapping.o b/kernel/src/x86/io_mapping.o new file mode 100644 index 0000000..beae8c3 Binary files /dev/null and b/kernel/src/x86/io_mapping.o differ diff --git a/kernel/src/x86/libarch.a b/kernel/src/x86/libarch.a new file mode 100644 index 0000000..96232c0 Binary files /dev/null and b/kernel/src/x86/libarch.a differ diff --git a/kernel/src/x86/memory.c b/kernel/src/x86/memory.c new file mode 100644 index 0000000..0c7126f --- /dev/null +++ b/kernel/src/x86/memory.c @@ -0,0 +1,1027 @@ +/********************************************************************* + * + * Copyright (C) 1999-2002, Karlsruhe University + * + * File path: x86/memory.c + * Description: X86 specific memory management functions. + * + * @LICENSE@ + * + * $Id: memory.c,v 1.101 2002/05/14 13:08:53 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include +#include +#include +#include + +#define PF_USERMODE(x) (x & PAGE_USER) +#define PF_WRITE(x) (x & PAGE_WRITABLE) +#define PF_PROTECTION(x) (x & 0x1) + +#define FP_NUM_PAGES(x) (1 << (((x & 0xfc) >> 2) - PAGE_BITS)) +#define FP_ADDR(x) (x & PAGE_MASK) +#define FP_BASE_MASK(x) ((~0U) >> (32 - ((x & 0xfc) / 4))) + +#ifdef CONFIG_DEBUG_DOUBLE_PF_CHECK +static dword_t last_pf_addr = ~0; +static tcb_t * last_pf_tcb = NULL; +#endif + + +/* + * Page sizes handled by the hardware. + */ + +dword_t hw_pgshifts[HW_NUM_PGSIZES+1] = { 12, 22, 32 }; + +/* + * Page sizes handled in the mapping database. + */ + +dword_t mdb_pgshifts[NUM_PAGESIZES+1] = { 12, 22, 32 }; + +/* + * Allocation sizes handled by the mapping database allocator. + */ +mdb_buflist_t mdb_buflists[] = { + { 12 }, // Mapping nodes + { 8 }, // ptrnode_t + { 4096 }, // 4KB array +#if defined(CONFIG_IO_FLEXPAGES) + { 28 }, // IO-Mapping-Nodes +#endif + { 0 } +}; + +#if defined(CONFIG_SMP) +# define SPACE_ALLOC_SIZE (PAGE_SIZE * CONFIG_SMP_MAX_CPU) +#else +# define SPACE_ALLOC_SIZE (PAGE_SIZE) +#endif + + +/* + * Function create_space () + * + * Called from create_tcb() when a new address space is created. + * + */ +space_t * create_space (void) +{ + space_t *nspace = (space_t *) virt_to_phys + (kmem_alloc (SPACE_ALLOC_SIZE * 2)); + space_t *kspace = get_kernel_space (); + pgent_t *pg_n = nspace->pgent (TCB_AREA >> PAGEDIR_BITS); + pgent_t *pg_k = kspace->pgent (TCB_AREA >> PAGEDIR_BITS); + + /* Copy TCB area and kernel area. */ + for (int i = (TCB_AREA >> PAGEDIR_BITS); i < 1024; i++) + { + pg_n->copy (nspace, 1, pg_k, kspace, 1); + pg_n = pg_n->next (nspace, 1, 1); + pg_k = pg_k->next (kspace, 1, 1); + } + +#if defined(CONFIG_ENABLE_SMALL_AS) + /* Set to large space. */ + nspace->set_smallid (SMALL_SPACE_INVALID); +#endif + +#if defined(CONFIG_SMP) + /* Free up unused shadow page directories. */ + dword_t tmp = (dword_t) nspace->pagedir () + SPACE_ALLOC_SIZE; + for (int cpu = 1; cpu < CONFIG_SMP_MAX_CPU; cpu++) + kmem_free ((ptr_t) (tmp + PAGE_SIZE * cpu), PAGE_SIZE); + + /* fixup the cpu-local mappings */ + for (int cpu = 0; cpu < CONFIG_SMP_MAX_CPU; cpu++) + { + extern char _start_cpu_local; + pg_n = nspace->pgent(pgdir_idx((dword_t)&_start_cpu_local), cpu); + pg_k = kspace->pgent(pgdir_idx((dword_t)&_start_cpu_local), cpu); + pg_n->copy_nosync(nspace, 1, pg_k, kspace, 1); + } +#endif + + return nspace; +} + + +/* + * Function delete_space (space) + * + * Called from task_delete (). + * + */ +void delete_space (space_t * space) +{ +#if defined(CONFIG_ENABLE_SMALL_AS) + if (space->is_small ()) + small_space_to_large (space); + + /* + * VU: If we run in a small space we better switch to our own + * pagetable, because otherwise it may disappear. + */ + if (get_current_tcb ()->space->is_small ()) + set_current_pagetable (get_current_tcb ()->space->pagedir_phys ()); +#endif + + /* Flush whole address space. */ + fpage_unmap (space, FPAGE_WHOLE_SPACE, FPAGE_OWN_SPACE + FPAGE_FLUSH); + + /* Delete page directory. */ + kmem_free ((ptr_t) space->pagedir (), SPACE_ALLOC_SIZE); + + /* Free up shadow page directory. */ + kmem_free ((ptr_t) ((dword_t) space->pagedir () + SPACE_ALLOC_SIZE), + PAGE_SIZE); +} + + +#if defined(CONFIG_ENABLE_SMALL_AS) + +extern "C" void ipc_sysenter_small (void); +static int restart_ipc (tcb_t *); + +#if defined(CONFIG_GLOBAL_SMALL_SPACES) +static void modify_global_bits (space_t *, pgent_t *, int, int); +#endif + + +/* + * Array containing pagedir pointers for the spaces who've allocated + * the space slots. + */ + +space_t * small_space_owner[MAX_SMALL_SPACES]; + + +/* + * Function make_small_space (space, smallid) + * + * Make a small space of SPACE. We also allow for extending a + * small space, but only if the space starts at the same pgdir + * position. Making a space smaller is currently not supported. + * Return 0 upon success, -1 upon error. + * + */ +int make_small_space (space_t * space, byte_t smallid) +{ + smallid_t small; + small.set_value (smallid); + + dword_t size = small.size (); + dword_t idx = small.idx (); + int i; + + /* Check for previoulsy allocated slots. */ + for ( i = 0; i < MAX_SMALL_SPACES; i++ ) + { + if ( small_space_owner[i] == space && + ((dword_t) i < idx || (dword_t) i >= idx+size) ) + goto Space_failed; + } + + /* Try allocating space slots. */ + for ( i = 0; i < (int) size; i++ ) + { + if ( small_space_owner[idx + i] == 0 ) + small_space_owner[idx + i] = (space_t *) ((dword_t) space | 1); + else if ( small_space_owner[idx + i] != space ) + break; + } + + /* Did we manage to allocate all slots? */ + if ( i < (int) size ) + { + while ( i > 0 ) + /* Do not deallocate previously allocated slots. */ + if ( small_space_owner[idx + i] != space ) + small_space_owner[idx + i] = 0; + + Space_failed: + TRACEPOINT(SET_SMALL_SPACE_FAILED, + printf("Creating small space %2x failed [size=%d idx=%d]\n", + small, size, idx)); + return -1; + } + + /* Fixup newly allocated slots. */ + for ( i = 0; i < (int) size; i++ ) + small_space_owner[idx + i] = space; + + tcb_t *t = get_idle_tcb(); + do { + /* + * If a thread in the same address space is in the middle of a + * long IPC, the memory pointers used in the IPC will be + * incorrect in a small space context. We must therefore + * restart any such ongoing (and active) IPC operations. + */ + if ((t->space == space) && (~t->thread_state & TSB_LOCKED)) + restart_ipc(t); + + t = t->present_next; + } while ( t != get_idle_tcb() ); + + +#if defined(CONFIG_GLOBAL_SMALL_SPACES) + modify_global_bits (space, space->pgent (0), small.bytesize (), 1); +#endif + +#if defined(CONFIG_IA32_FEATURE_SEP) + static int uses_small_spaces = 0; + + if ( ! uses_small_spaces ) + { + /* + * Once we start using small spaces, we must switch to the + * version of ipc_sysenter that saves/restores segment + * registers. + */ + asm (" sub %%edx, %%edx \n" + " wrmsr /* SYSENTER_EIP_MSR */ \n" + : + :"c"(0x176), "a"(ipc_sysenter_small) + :"edx"); + + extern dword_t return_from_sys_ipc; + extern dword_t return_from_sys_ipc_small; + t = get_idle_tcb(); + do { + /* + * Make sure that ongoing ipc_sysenter operations are + * returned through the `ipc_sysenter_small' handler (so + * that segment registers are loaded properly). + */ + if ( t->stack < (ptr_t) &get_tcb_stack_top(t)[IPCSTK_RETADDR] && + (get_tcb_stack_top(t)[IPCSTK_RETADDR] == + (dword_t) &return_from_sys_ipc) ) + { + get_tcb_stack_top(t)[IPCSTK_RETADDR] = + (dword_t) &return_from_sys_ipc_small; + } + + t = t->present_next; + } while ( t != get_idle_tcb() ); + + uses_small_spaces = 1; + } +#endif /* CONFIG_IA32_FEATURE_SEP */ + + space->set_smallid (small); + + if (space == get_current_space ()) + { + /* Reset GDT entries to have proper limits. */ + extern seg_desc_t gdt[]; + gdt[X86_UCS >> 3].set_seg ((void *) small.offset (), + small.bytesize () - 1, + 3, GDT_DESC_TYPE_CODE); + gdt[X86_UDS >> 3].set_seg ((void *) small.offset (), + small.bytesize () - 1, + 3, GDT_DESC_TYPE_DATA); + reload_user_segregs (); + + /* Inform thread switch code that we run in a small space. */ + extern dword_t __is_small; + __is_small = 1; + } + + return 0; +} + + +/* + * Function small_space_to_large (space) + * + * Promote the small space into a large one. This is an expensive + * operation since all page tables in the system has to be modified + * so that they no longer contain any pagedir entries from the + * previous small space. + * + * It is possible to make this operation cheaper by keeping some + * versioning info in all pagetables and let the padedir entry + * deletion happen lazily upon context switches. Such an approach + * would, however, make context switch times more unpredictable. + * + */ +void small_space_to_large (space_t * space) +{ + smallid_t small = space->smallid (); + dword_t idx = small.pgdir_idx (); + dword_t size = small.size (); + dword_t *p, i; + tcb_t *t; + int restarted_current = 0; + + space->set_smallid (SMALL_SPACE_INVALID); + +#if defined(CONFIG_GLOBAL_SMALL_SPACES) + modify_global_bits (space, space->pgent (0), small.bytesize (), 0); +#endif + + t = get_idle_tcb (); + do { + /* Remove stale pagedir entries. */ + p = t->space->pagedir (); + for (i = 0; i < (size * SMALL_SPACE_MIN/4); i++) + p[idx + i] = 0; + + /* + * If a thread in the same address space is in the middle of a + * long IPC, the memory pointers used in the IPC will be + * incorrect when enlarging the space. We must therefore + * restart any such ongoing (and active) IPC operations. + */ + if ((t->space == space) && (~t->thread_state & TSB_LOCKED)) + restarted_current |= restart_ipc (t); + + t = t->present_next; + } while (t != get_idle_tcb ()); + + TRACEPOINT (ENLARGE_SPACE); + + /* Deallocate pagedir slots. Must be done last. */ + idx = small.idx (); + for (i = 0; i < size; i++) + small_space_owner[idx + i] = NULL; + + if (get_current_tcb ()->space == space) + { + /* Reset GDT entries to 3GB limit. */ + extern seg_desc_t gdt[]; + gdt[X86_UCS >> 3].set_seg (0, USER_AREA_MAX-1, 3, GDT_DESC_TYPE_CODE); + gdt[X86_UDS >> 3].set_seg (0, USER_AREA_MAX-1, 3, GDT_DESC_TYPE_DATA); + reload_user_segregs (); + + /* Make sure that we run on our own page table. */ + set_current_pagetable (space->pagedir_phys ()); + + /* Inform thread switch code that we run in a large space. */ + extern dword_t __is_small; + __is_small = 0; + } + + /* + * Flush complete TLB (including global pages) by modifying the + * PGE bit in cr4. + */ + asm volatile ( + " movl %%cr4, %%eax \n" + " andl %0, %%eax \n" + " movl %%eax, %%cr4 \n" + " movl %%cr3, %%ebx \n" + " movl %%ebx, %%cr3 \n" + " orl %1, %%eax \n" + " movl %%eax, %%cr4 \n" + : + : "i" (~X86_CR4_PGE), "i" (X86_CR4_PGE) + : "eax", "ebx"); + + if (restarted_current) + { + /* + * If an IPC in the current thread was restarted, we must + * reenter the sys_ipc function instead of returning. + */ + asm volatile ( + " movl %0, %%esp \n" + " ret \n" + : + : "r" (get_current_tcb ()->stack)); + /* NOTREACHED */ + } +} + + +/* + * Function restart_ipc (tcb) + * + * Restart the IPC operation in which `tcb' is involved. It is + * assumed that the `tcb' is involved in an IPC with its partner. + * Return non-nil if `tcb' or its partner is the current thread, + * otherwise nil. + * + */ +static int restart_ipc(tcb_t *tcb) +{ + tcb_t *current = get_current_tcb(); + tcb_t *partner = tid_to_tcb(tcb->partner); + + enter_kdebug("Restart ipc --- press `g' and tell Espen if this works"); + TRACEPOINT(RESTART_IPC, + printf("Restart IPC (tcb %p, partner %p)\n", tcb, partner)); + + /* + * Cancel ongoing IPC operations. Set unwind_ipc_sp so that stack + * contents are not overwritten. + */ + + tcb->unwind_ipc_sp = get_tcb_stack_top(tcb) - 9; + partner->unwind_ipc_sp = get_tcb_stack_top(partner) - 9; + unwind_ipc(tcb); + + /* + * If thread is inside send phase, restart whole IPC. If thread + * is inside receive phase, cancel send phase by setting the send + * descriptor to nil. + */ + + if ( tcb->flags & TF_SENDING_IPC ) + tcb->flags &= ~TF_SENDING_IPC; + else + get_tcb_stack_top(tcb)[IPCSTK_SNDDESC] = 0xffffffff; + + if ( partner->flags & TF_SENDING_IPC ) + partner->flags &= ~TF_SENDING_IPC; + else + get_tcb_stack_top(partner)[IPCSTK_SNDDESC] = 0xffffffff; + + /* + * Push sys_ipc on the stacks, making thread_switch reenter the + * sys_ipc function when thread is rescheduled. + */ + + void sys_ipc(l4_threadid_t, dword_t, dword_t); + tcb_stack_push(tcb, (dword_t) sys_ipc); + tcb_stack_push(partner, (dword_t) sys_ipc); + + tcb->thread_state = partner->thread_state = TS_RUNNING; + tcb->resources &= ~TR_LONG_IPC_PTAB; + partner->resources &= ~TR_LONG_IPC_PTAB; + + return (tcb == current) || (partner == current); +} + +#if defined(CONFIG_GLOBAL_SMALL_SPACES) + +/* + * Function modify_global_bits (space, pg, size, onoff) + * + * Set the global bit in page directory and page table entries as + * specified by ONOFF. SIZE indicates the number of entries to + * modify. + * + */ +static void modify_global_bits (space_t * space, pgent_t * pg, + int size, int onoff) +{ + while (size > 0) + { + if (pg->is_valid (space)) + { + if (onoff == 0) pg->x.raw &= ~PAGE_GLOBAL; + else pg->x.raw |= PAGE_GLOBAL; + + if (pg->is_subtree (space, 1)) + { + pgent_t *pg2 = pg->subtree (space, 1); + for (int i = 1024; i > 0; i--) + { + if (pg2->is_valid (space)) + { + if (onoff == 0) pg2->x.raw &= ~PAGE_GLOBAL; + else pg2->x.raw |= PAGE_GLOBAL; + } + pg2 = pg2->next (space, 1); + } + } + } + + size -= PAGEDIR_SIZE; + pg = pg->next (space, 1); + } +} + +#endif /* CONFIG_GLOBAL_SMALL_SPACES */ +#endif /* CONFIG_ENABLE_SMALL_AS */ + + +/********************************************************************** + * temporary mapping for IPC + * the resource bits are set in the pagefault handler!!! + */ + +ptr_t get_copy_area(tcb_t * from, tcb_t * to, ptr_t addr) +{ +#if defined(CONFIG_ENABLE_SMALL_AS) + smallid_t small_from = from->space->smallid (); + smallid_t small_to = to->space->smallid (); + + if (small_to.is_valid ()) + { + /* + * Use small space area of target address space. + */ + TRACEPOINT(SMALL_SPACE_RECEIVER); + return (ptr_t) ((dword_t) addr + small_to.offset ()); + } + else if (small_from.is_valid ()) + { + /* + * Use normal address for target address space and make sure + * that target address spaces' page tables are used. + */ + TRACEPOINT(SMALL_SPACE_SENDER); + from->resources |= TR_LONG_IPC_PTAB; + if (get_current_space() != to->space) + set_current_pagetable (to->space->pagedir_phys ()); + return addr; + } +#endif + + dword_t *pgdir_from = from->space->pagedir (); + dword_t *pgdir_to = tid_to_tcb(from->partner)->space->pagedir (); + + if ( from->copy_area1 == COPYAREA_INVALID ) + { + /* Nothing mapped yet. Use copy area 1. */ + from->copy_area1 = (dword_t) addr & PAGEDIR_MASK; + + pgdir_from[pgdir_idx(MEM_COPYAREA1)] = + pgdir_to[pgdir_idx((dword_t) addr)]; + pgdir_from[pgdir_idx(MEM_COPYAREA1)+1] = + pgdir_to[pgdir_idx((dword_t) addr)+1]; + + from->resources |= TR_IPC_MEM1; + return (ptr_t) (((dword_t) addr & ~PAGEDIR_MASK) + MEM_COPYAREA1); + } + else + { + if ( from->copy_area1 == ((dword_t) addr & PAGEDIR_MASK) ) + { + /* Copy area 1 contains the correct mapping. */ + return (ptr_t) (((dword_t) addr & ~PAGEDIR_MASK) + MEM_COPYAREA1); + } + else if ( from->copy_area2 == ((dword_t) addr & PAGEDIR_MASK) ) + { + /* + * Copy area 2 contians the correct mapping. Also works if + * area is invalid. + */ + return (ptr_t) (((dword_t) addr & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + else + { + /* Use copy area 2. */ + pgdir_from[pgdir_idx(MEM_COPYAREA2)] = + pgdir_to[pgdir_idx((dword_t) addr)]; + pgdir_from[pgdir_idx(MEM_COPYAREA2)+1] = + pgdir_to[pgdir_idx((dword_t) addr)+1]; + + if ( from->resources & TR_IPC_MEM2 ) + { + /* + * Copy area 2 in use (i.e., worst case). We have to + * flush the existing TLB entries. + */ + enter_kdebug("remap copy_area2"); + flush_tlb(); + } + else + from->resources |= TR_IPC_MEM2; + + from->copy_area2 = (dword_t) addr & PAGEDIR_MASK; + return (ptr_t) (((dword_t) addr & ~PAGEDIR_MASK) + MEM_COPYAREA2); + } + } + + /* NOTREACHED */ + return 0; +} + +void free_copy_area(tcb_t * tcb) +{ + tcb->copy_area1 = COPYAREA_INVALID; + tcb->copy_area2 = COPYAREA_INVALID; +} + + + +/********************************************************************** + * pagefault handling + */ + +void pagefault(dword_t edx, dword_t ecx, dword_t eax, dword_t errcode, dword_t ip) +{ + /* The first three arguments of this function are dummy arguments - they + have been pushed to the stack by the exception handler to save them + over the C function call and restore them afterwards. */ + + // fault is already pf-protocol compliant + dword_t fault = (get_pagefault_address() & (~PAGE_WRITABLE)) | (errcode & PAGE_WRITABLE); + // we need it in 99% of the interesting cases... + tcb_t * current = get_current_tcb(); + + /* Correct `current' for pagefaults happening on the kdebug stack. */ + if ( (dword_t) current > TCB_AREA + TCB_AREA_SIZE ) + { + extern dword_t _kdebug_saved_esp; + current = ptr_to_tcb((ptr_t) _kdebug_saved_esp); + } + + +#ifdef CONFIG_DEBUG_DOUBLE_PF_CHECK + if (last_pf_addr == fault && last_pf_tcb == current) { + printf("double pagefault (%x)\n", fault); + enter_kdebug(); + } + last_pf_addr = fault; + last_pf_tcb = current; +#endif + +#if defined(CONFIG_DEBUGGER_KDB) && defined(CONFIG_DEBUG_BREAKIN) + // if we have a kernel pagefault loop no timer interrupts are raised :( + kdebug_check_breakin(); +#endif + + /*---- user pagefault ------------------------------------------------*/ + if ( PF_USERMODE(errcode) ) + { +#ifdef CONFIG_DEBUG_TRACE_UPF + if (__kdebug_pf_tracing) { + printf("upf: thread: %x @ %x ip: %x, err: %x, cr3: %x\n", + current, fault, ip, errcode, get_current_pagetable()); + if (__kdebug_pf_tracing > 1) + enter_kdebug("upf"); + } +#endif + + if ( fault >= TCB_AREA ) + { + printf("upf (%x): %x @ %x, err: %x\n", + current, fault, ip, errcode); + enter_kdebug("user touches kernel area"); +#warning: REVIEWME: thread shoot-down is experimental + extern void unwind_ipc(tcb_t*); + unwind_ipc(current); + thread_dequeue_ready(current); + thread_dequeue_wakeup(current); + current->thread_state = TS_ABORTED; + while (1) + switch_to_idle(current); + } + + if (same_address_space (current, sigma0)) + { + /* + * Sigma0 pagefaults are simple map operations. Bypass + * the mdb_map() operation. + */ + ASSERT(fault < TCB_AREA); + + pgent_t *pg = current->space->pgent (pgdir_idx (fault)); + pg->set_address (current->space, 1, fault & PAGEDIR_MASK); + pg->set_flags (current->space, 1, PAGE_SIGMA0_BITS); + } + else + { + /* + * Other pagefaults generate pagefault IPCs. + */ + current->ipc_timeout = TIMEOUT_NEVER; + +#if defined(CONFIG_ENABLE_SMALL_AS) + space_t * mspace = current->space; + if (mspace->is_small ()) + { + /* + * Check if we can simply copy a valid pagedir entry + * from the master page table. If not, fall through + * and perform pagefault IPC (with translated fault + * address). + */ + space_t *fspace = get_current_space (); + pgent_t *pg_f = fspace->pgent (pgdir_idx (fault)); + fault -= mspace->smallid ().offset (); + pgent_t *pg_m = mspace->pgent (pgdir_idx (fault)); + + if (pg_m->is_valid (mspace) && (! pg_f->is_valid (fspace))) + { + /* Copy valid pagedir entry and try again. */ + TRACEPOINT (COPY_SMALL_PDIRENT); + pg_f->copy (fspace, 1, pg_m, mspace, 1); + return; + } + } +#endif + +#if defined(CONFIG_DEBUG_TRACE_UPF) + if (__kdebug_pf_tracing) + printf("do_pf_ipc(%x, %x, %x)\n", current, fault, ip); +#endif + do_pagefault_ipc(current, fault, ip); + } + + return; + } + + /*---- kernel pagefault ----------------------------------------------*/ + +#ifdef CONFIG_DEBUG_TRACE_KPF + if (__kdebug_pf_tracing) { + printf("kpf: thread: %x @ %x ip: %x, err: %x, cr3: %x\n", + current, fault, ip, errcode, get_current_pagetable()); +#ifdef CONFIG_SMP + printf("cpu: %d/%d\n", get_cpu_id(), get_apic_cpu_id()); +#endif + if (__kdebug_pf_tracing > 1) + enter_kdebug("kpf"); + } +#endif + + /* Pointer to the pgent we faulted on. */ + space_t *fspace = get_current_space (); + pgent_t *pg_f = (pgent_t *) fspace->pgent (pgdir_idx (fault)); + + if ( fault < TCB_AREA ) + { + /* + * This is most likely a string copy pf. Registers are + * already transfered, ipc_buffer[...] can therefore be + * spilled. Alternatively, we might have caught a pagefault + * in the instruction parsing or LIDT emulation of the GP + * exception handler -- we may treat those faults in the same + * manner as string copy faults. + */ + +#if defined (CONFIG_DEBUG_SANITY) + if (current->space == sigma0->space) + panic("Sigma0 - kpf in user area"); +#endif + + TRACEPOINT_2PAR(KERNEL_USER_PF, fault, ip, + printf("kpf: thread: %x @ %x ip: %x, err: %x, cr3: %x\n", + current, fault, ip, errcode, get_current_pagetable())); + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( fault >= SMALL_SPACE_START ) + { + tcb_t *partner = tid_to_tcb(current->partner); + space_t *mspace = current->space; + space_t *pspace = partner->space; + smallid_t small_m = mspace->smallid (); + smallid_t small_p = partner->space->smallid (); + + if (small_m.is_valid () && + fault >= small_m.offset () && + fault < (small_m.offset () + small_m.bytesize ())) + { + /* + * Pagefault in current small space. + */ + fault -= small_m.offset (); + pgent_t *pg_m = mspace->pgent (pgdir_idx (fault)); + + if (pg_m->is_valid (mspace) && (!pg_f->is_valid (fspace))) + { + /* Copy valid pagedir entry and try again. */ + pg_f->copy (fspace, 1, pg_m, mspace, 1); + return; + } + } + else if ((~current->thread_state & TSB_LOCKED) && + small_p.is_valid () && + fault >= small_p.offset () && + fault < (small_p.offset () + small_p.bytesize ())) + { + /* + * Pagefault in partner's small space (i.e., during + * long IPC). + */ + fault -= small_p.offset (); + pgent_t *pg_p = pspace->pgent (pgdir_idx (fault)); + + if ((!pg_p->is_valid (pspace)) || pg_f->is_valid (fspace)) + { + /* + * Master pagedir or pagetab entry not present, + * tunnel pagefault through partner. + */ + dword_t *saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, fault, + (dword_t) current); + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + dispatch_thread(partner); + partner->stack = saved_stack; + } + + /* Copy valid pagedir entry. */ + pg_f->copy (fspace, 1, pg_p, pspace, 1); + return; + } + else + panic("kernel pagefault in small space"); + } + + /* IPC buffer must be saved in case we have to restart IPC. */ + dword_t ipc_buf[3] = { current->ipc_buffer[0], + current->ipc_buffer[1], + current->ipc_buffer[2] }; +#endif + + l4_threadid_t saved_partner = current->partner; + dword_t saved_state = current->thread_state; + timeout_t to = current->ipc_timeout; + + TRACEPOINT(STRING_COPY_PF, + printf("String copy pagefault (%p @ %p) ip=%p\n", + current, fault, ip); + kdebug_dump_frame((exception_frame_t *) + get_tcb_stack_top(current) - 1)); + + current->ipc_timeout = + GET_SEND_PF_TIMEOUT(tid_to_tcb(current->partner)->ipc_timeout); + do_pagefault_ipc(current, fault, 0xffffffff /*ip*/); + + current->partner = saved_partner; + current->ipc_timeout = to; + current->thread_state = saved_state; +#if defined(CONFIG_ENABLE_SMALL_AS) + current->ipc_buffer[0] = ipc_buf[0]; + current->ipc_buffer[1] = ipc_buf[1]; + current->ipc_buffer[2] = ipc_buf[2]; +#endif + return; + } + + + if (fault < (TCB_AREA + TCB_AREA_SIZE)) + { + space_t *kspace = get_kernel_space (); + pgent_t *pg_k = kspace->pgent (pgdir_idx (fault)); + + /* + * Try syncing TCB area, but not if running on kernel ptab. + */ + + if (pg_f != pg_k) + { + if (!pg_f->is_valid (fspace, 1) && pg_k->is_valid (kspace, 1)) + { + TRACEPOINT (SYNC_TCB_AREA, + printf ("Sync TCB area: " + "kernel: %p/%x this: %p/%x\n", + kspace, pg_k->x.raw, + fspace, pg_f->x.raw)); + + pg_f->copy (fspace, 1, pg_k, kspace, 1); + return; + } + } + + /* + * TCB map request. + */ + + if ((! pg_f->is_valid (fspace, 1)) || (! pg_f->is_subtree (fspace, 1))) + { + pg_f->make_subtree (fspace, 1); + /* sync kernel pagedir */ + pg_k->copy(kspace, 1, pg_f, fspace, 1); + } + + pg_f = pg_f->subtree (fspace, 1); + pg_f = pg_f->next (fspace, pgtab_idx (fault), 0); + + if (PF_WRITE (errcode)) + { + TRACEPOINT (MAP_NEW_TCB, + printf ("map TCB page (%p @ %p)\n", fault, ip)); + + pg_f->set_address (fspace, 0, (dword_t) + virt_to_phys (kmem_alloc (PAGE_SIZE))); + pg_f->set_flags (fspace, 1, PAGE_TCB_BITS); + flush_tlbent ((ptr_t) fault); /* Get rid of zero-page entries. */ + return; + } + else + { + TRACEPOINT (MAP_ZERO_PAGE, + printf ("map zero page (%p @ %p)\n", fault, ip)); + + pg_f->set_address (fspace, 0, (dword_t) + virt_to_phys (__zero_page)); + pg_f->set_flags (fspace, 0, PAGE_ZERO_BITS); + return; + } + } + else + { + +#if !defined(CONFIG_DISABLE_LONGIPC) + if ( fault >= MEM_COPYAREA1 && fault < MEM_COPYAREA_END ) + { + tcb_t * partner = tid_to_tcb(current->partner); + ptr_t pdir_to = partner->space->pagedir (); + ptr_t pdir_from = current->space->pagedir (); + + dword_t *saved_stack; + + if ( fault < MEM_COPYAREA2 ) + { + if ( current->resources & TR_IPC_MEM1 ) + { + /* + * Page has not been mapped. Tunnel pagefault to + * the receiving thread. + */ + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area1 + + (fault - MEM_COPYAREA1), + (dword_t) current); + + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + + /* Receiver is already present in the ready queue. */ + dispatch_thread(partner); + partner->stack = saved_stack; + + /* + * We did an IPC (i.e., thread switch), implying + * that the pagetable entires of copy area are + * possibly gone. Fall through so that the + * pagedir entries are updated again. + */ + } + + pdir_from[pgdir_idx(MEM_COPYAREA1)] = + pdir_to[pgdir_idx(current->copy_area1)] & ~PAGE_USER; + pdir_from[pgdir_idx(MEM_COPYAREA1) + 1] = + pdir_to[pgdir_idx(current->copy_area1) + 1] & ~PAGE_USER; + + current->resources |= TR_IPC_MEM1; + return; + } + else + { + if ( current->resources & TR_IPC_MEM2 ) + { + /* + * Page has not been mapped. Tunnel pagefault to + * the receiving thread. + */ + saved_stack = partner->stack; + notify_thread_2(partner, copy_pagefault, + current->copy_area2 + + (fault - MEM_COPYAREA2), + (dword_t)current); + + partner->thread_state = TS_LOCKED_RUNNING; + current->thread_state = TS_LOCKED_WAITING; + + /* Receiver is already present in the ready queue. */ + dispatch_thread(partner); + partner->stack = saved_stack; + } + + pdir_from[pgdir_idx(MEM_COPYAREA2)] = + pdir_to[pgdir_idx(current->copy_area2)] & ~PAGE_USER; + pdir_from[pgdir_idx(MEM_COPYAREA2) + 1] = + pdir_to[pgdir_idx(current->copy_area2) + 1] & ~PAGE_USER; + + current->resources |= TR_IPC_MEM2; + return; + } + } +#endif /* !CONFIG_DISABLE_LONGIPC */ + +#if 0 + else if (fault >= phys_to_virt(0U) && fault < phys_to_virt(kernel_info_page.main_mem_high)) + { + /* is the area mapped in the kernel's pagetable ? */ + ptr_t pdir = get_current_pagetable(); + ptr_t pkdir = get_kernel_pagetable(); + /* do we run on the kernel ptab (idler...)? */ + if (pdir != virt_to_phys((ptr_t) pkdir)) + { + if (pkdir[fault >> PAGEDIR_BITS] != phys_to_virt(pdir)[fault >> PAGEDIR_BITS]) + { + /* sync pagetables */ + phys_to_virt(pdir)[fault >> PAGEDIR_BITS] = pkdir[fault >> PAGEDIR_BITS]; + return; + } + } + printf("map physmem\n"); + x86_map_kpage(fault & PAGE_MASK, ((dword_t)virt_to_phys(fault & PAGE_MASK)) | PAGE_KERNEL_BITS); + return; + } +#endif +#if defined (CONFIG_SMP) + printf("kernel pf: %x ip: %x cpu: %x\n", fault, ip, get_cpu_id()); +#else + printf("kernel pf: %x ip: %x\n", fault, ip); +#endif + panic("kernel pagefault"); + } + printf("%x", fault); + spin(79); +} diff --git a/kernel/src/x86/memory.o b/kernel/src/x86/memory.o new file mode 100644 index 0000000..21b5c4c Binary files /dev/null and b/kernel/src/x86/memory.o differ diff --git a/kernel/src/x86/p4/.cvsignore b/kernel/src/x86/p4/.cvsignore new file mode 100644 index 0000000..60f025c --- /dev/null +++ b/kernel/src/x86/p4/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.ii *.s diff --git a/kernel/src/x86/p4/Makefile b/kernel/src/x86/p4/Makefile new file mode 100644 index 0000000..e4fa32d --- /dev/null +++ b/kernel/src/x86/p4/Makefile @@ -0,0 +1,28 @@ +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: x86/p4/Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.2 2001/11/22 13:39:08 skoglund Exp $ +## +###################################################################### + +###################################################################### +# the source files... + +LIB = libplatform.a +OBJ_SRC = startup.S +LIB_SRC = null.S + +###################################################################### +# includes + +include ../../../Makeconf $(wildcard .depend) + +###################################################################### +# rules + +all: $(OBJ) $(LIB) diff --git a/kernel/src/x86/p4/null.S b/kernel/src/x86/p4/null.S new file mode 100644 index 0000000..e69de29 diff --git a/kernel/src/x86/p4/startup.S b/kernel/src/x86/p4/startup.S new file mode 100644 index 0000000..e355895 --- /dev/null +++ b/kernel/src/x86/p4/startup.S @@ -0,0 +1,82 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86/p4/startup.S + * Description: Startup code for Pentium4 processors. + * + * @LICENSE@ + * + * $Id: startup.S,v 1.5 2001/11/22 13:39:08 skoglund Exp $ + * + ********************************************************************/ +.globl _start +.section .init + +#include +#include +#include + +#if (__GNUC__ >= 3) +# define INIT_PAGING _Z11init_pagingv +# define INIT _Z4initv +#else +# define INIT_PAGING init_paging__Fv +# define INIT init__Fv +#endif + +_start: + /* Save the multiboot info structure pointer (ebx) to physical + address of kernel_arg. We assume that the kernel IS multibooted. + This value is later on passed to the root task */ + /* UD: Actually, we should save the mbi flags as well - just for the + case where we AREN'T multibooted. */ + movl %ebx, kernel_arg - KERNEL_OFFSET + cli /* disable int's */ + cld /* clear direction flag */ + mov %ds, %ax + mov %ax, %es + mov %ax, %fs + jmp 1f +1: + nop + nop + mov %ax, %gs + mov %ax, %ss + + /* load temporary stack pointer */ + lea _mini_stack-4, %esp + /* set up paging */ + call INIT_PAGING + + + /* Enable various CPU features. */ + mov $IA32_MISC_ENABLE, %ecx + sub %eax, %eax + sub %edx, %edx +#if defined(CONFIG_PERFMON) + add $IA32_ENABLE_PERFMON, %eax +#endif +#if defined(CONFIG_X86_P4_BTS) + add $IA32_ENABLE_BRANCH_TRACE, %eax +#endif +#if defined(CONFIG_X86_P4_PEBS) + add $IA32_ENABLE_PEBS, %eax +#endif + wrmsr + + /* still running in 1:1 mapped area + jump to the top level init function */ + jmp INIT + + + .space 1024 + .globl _mini_stack +_mini_stack: + + .section .mb_header + .align 4 +_mb_header: + .long 0x1BADB002 /* magic */ + .long 0x00000000 /* flags */ + .long - 0x00000000 - 0x1BADB002 /* check */ diff --git a/kernel/src/x86/resources.c b/kernel/src/x86/resources.c new file mode 100644 index 0000000..96f6083 --- /dev/null +++ b/kernel/src/x86/resources.c @@ -0,0 +1,172 @@ +/********************************************************************* + * + * Copyright (C) 2001, Karlsruhe University + * + * File path: x86/resources.c + * Description: Thread resource management for x86. + * + * @LICENSE@ + * + * $Id: resources.c,v 1.5 2002/05/13 13:04:31 stoess Exp $ + * + ********************************************************************/ + +#include +#include +#include + +void save_resources(tcb_t *current, tcb_t *dest) +{ + TRACEPOINT(SAVE_RESOURCES, printf("save_resources: tcb=%p rc=%p\n", + current, current->resources)); + + /* + * Debug registers must be saved upon each context switch and all + * current breakpoints must be disabled. + */ + if ( current->resources & TR_DEBUG_REGS ) + { + save_debug_regs((ptr_t) ¤t->priv[0].dbg); + asm ("mov %0, %%dr7" : :"r"(0)); + } + + /* + * Floating point state can be saved lazily (i.e., next time + * floating point unit is used). + */ + if ( current->resources & TR_FPU ) + { + disable_fpu(); + current->resources &= ~TR_FPU; + } + + /* + * Remove any temporary copy-area mapppings. + */ + if ( current->resources & TR_IPC_MEM ) + { + dword_t * pgdir = current->space->pagedir (); + + pgdir[pgdir_idx(MEM_COPYAREA1)] = 0; + pgdir[pgdir_idx(MEM_COPYAREA1)+1] = 0; + pgdir[pgdir_idx(MEM_COPYAREA2)] = 0; + pgdir[pgdir_idx(MEM_COPYAREA2)+1] = 0; + + if ( dest == get_idle_tcb () || +#if defined(CONFIG_ENABLE_SMALL_AS) + dest->space->is_small () || +#endif + same_address_space(current, dest) ) + flush_tlb(); + + current->resources &= ~TR_IPC_MEM; + } +#if defined(CONFIG_ENABLE_PVI) + + if ( current->resources & TR_PVI ) + { + // printf("PVI resources\n"); + dword_t dest_ufl = get_user_flags(dest); + dword_t src_ufl = get_user_flags(current); + + current->resources &= ~TR_PVI; + dest->resources |= TR_PVI; + src_ufl &= ~X86_EFL_VIP; + dest_ufl |= X86_EFL_VIP; + + set_user_flags(dest, dest_ufl); + set_user_flags(current, src_ufl); + + } +#endif +} + + +/* + * Purges all resources that the thread holds, including lazily stored + * resources. Needed for, e.g., thread migration. + */ +void purge_resources(tcb_t * tcb) +{ + TRACEPOINT(PURGE_RESOURCES, printf("purge_resources: tcb=%p\n", tcb)); + + /* the current FPU owner resides in the cpu-local section */ + extern tcb_t* fpu_owner; + if (fpu_owner == tcb) + { +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) + save_fpu_state((byte_t*) tcb->priv->fpu_ptr); +#else + save_fpu_state((byte_t*) &tcb->priv->fpu); +#endif + fpu_owner = NULL; + } +} + + +void load_resources(tcb_t *current) +{ + TRACEPOINT(LOAD_RESOURCES, printf("load_resources: tcb=%p rc=%p\n", + current, current->resources)); + +#if defined(CONFIG_ENABLE_SMALL_AS) + if ( current->resources & TR_LONG_IPC_PTAB ) + { + /* + * Current thread (in small address space) is doing long IPC + * and needs to use the pagetable of its partner for copying. + */ + enter_kdebug("setting live ptab"); + ptr_t pgdir = tid_to_tcb (current->partner)->space->pagedir_phys (); + if ( get_current_pagetable() != pgdir ) + set_current_pagetable(pgdir); + } +#endif + + if ( current->resources & TR_DEBUG_REGS ) + load_debug_regs((ptr_t) ¤t->priv[0].dbg); +#if defined(CONFIG_ENABLE_PVI) + if ( current->resources & TR_PVI ) + { + dword_t ufl = get_user_flags(current); + + // if ((ufl & X86_EFL_VIF) || (current == get_idle_tcb())){ + if ((current == get_idle_tcb() || current == sigma0)){ + + extern void handle_pending_irq(void); + current->resources &= ~TR_PVI; + ufl &= ~X86_EFL_VIP; + set_user_flags(current, ufl); + handle_pending_irq(); + + } + } +#endif + +} + + +void init_resources(tcb_t * tcb) +{ +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) + tcb->priv->fpu_ptr = NULL; +#else + tcb->priv->fpu_used = 0; // fpu not used +#endif +} + +void free_resources(tcb_t * tcb) +{ +#if defined(X86_FLOATING_POINT_ALLOC_SIZE) + if (tcb->priv->fpu_ptr) + { + kmem_free ((ptr_t) tcb->priv->fpu_ptr, X86_FLOATING_POINT_ALLOC_SIZE); + tcb->priv->fpu_ptr = NULL; + } +#endif + + extern tcb_t *fpu_owner; + if (fpu_owner == tcb) + fpu_owner = NULL; +} + diff --git a/kernel/src/x86/resources.o b/kernel/src/x86/resources.o new file mode 100644 index 0000000..cc59085 Binary files /dev/null and b/kernel/src/x86/resources.o differ diff --git a/kernel/src/x86/smp-boot.S b/kernel/src/x86/smp-boot.S new file mode 100644 index 0000000..70d18a6 --- /dev/null +++ b/kernel/src/x86/smp-boot.S @@ -0,0 +1,79 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/smp-boot.S + * Description: Assembly glue for booting SMP. + * + * @LICENSE@ + * + * $Id: smp-boot.S,v 1.3 2001/11/22 13:39:07 skoglund Exp $ + * + ********************************************************************/ +#include +#include +#include + + +#if (__GNUC__ >= 3) +# define INIT_SMP _Z8init_smpv +#else +# define INIT_SMP init_smp__Fv +#endif + +#if defined(CONFIG_SMP) + .section .init +/* startup of application processor after switching to protected mode */ +_start_ap: + mov $X86_KDS, %ax + mov %ax, %ds + mov %ax, %ss + mov %ax, %es + mov %ax, %fs + jmp 1f +1: + + /* load temporary stack pointer */ + lea _mini_stack-4, %esp + /* set up paging */ + call INIT_SMP + + +.code16 + +.globl _start_smp +.globl _end_smp +.align 4 +_start_smp: +_base = . + /* disable ints */ + cli + + /* equal code and data segment */ + mov %cs, %ax + mov %ax, %ds + + /* setup a boot gdt, (ptr - _base) for .code16 relocation */ + lgdt _smp_gdt - _base + + /* enable protected mode */ + xor %ax, %ax + inc %ax + lmsw %ax + jmp 1f +1: + nop + nop + + ljmpl $X86_KCS, $_start_ap + + /* does not return */ + +.align 16 +_smp_gdt: + .word 3*8 /* this GDT has 3 entries: NULL, KCS, KDS */ + .long smp_boot_gdt - KERNEL_OFFSET + .word 0 + +_end_smp: +#endif /* CONFIG_SMP */ diff --git a/kernel/src/x86/smp-boot.o b/kernel/src/x86/smp-boot.o new file mode 100644 index 0000000..066d45d Binary files /dev/null and b/kernel/src/x86/smp-boot.o differ diff --git a/kernel/src/x86/smp.c b/kernel/src/x86/smp.c new file mode 100644 index 0000000..1faf30d --- /dev/null +++ b/kernel/src/x86/smp.c @@ -0,0 +1,970 @@ +/********************************************************************* + * + * Copyright (C) 1999, 2000, 2001, Karlsruhe University + * + * File path: x86/smp.c + * Description: SMP handling code. + * + * @LICENSE@ + * + * $Id: smp.c,v 1.19 2001/12/04 21:22:07 uhlig Exp $ + * + ********************************************************************/ +#include +#include +#include + +#if defined (CONFIG_SMP) + +#if defined(CONFIG_DEBUG_TRACE_IPI) +DEFINE_SPINLOCK(ipi_printf_lock); +#define IPI_PRINTF(fmt, args...) do {printf("cpu %d: ", get_cpu_id()); printf(fmt, ## args ); } while(0) +#else +#define IPI_PRINTF(x...) +#endif + +#if 0 +#define XIPC_PRINTF IPI_PRINTF +#else +#define XIPC_PRINTF(x...) +#endif + +/* + * one bit for each processor which is online + */ +#if (CONFIG_SMP_MAX_CPU > 32) +# error review processor_online_map +#endif +volatile dword_t processor_online_map = 0; +volatile dword_t processor_map = 0; +seg_desc_t smp_boot_gdt[3]; /* this GDT has 3 entries: NULL, KCS, KDS */ + +void init_smp() L4_SECT_INIT; +void send_startup_ipi(int cpu) L4_SECT_INIT; + +/* smp startup code */ +extern "C" void _start_smp(); +extern "C" void _end_smp(); + +/* mailboxes for inter-cpu communication */ +cpu_mailbox_t cpu_mailbox[CONFIG_SMP_MAX_CPU]; + +/* global lock for all ipi's */ +DEFINE_SPINLOCK(ipi_lock); + + + +/********************************************************************** + * online status of processors + */ + +/* the apic id of the boot processor */ +dword_t boot_cpu = 0; + +void set_cpu_online(dword_t cpu) +{ + processor_online_map |= (1 << cpu); +} + +int is_cpu_online(dword_t cpu) +{ + return processor_online_map & (1 << cpu); +} + + +/********************************************************************** + * helpers + */ + +INLINE cpu_mailbox_t * get_mailbox() +{ + return &cpu_mailbox[get_cpu_id()]; +} + + +static void udelay(int usec) +{ + for (int i=0; i<(100000*usec); i++); +} + +void send_startup_ipi(int cpu) +{ + dword_t val; + + //out_rtc(0xf, 0xa); + + /* at this stage we still have our 1:1 mapping at 0 */ + *((volatile unsigned short *) 0x469) = SMP_STARTUP_PAGE >> 4; + *((volatile unsigned short *) 0x467) = SMP_STARTUP_PAGE & 0xf; + + + /* assert init */ +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("APIC INIT assert...\n"); +#endif + val = get_local_apic(X86_APIC_INTR_CMD2); + val &= 0x00ffffff; + set_local_apic(X86_APIC_INTR_CMD2, val | cpu << (56 - 32)); + + val = get_local_apic(X86_APIC_INTR_CMD1); + val &= ~0xCDFFF; + val |= APIC_TRIGGER_LEVEL | APIC_ASSERT | APIC_DEL_INIT; + set_local_apic(X86_APIC_INTR_CMD1, val); + + udelay(200); + + /* deassert init */ +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("APIC INIT deassert...\n"); +#endif + val = get_local_apic(X86_APIC_INTR_CMD2); + val &= 0x00ffffff; + set_local_apic(X86_APIC_INTR_CMD2, val | cpu << (56 - 32)); + + val = get_local_apic(X86_APIC_INTR_CMD1); + val &= ~0xCDFFF; + val |= APIC_TRIGGER_LEVEL | APIC_DEASSERT | APIC_DEL_INIT; + set_local_apic(X86_APIC_INTR_CMD1, val); + + /* send startup ipi */ +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("APIC send startup ipi...\n"); +#endif + + // send startup ipi 2 times (see: intel mp boot) + for (int i = 0; i < 2; i++) { + set_local_apic(X86_APIC_ERR_STATUS, 0); +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("APIC: reset status\n"); +#endif + + val = get_local_apic(X86_APIC_INTR_CMD2); + val &= 0x00ffffff; + set_local_apic(X86_APIC_INTR_CMD2, val | cpu << (56 - 32)); + + val = get_local_apic(X86_APIC_INTR_CMD1); + val &= ~0xCDFFF; + val |= 0x600 | (SMP_STARTUP_PAGE >> PAGE_BITS); + set_local_apic(X86_APIC_INTR_CMD1, val); + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("APIC wait for completion\n"); +#endif + // wait till message is delivered + do { + udelay(100); + val = get_local_apic(X86_APIC_INTR_CMD1) & 0x1000; + } while(val); + + udelay(200); + + // get delivery error + val = get_local_apic(X86_APIC_ERR_STATUS) & 0xef; +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("\ndelivery status: %x\n", val); +#endif + } + +} + +void thread_adapt_queue_state(tcb_t * tcb, dword_t queue_state) +{ + /* we always enqueue into ready and present queue */ + thread_enqueue_present(tcb); + thread_enqueue_ready(tcb); + + /* enqueue into wakeup queue on demand */ + if (queue_state & TS_QUEUE_WAKEUP) + thread_enqueue_wakeup(tcb); +} + + +dword_t cpu_mailbox_t::send_command(dword_t cpu, dword_t command, dword_t value) +{ + int count = MAILBOX_TIMEOUT; + m_status = value; + m_command = command; + + /* signal the request */ + cpu_mailbox[cpu].set_request(get_cpu_id()); + + /* send command IPI to the cpu */ + send_command_ipi(cpu); + spin1(71); + + /* and now wait for the cpu to handle the reuqest */ + while (m_status == value) { + spin1(70); + + if (count-- == 0) + { + IPI_PRINTF("mailbox::send_command timeout - resend IPI to %d\n", cpu); + enter_kdebug("timeout"); + send_command_ipi(cpu); + count = MAILBOX_TIMEOUT; + } + + /* allow incoming requests from other cpus */ + if (pending_requests) + { + IPI_PRINTF("mailbox::send_command incoming request\n"); + handle_pending_requests(); + continue; + } + + __asm__ __volatile__ (".byte 0xf3; .byte 0x90\n"); + } + return m_status; +} + + +static void do_xcpu_ipc_short(cpu_mailbox_t * mailbox) +{ + tcb_t * to_tcb = mailbox->tcb; + tcb_t * from_tcb = (tcb_t*)mailbox->param[0]; + XIPC_PRINTF("smp ipi: thread block to_tcb: %p, from_tcb: %p\n", to_tcb, from_tcb); + + if (to_tcb->cpu != get_cpu_id()) + { + XIPC_PRINTF("%s to_tcb->cpu != current_cpu\n", __FUNCTION__); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + spin_lock(&to_tcb->tcb_spinlock); + + /* check if destination still receives from me */ + if (!( ( to_tcb->thread_state == TS_WAITING ) && + ( to_tcb->partner == L4_NIL_ID || + to_tcb->partner == from_tcb->myself ) )) + { + XIPC_PRINTF("destination not waiting (state: %x, partner: %x)\n", + to_tcb->thread_state, to_tcb->partner); + spin_unlock(&to_tcb->tcb_spinlock); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + spin_unlock(&to_tcb->tcb_spinlock); + + + XIPC_PRINTF("waiting for handshake on mailbox %x\n", &mailbox); + /* now do the short ipc hand-shaking */ + mailbox->wait_for_status(MAILBOX_OK); + + /* here the transfer is finished - let the baby run... */ + to_tcb->thread_state = TS_LOCKED_RUNNING; + thread_enqueue_ready(to_tcb); +} + +void do_xcpu_ipc_start(cpu_mailbox_t * mailbox) +{ + tcb_t * to_tcb = mailbox->tcb; + tcb_t * from_tcb = (tcb_t*)mailbox->param[0]; + IPI_PRINTF("ipi: %s from: %p, to: %p\n", __FUNCTION__, from_tcb, to_tcb); + + if (to_tcb->cpu != get_cpu_id()) + { + IPI_PRINTF("%s to_tcb->cpu != current_cpu\n", __FUNCTION__); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + spin_lock(&to_tcb->tcb_spinlock); + + /* check if destination still receives from me */ + if (!( ( to_tcb->thread_state == TS_WAITING ) && + ( to_tcb->partner == L4_NIL_ID || + to_tcb->partner == from_tcb->myself ) )) + { + XIPC_PRINTF("destination not waiting (state: %x, partner: %x)\n", + to_tcb->thread_state, to_tcb->partner); + spin_unlock(&to_tcb->tcb_spinlock); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + /* set into receiving state */ + to_tcb->thread_state = TS_LOCKED_WAITING; + spin_unlock(&to_tcb->tcb_spinlock); + + /* release partner CPU */ + mailbox->set_status(MAILBOX_OK); +} + +void do_xcpu_ipc_end(cpu_mailbox_t * mailbox) +{ + tcb_t * to_tcb = mailbox->tcb; + tcb_t * from_tcb = (tcb_t*)mailbox->param[0]; + XIPC_PRINTF("ipi: %s from: %p, to: %p\n", __FUNCTION__, from_tcb, to_tcb); + + if (to_tcb->cpu != get_cpu_id()) + { + IPI_PRINTF("%s: to_tcb->cpu != current_cpu\n", __FUNCTION__); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + spin_lock(&to_tcb->tcb_spinlock); + + /* check that everything is still all right! */ + if (to_tcb->thread_state != TS_LOCKED_WAITING || + to_tcb->partner != from_tcb->myself) + { + IPI_PRINTF("%s something whicked happened meanwhile (ex_regs?) (to->state=%x, to->partner=%x\n", __FUNCTION__, to_tcb->thread_state, to_tcb->partner); + spin_unlock(&to_tcb->tcb_spinlock); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + /* ok, everything is fine, we have to explicitly enqueue the thread, + * since we do not directly switch */ + to_tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(to_tcb); + + spin_unlock(&to_tcb->tcb_spinlock); + mailbox->set_status(MAILBOX_OK); +} + +void do_xcpu_ipc_receive(cpu_mailbox_t * mailbox) +{ + tcb_t * from_tcb = mailbox->tcb; + tcb_t * to_tcb = (tcb_t*)mailbox->param[0]; + XIPC_PRINTF("ipi: %s from: %p, to: %p\n", __FUNCTION__, from_tcb, to_tcb); + if (from_tcb->cpu != get_cpu_id()) + { + IPI_PRINTF("from_tcb->cpu != current_cpu\n"); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + spin_lock(&to_tcb->tcb_spinlock); + + if (!IS_POLLING(from_tcb) || + (from_tcb->partner != to_tcb->myself)) + { + IPI_PRINTF("not receiving from partner anymore\n"); + mailbox->set_status(MAILBOX_ERROR); + spin_unlock(&to_tcb->tcb_spinlock); + return; + } + + /* ok - we are partners and want to do ipc with each other */ + thread_dequeue_send(to_tcb, from_tcb); + thread_dequeue_wakeup(from_tcb); + from_tcb->thread_state = TS_XCPU_LOCKED_RUNNING; + thread_enqueue_ready(from_tcb); + spin_unlock(&to_tcb->tcb_spinlock); + + /* release other cpu */ + mailbox->set_status(MAILBOX_OK); +} + +dword_t smp_start_receive_ipc(tcb_t * from_tcb, tcb_t * current) +{ + cpu_mailbox_t * mailbox = get_mailbox(); + mailbox->tcb = from_tcb; + mailbox->param[0] = (dword_t)current; + dword_t status = mailbox->send_command(from_tcb->cpu, SMP_CMD_IPC_RECEIVE); + + if (status == MAILBOX_ERROR) { + //enter_kdebug("smp_start_receive_ipc failed"); + return 0; + } + + switch_to_idle(current); + + return 1; +} + +void do_xcpu_thread_get(cpu_mailbox_t * mailbox) +{ + tcb_t* tcb = mailbox->tcb; + IPI_PRINTF("%s %p, state=%x\n", __FUNCTION__, tcb, tcb->thread_state); + + /* not on our cpu! */ + if (tcb->cpu != get_cpu_id()) + { + mailbox->set_status(MAILBOX_ERROR); + return; + } + + mailbox->param[0] = tcb->queue_state; + thread_dequeue_present(tcb); + thread_dequeue_ready(tcb); + thread_dequeue_wakeup(tcb); + + /* are we ourself the migrated thread ??? */ + if (tcb == get_current_tcb()) + { + apic_ack_irq(); + mailbox->switch_to_idle(tcb /* which is current */, MAILBOX_OK); + return; + }; + + mailbox->set_status(MAILBOX_OK); +} + +void do_xcpu_thread_put(cpu_mailbox_t * mailbox) +{ + tcb_t * tcb = mailbox->tcb; + IPI_PRINTF("%s %p, state=%x\n", __FUNCTION__, tcb, tcb->thread_state); + + tcb->cpu = get_cpu_id(); + thread_adapt_queue_state(tcb, mailbox->param[0]); + mailbox->set_status(MAILBOX_OK); + + /* adjust the page directory for this tcb */ + IPI_PRINTF("pgdir for tcb=%x: %x\n", tcb, tcb->pagedir_cache); + thread_adapt_pagetable(tcb, get_cpu_id()); + IPI_PRINTF("pgdir for tcb=%x: %x\n", tcb, tcb->pagedir_cache); + //while(1); +} + +#warning xcpu_unwind_mailbox should be explicitly initialized +static cpu_mailbox_t * xcpu_unwind_mailbox L4_SECT_CPULOCAL; +void do_xcpu_unwind(cpu_mailbox_t * mailbox) +{ + tcb_t * tcb = mailbox->tcb; + if (tcb->cpu != get_cpu_id()) + { + IPI_PRINTF("xcpu unwind on wrong cpu (%x)\n", tcb); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + IPI_PRINTF("%s %x (partner=%x, current=%x)\n", + __FUNCTION__, tcb, tcb->partner, get_current_tcb()); + + xcpu_unwind_mailbox = mailbox; + + unwind_ipc(tcb); + + xcpu_unwind_mailbox = NULL; + + /* now that guy is ready to run - enqueue into run queue */ + tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(tcb); + + /* may be ignored, if we have an unwind */ + mailbox->set_status(MAILBOX_OK); +} + +extern void delete_all_threads(space_t *); +void do_xcpu_delete_all_threads(cpu_mailbox_t * mailbox) +{ + space_t* space = (space_t*)mailbox->param[0]; + + xcpu_unwind_mailbox = mailbox; + + delete_all_threads(space); + + xcpu_unwind_mailbox = NULL; + + /* ensure that our pagetable does not disappear */ + if (get_current_pagetable() == space->pagedir_phys(get_cpu_id())) + { + /* after deleting all threads we must switch the pagetable */ + set_current_pagetable(get_kernel_space()->pagedir_phys(get_cpu_id())); + + if (get_current_tcb() != get_idle_tcb()) + { + mailbox->switch_to_idle(get_current_tcb(), MAILBOX_OK); + /* not re-activated */ + panic("mailbox->switch_to_idle reactivated"); + } + + } + mailbox->set_status(MAILBOX_OK); +} + +void do_xcpu_thread_ex_regs(cpu_mailbox_t * mailbox) +{ + tcb_t * tcb = mailbox->tcb; + if (tcb->cpu != get_cpu_id()) + { + IPI_PRINTF("xcpu ex regs on wrong cpu (%x)\n", tcb); + mailbox->set_status(MAILBOX_ERROR); + return; + } + + IPI_PRINTF("%s %x, state=%x\n", __FUNCTION__, tcb, tcb->thread_state); + + xcpu_unwind_mailbox = mailbox; + IPI_PRINTF("before unwind_ipc (%x)\n", get_cpu_id(), tcb); + + /* unwind ipc expects to have the spinlock! */ + spin_lock(&tcb->tcb_spinlock); + unwind_ipc(tcb); + IPI_PRINTF("after unwind_ipc (%x)\n", get_cpu_id(), tcb); + + if (mailbox->param[1] == ~0U) + mailbox->param[1] = get_user_sp(tcb); + else + mailbox->param[1] = set_user_sp(tcb, mailbox->param[0]); + + if (mailbox->param[0] == ~0U) + mailbox->param[0] = get_user_ip(tcb); + else + mailbox->param[0] = set_user_ip(tcb, mailbox->param[0]); + + if (mailbox->tid == L4_INVALID_ID) + mailbox->tid = tcb->pager; + else + { + l4_threadid_t oldpager; + oldpager = tcb->pager; + tcb->pager = mailbox->tid; + mailbox->tid = oldpager; + } + + /* + * we never allocate xcpu-threads + * therefore we can always set them running + */ + thread_dequeue_wakeup(tcb); + tcb->thread_state = TS_RUNNING; + thread_enqueue_ready(tcb); + spin_unlock(&tcb->tcb_spinlock); + + xcpu_unwind_mailbox = NULL; + mailbox->set_status(MAILBOX_OK); +} + +void do_xcpu_flush_tlb(cpu_mailbox_t * mailbox) +{ + flush_tlb(); + mailbox->set_status(MAILBOX_OK); +} + +/* central inter-cpu command handler */ +void smp_handle_request(dword_t from_cpu) +{ + dword_t current_cpu = get_cpu_id(); + cpu_mailbox_t * mailbox = &cpu_mailbox[from_cpu]; + if (mailbox->get_command() > SMP_CMD_IPC_RECEIVE) + IPI_PRINTF("smp-ipi command %d from %d\n", mailbox->get_command(), from_cpu); + spin1(72); + + if (current_cpu == from_cpu) { + enter_kdebug("self command ipi???"); + return; + } + + //IPI_PRINTF("smp-ipi command %x from %d\n", mailbox->get_command(), from_cpu); + + switch(mailbox->get_command()) { + case SMP_CMD_IPC_SHORT: + do_xcpu_ipc_short(mailbox); + break; + + case SMP_CMD_IPC_START: + do_xcpu_ipc_start(mailbox); + break; + + case SMP_CMD_IPC_END: + do_xcpu_ipc_end(mailbox); + break; + + case SMP_CMD_IPC_RECEIVE: + do_xcpu_ipc_receive(mailbox); + break; + + case SMP_CMD_THREAD_GET: + do_xcpu_thread_get(mailbox); + break; + + case SMP_CMD_THREAD_PUT: + do_xcpu_thread_put(mailbox); + break; + + case SMP_CMD_THREAD_EX_REGS: + do_xcpu_thread_ex_regs(mailbox); + break; + + case SMP_CMD_UNWIND: + do_xcpu_unwind(mailbox); + break; + + case SMP_CMD_DELETE_ALL_THREADS: + do_xcpu_delete_all_threads(mailbox); + break; + + case SMP_CMD_FLUSH_TLB: + do_xcpu_flush_tlb(mailbox); + break; + + default: + printf("cpu%d: unhandled command from cpu %d: cmd: %x, tcb: %p\n", + get_cpu_id(), from_cpu, mailbox->get_command(), mailbox->tcb); + } +} + +void smp_handle_requests() +{ + cpu_mailbox_t * mailbox = get_mailbox(); + + while(mailbox->pending_requests) + { + for (dword_t i = 0; i < CONFIG_SMP_MAX_CPU; i++) + if (mailbox->pending_requests & (1 << i)) + { + mailbox->clear_request(i); + smp_handle_request(i); + } + } +} + +void smp_handler_command_ipi() +{ + smp_handle_requests(); + apic_ack_irq(); +} + + +void smp_move_thread(tcb_t * tcb, dword_t cpu) +{ + cpu_mailbox_t * mailbox = get_mailbox(); + //mailbox->command = SMP_CMD_THREAD_MOVE; + mailbox->tcb = tcb; + //mailbox->status = MAILBOX_NULL; + mailbox->param[0] = tcb->queue_state; + + //IPI_PRINTF("smp move thread %p from cpu %d to cpu %d\n", tcb, tcb->cpu, cpu); + + /* do not move thread if already on cpu */ + if (tcb->cpu == cpu) + return; + + /* do not migrate to inactive cpus */ + if (!is_cpu_online(cpu)) + return; + + retry_migration: + + if (tcb->cpu == get_cpu_id()) + { + /* we have the thread - so, we can give it away */ + thread_dequeue_present(tcb); + thread_dequeue_ready(tcb); + thread_dequeue_wakeup(tcb); + + IPI_PRINTF("before thread put (current: %x, pdir=%x, tcb: %x)\n", + get_current_tcb(), get_current_pagetable(), tcb); + + mailbox->send_command(cpu, SMP_CMD_THREAD_PUT); + + IPI_PRINTF("thread_put done (current: %x, pdir=%x, cpu: %d/%d)\n", + get_current_tcb(), get_current_pagetable(), + get_cpu_id(), get_apic_cpu_id()); + } + else + { + /* we don't have the thread - ask the cpu */ + dword_t status; + status = mailbox->send_command(tcb->cpu, SMP_CMD_THREAD_GET); + + /* thread may have moved meanwhile */ + if (status != MAILBOX_OK) + goto retry_migration; + + if (cpu == get_cpu_id()) + { + /* the thread comes to us */ + tcb->cpu = cpu; + thread_adapt_queue_state(tcb, mailbox->param[1]); + /* adjust the page directory for this tcb */ + //printf("pgdir: %x\n", tcb->page_dir); + thread_adapt_pagetable(tcb, get_cpu_id()); + //printf("pgdir: %x\n", tcb->page_dir); + } + else + { + status = mailbox->send_command(cpu, SMP_CMD_THREAD_PUT); + + if (status != MAILBOX_OK) + { + enter_kdebug("3-cpu thread migration failed"); + return; + } + } + } +} + +/* pre-condition: + * tcb is waiting or receiving on another cpu + */ +dword_t smp_start_short_ipc(tcb_t * tcb, tcb_t * current) +{ + XIPC_PRINTF("sending start_short_ipc ipi (current=%p)\n", current); + + cpu_mailbox_t * mailbox = get_mailbox(); + mailbox->tcb = tcb; + mailbox->param[0] = (dword_t)current; + + dword_t status = mailbox->send_command(tcb->cpu, SMP_CMD_IPC_SHORT); + + /* + * ok - delivery can start now + * partner cpu spins in mailbox loop and waits for message. + */ + if (status == MAILBOX_OK) + return 1; + + IPI_PRINTF("%d smp_start_short_ipc failed (%x (%d, %x) -> %x (%d, %x))\n", + get_cpu_id(), + current, current->cpu, current->thread_state, + tcb, tcb->cpu, tcb->thread_state); + + /* ipc failed - check whether we have pending requests */ + IPI_PRINTF("pending requests = %x\n", mailbox->pending_requests); + mailbox->handle_pending_requests(); + + return 0; +} + +void smp_end_short_ipc(tcb_t * to_tcb) +{ + cpu_mailbox_t * mailbox; + XIPC_PRINTF("smp_end_short_ipc (tcb=%x)\n", to_tcb); + + if (to_tcb->thread_state == TS_XCPU_LOCKED_RUNNING) + mailbox = &cpu_mailbox[to_tcb->cpu]; + else + mailbox = get_mailbox(); + + XIPC_PRINTF("notifying mailbox %x\n", mailbox); + + /* ok notification for partner cpu that transfer is complete */ + mailbox->set_status(MAILBOX_DONE); +} + +dword_t smp_start_ipc(tcb_t * to_tcb, tcb_t * current) +{ + XIPC_PRINTF("sending start_ipc ipi (current=%p)\n", current); + + cpu_mailbox_t * mailbox = get_mailbox(); + mailbox->tcb = to_tcb; + mailbox->param[0] = (dword_t)current; + + dword_t status = mailbox->send_command(to_tcb->cpu, SMP_CMD_IPC_START); + + if (status == MAILBOX_OK) + return 1; + + IPI_PRINTF("%d smp_start_ipc failed (%x (%d, %x) -> %x (%d, %x))\n", + get_cpu_id(), + current, current->cpu, current->thread_state, + to_tcb, to_tcb->cpu, to_tcb->thread_state); + + return 0; +} + +dword_t smp_end_ipc(tcb_t * to_tcb, tcb_t * current) +{ + XIPC_PRINTF("sending end_ipc ipi (to_tcb=%p)\n", to_tcb); + + cpu_mailbox_t * mailbox = get_mailbox(); + mailbox->tcb = to_tcb; + mailbox->param[0] = (dword_t)current; + + dword_t status = mailbox->send_command(to_tcb->cpu, SMP_CMD_IPC_END); + + if (status == MAILBOX_OK) + return 1; + + IPI_PRINTF("smp_end_ipc failed (%x (%d, %x)\n", + get_cpu_id(), + to_tcb, to_tcb->cpu, to_tcb->thread_state); + + return 0; +} + +int smp_delete_all_threads(space_t * space) +{ + //IPI_PRINTF("%s (%x)\n", __FUNCTION__, victim); + cpu_mailbox_t * mailbox = get_mailbox(); + for (dword_t cpu = 0; cpu < CONFIG_SMP_MAX_CPU; cpu++) + { + if (cpu == get_cpu_id()) + continue; + if (!is_cpu_online(cpu)) + continue; + + mailbox->param[0] = (dword_t)space; + dword_t status = mailbox->send_command(cpu, SMP_CMD_DELETE_ALL_THREADS); + switch(status) + { + case MAILBOX_OK: + return 1; + case MAILBOX_UNWIND_REMOTE: + /* we have to perform a remote unwind */ + IPI_PRINTF("%s: remote unwind %x\n", mailbox->tcb); + unwind_ipc(mailbox->tcb); + break; + case MAILBOX_ERROR: + enter_kdebug("smp_delete_task: error deleting task"); + break; + default: + enter_kdebug("smp_delete_task: unexpected return value"); + break; + } + } + return 0; +} + +int smp_unwind_ipc(tcb_t * tcb) +{ + IPI_PRINTF("smp_unwind_ipc(%x), partner=%x, current=%x, xcpu_mb=%x\n", + tcb, tcb->partner, get_current_tcb(), xcpu_unwind_mailbox); + /* check if we are already performing an unwind ipc operation */ + if (xcpu_unwind_mailbox) + { + xcpu_unwind_mailbox->tcb = tcb; + xcpu_unwind_mailbox->set_status(MAILBOX_UNWIND_REMOTE); + return 1; + } + + dword_t status; + cpu_mailbox_t * mailbox = get_mailbox(); + mailbox->tcb = tcb; + + status = mailbox->send_command(tcb->cpu, SMP_CMD_UNWIND); + + switch(status) + { + case MAILBOX_UNWIND_REMOTE: + /* we have to perform a remote unwind */ + unwind_ipc(mailbox->tcb); + break; + case MAILBOX_OK: + /* unwind done */ + break; + case MAILBOX_ERROR: + /* thread may have moved */ + return 0; + default: + enter_kdebug("smp_unwind: unexpected return value"); + return 0; + }; + return 1; +} + +int smp_ex_regs(tcb_t * tcb, dword_t * uip, dword_t * usp, + l4_threadid_t * pager, dword_t * flags) +{ + cpu_mailbox_t * mailbox = get_mailbox(); + IPI_PRINTF("xcpu ex_regs tcb=%x ip=%x sp=%x pager=%x\n", + tcb, *uip, *usp, *pager); + + mailbox->tcb = tcb; + mailbox->param[0] = *uip; + mailbox->param[1] = *usp; + mailbox->tid = *pager; + + switch(mailbox->send_command(tcb->cpu, SMP_CMD_THREAD_EX_REGS)) + { + case MAILBOX_ERROR: + IPI_PRINTF("xcpu ex_regs failed\n"); + return 0; + case MAILBOX_UNWIND_REMOTE: + enter_kdebug("smp_ex_regs unwind remote"); + *uip = mailbox->param[0]; + *usp = mailbox->param[1]; + *flags = mailbox->param[3]; + *pager = mailbox->tid; + unwind_ipc(mailbox->tcb); + return 1; + case MAILBOX_OK: + IPI_PRINTF("xcpu ex_regs done\n"); + *uip = mailbox->param[0]; + *usp = mailbox->param[1]; + *flags = mailbox->param[3]; + *pager = mailbox->tid; + return 1; + default: + printf("smp_ex_regs: unknown response\n"); + } + return 0; +} + +void smp_flush_tlb() +{ +#warning inefficient implementation of tlb shootdown + cpu_mailbox_t * mailbox = get_mailbox(); + for (dword_t cpu = 0; cpu < CONFIG_SMP_MAX_CPU; cpu++) + { + if (cpu == get_cpu_id()) + continue; + if (!is_cpu_online(cpu)) + continue; + + dword_t status = mailbox->send_command(cpu, SMP_CMD_FLUSH_TLB); + if (status != MAILBOX_OK) + enter_kdebug("smp_flush_tlb"); + } +} + + +void smp_startup_processors() +{ + +#define gdt_idx(x) ((x) >> 3) + /* the kernel code - kernel_space_exec */ + smp_boot_gdt[gdt_idx(X86_KCS)].set_seg(0, ~0, 0, GDT_DESC_TYPE_CODE); + /* kernel data - linear_kernel_space */ + smp_boot_gdt[gdt_idx(X86_KDS)].set_seg(0, ~0, 0, GDT_DESC_TYPE_DATA); + +#if defined(CONFIG_DEBUG_TRACE_SMP) + printf("smp_start_processors\n"); +#endif + memcpy((dword_t*)SMP_STARTUP_PAGE, (dword_t*)_start_smp, (dword_t)(_end_smp) - (dword_t)(_start_smp)); + //enter_kdebug("after smp-copy"); + wbinvd(); + + for (dword_t cpu = 0; cpu < CONFIG_SMP_MAX_CPU; cpu++) + { + // the boot cpu is not necessarily cpu 0 + if (cpu == get_boot_cpu()) + continue; + + // start only processor which are in the processor map + if (!(processor_map & (1 << cpu))) + continue; + + send_startup_ipi(cpu); + + // wait for cpu to be online - aprox. 100 * 100us = + for (int i=0; i<100; i++) { + udelay(100); + if (is_cpu_online(cpu)) break; + } + + if (!is_cpu_online(cpu)) { + printf("CPU %d failed to start\n", cpu); + } + else + { + printf("CPU %d is online\n", cpu); + } + } + //enter_kdebug("startup done"); +} +#if 1 +void system_sleep() +{ +#if 1 + //apic_ack_irq(); + __asm__ __volatile__("sti \n" + "hlt \n" + "cli \n" + :); +#else + enable_interrupts(); + while(!get_mailbox()->pending_requests); + disable_interrupts(); + get_mailbox()->handle_pending_requests(); +#endif +} +#endif +#endif /* CONFIG_SMP */ diff --git a/kernel/src/x86/smp.o b/kernel/src/x86/smp.o new file mode 100644 index 0000000..062ba9e Binary files /dev/null and b/kernel/src/x86/smp.o differ diff --git a/kernel/src/x86/smpipc.c b/kernel/src/x86/smpipc.c new file mode 100644 index 0000000..01301e1 --- /dev/null +++ b/kernel/src/x86/smpipc.c @@ -0,0 +1,573 @@ +/********************************************************************* + * + * Copyright (C) 2000, 2001, Karlsruhe University + * + * File path: x86/smpipc.c + * Description: IPC code for x86 SMP. + * + * @LICENSE@ + * + * $Id: smpipc.c,v 1.5 2001/12/04 20:38:37 uhlig Exp $ + * + ********************************************************************/ +#include + +#if defined(CONFIG_SMP) + +#include +#include +#include INC_ARCH(syscalls.h) + +#define IS_SEND (snd_desc != (dword_t)~0) +#define IS_RECEIVE (rcv_desc != (dword_t)~0) +#define IS_OPEN_WAIT ((rcv_desc & 1) == 1) + +#define IRQ_IN_SERVICE (1<<31) + +#define IS_SHORT_IPC(x) (!(x & ~0x3)) +#define IS_MAP(x) (x & 0x2) + +#if defined(CONFIG_DEBUG_TRACE_IPC) +extern dword_t __kdebug_ipc_tracing; +extern dword_t __kdebug_ipc_tr_mask; +extern dword_t __kdebug_ipc_tr_thread; +extern dword_t __kdebug_ipc_tr_this; +extern dword_t __kdebug_ipc_tr_dest; +#endif + + +/* we can make some assumptions here: + * - we are not the idle thread + * - we know that we don't activate ourself + * --> save time :-))) + */ +INLINE void ipc_switch_to_thread(tcb_t * current, tcb_t * tcb) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + //printf("ipc_switch_to_thread(%x->%x)\n", current, tcb); +#endif + ASSERT(current->cpu == tcb->cpu); + switch_to_thread(tcb, current); +} + +INLINE void ipc_switch_to_idle(tcb_t * current) +{ +#if defined(CONFIG_DEBUG_TRACE_MISC) + //printf("ipc_switch_to_idle: curr: %x\n", current); +#endif + switch_to_idle(current); +} + + +INLINE void transfer_message(tcb_t* const from, tcb_t* const to, const dword_t snd_desc) +{ + + /* UD: use temporary variables to give gcc a hint + to->ipc_buffer = from->ipc_buffer resulted in only one register + being used for all three dwords -> stalls */ + dword_t w0, w1, w2; + w0 = from->ipc_buffer[0]; + w1 = from->ipc_buffer[1]; + w2 = from->ipc_buffer[2]; + to->ipc_buffer[0] = w0; + to->ipc_buffer[1] = w1; + to->ipc_buffer[2] = w2; + +#if 1 +#warning REVIEWME: p-bit + /* What's up with the p-bit?? We don't support autopropagation, + but we can't simply assume the bit to be zero !!! */ +#else + if (snd_desc & 1) + enter_kdebug("propagate"); +#endif + + /* IPC optimization - register ipc. */ + if (EXPECT_FALSE( snd_desc & ~0x1 )) + { + /* + * Make sure that we are marked as doing IPC (in case we are + * descheduled). Also set the SENDING_IPC flag while we are + * in the send phase. + */ + from->thread_state = TS_LOCKED_RUNNING; + from->flags |= TF_SENDING_IPC; + extended_transfer(from, to, snd_desc); + from->thread_state = TS_RUNNING; + from->flags &= ~TF_SENDING_IPC; + } + else + to->msg_desc = 0; +} + + +extern struct last_ipc_t +{ + l4_threadid_t myself; + l4_threadid_t dest; + dword_t snd_desc; + dword_t rcv_desc; + dword_t ipc_buffer[3]; + dword_t ip; +} last_ipc; + +/* + * the system call + */ + +/********************************************************************** + * MULTI-PROCESSOR * + **********************************************************************/ + +//#define CHECK_LOCK(l) do { if ((l)->lock) {printf("locked (%x)\n", l); enter_kdebug("check_lock");} } while(0) +#if 1 +#define IPC_SPIN_LOCK(x) spin_lock(x) +#define IPC_SPIN_UNLOCK(x) spin_unlock(x) +#else +#define IPC_SPIN_LOCK(x) +#define IPC_SPIN_UNLOCK(x) +#endif +void sys_ipc(const l4_threadid_t dest, const dword_t snd_desc, const dword_t rcv_desc) +{ + tcb_t * current = get_current_tcb(); + tcb_t * to_tcb = NULL; + +#if defined(CONFIG_DEBUG_TRACE_IPC) + { + last_ipc.myself = current->myself; + last_ipc.dest = dest; + last_ipc.snd_desc = snd_desc; + last_ipc.rcv_desc = rcv_desc; + last_ipc.ipc_buffer = (dword_t[]){current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2]}; + last_ipc.ip = get_user_ip(current); + } + if ( __kdebug_ipc_tracing && + /* Do we trace spcific threads? */ + ((! __kdebug_ipc_tr_thread) || + /* Do we trace IPCs invoked by this thread? */ + (__kdebug_ipc_tr_thread == (__kdebug_ipc_tr_mask & + (dword_t) current) && + __kdebug_ipc_tr_this) || + /* Do we trace sends _to_ this thread? */ + (__kdebug_ipc_tr_thread == (__kdebug_ipc_tr_mask & + (dword_t) tid_to_tcb(dest)) && + __kdebug_ipc_tr_dest)) ) + { + printf("ipc: %x -> %x snd_desc: %x rcv_desc: %x " + "(%x, %x, %x) - ip=%x\n", current->myself.raw, dest.raw, + snd_desc, rcv_desc, current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2], + get_user_ip(current)); + if (__kdebug_ipc_tracing > 1) + enter_kdebug("ipc"); + } +#endif + + TRACEPOINT_2PAR(SYS_IPC, current->myself.raw, dest.raw, + printf("ipc: %x -> %x snd_desc: %x rcv_desc: %x " + "(%x, %x, %x) - ip=%x\n", + current->myself.raw, dest.raw, + snd_desc, rcv_desc, current->ipc_buffer[0], + current->ipc_buffer[1], current->ipc_buffer[2], + get_user_ip(current))); + +#if defined(CONFIG_DEBUG) + if (current->queue_state & TS_QUEUE_WAKEUP) + { + printf("ipc: current in wakeup-queue (%x)\n", current); + enter_kdebug("ipc error"); + } +#endif + + if (EXPECT_TRUE( IS_SEND )) + { + to_tcb = tid_to_tcb(dest); +// printf("ipc: send branch (%p)\n", current); +restart_ipc_send: + if (EXPECT_TRUE( to_tcb->myself == dest )) + { + IPC_SPIN_LOCK(&to_tcb->tcb_spinlock); + current->partner = dest; +// printf("exist (%p, %x, %x)\n", to_tcb, to_tcb->partner.raw, +// to_tcb->thread_state ); + + if (EXPECT_FALSE( !IS_WAITING(to_tcb) ) || + EXPECT_FALSE( ((to_tcb->partner != current->myself) + && (!l4_is_nil_id(to_tcb->partner)) ))) + { +// printf("ipc (%p->%p): partner not ready(%x->%x,%x)\n", +// current, to_tcb, current->myself.raw, +// to_tcb->partner.raw, to_tcb->thread_state); + + /* + * Is either not receiving or is receiving but not from + * me or any. + */ + + /* special case: send to ourself fails (JOCHEN-compatible) */ + if (to_tcb == current) + return_ipc(IPC_ERR_EXIST); + + if ( !IS_INFINITE_SEND_TIMEOUT(current->ipc_timeout) ) + { + /* + * We have a send timeout. Enqueue into wakeup queue. + */ + qword_t absolute_timeout = + TIMEOUT(current->ipc_timeout.timeout.snd_exp, + current->ipc_timeout.timeout.snd_man); + + if ( !absolute_timeout ) + { + IPC_SPIN_UNLOCK(&to_tcb->tcb_spinlock); + return_ipc(IPC_ERR_SENDTIMEOUT); + } + + current->absolute_timeout = absolute_timeout + + get_current_time(); + + thread_enqueue_wakeup(current); + } + + thread_enqueue_send(to_tcb, current); + current->thread_state = TS_POLLING; + IPC_SPIN_UNLOCK(&to_tcb->tcb_spinlock); + + /* Start waiting for send to complete. */ + ipc_switch_to_idle(current); + + if ( current->thread_state == TS_RUNNING ) + /* Reactivated because of a timeout. */ + return_ipc(IPC_ERR_SENDTIMEOUT); + + /* retake spinlock - improves critical path */ + IPC_SPIN_LOCK(&to_tcb->tcb_spinlock); + + thread_dequeue_wakeup(current); + } + + /* + * at this point we _always_ hold the spinlock + */ + + /* do message transfer */ + + if (EXPECT_TRUE( to_tcb->cpu == get_cpu_id() )) + { +#if 0 +#warning debug hack + if (!l4_is_nil_id(to_tcb->partner) && + to_tcb->partner != current->myself) + { + printf("current=%x (%p), to=%x, ", + current->myself.raw, get_user_ip(current), to_tcb->myself.raw); + printf("to->partner=%x (ip=%p), state=%x\n", + to_tcb->partner, get_user_ip(to_tcb), to_tcb->thread_state); + + if (to_tcb->thread_state == TS_WAITING) + { + printf("eval bool: %x\n", (!IS_WAITING(to_tcb) ) || + ((to_tcb->partner != current->myself) && (!l4_is_nil_id(to_tcb->partner)) )); + enter_kdebug("weird thread state"); + } + } + current->scratch = 0; +#endif + /* same cpu, we run with disabled interrupts */ + spin_unlock(&to_tcb->tcb_spinlock); + transfer_message(current, to_tcb, snd_desc); + + /* what can happen here ??? */ + to_tcb->partner = current->myself; + + if (EXPECT_FALSE( !IS_RECEIVE )) + { + /* set ourself running and enqueue to ready */ + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + + ipc_switch_to_thread(current, to_tcb); + return_ipc(0); + } + } + else { + //printf("inter-processor ipc: %x->%x\n", current, to_tcb); + + /* if a send is performed, we have to signal the other cpu + * for a receive the partner thread is already waiting + * and we can perform the IPC + */ + if ( current->thread_state != TS_XCPU_LOCKED_RUNNING ) + { + /* active send */ + current->thread_state = TS_LOCKED_RUNNING; + spin_unlock(&to_tcb->tcb_spinlock); + if (EXPECT_TRUE( IS_SHORT_IPC(snd_desc) )) + { + if (!smp_start_short_ipc(to_tcb, current)) + { + current->thread_state = TS_RUNNING; + goto restart_ipc_send; + } + transfer_message(current, to_tcb, snd_desc); + to_tcb->partner = current->myself; + smp_end_short_ipc(to_tcb); + } + else + { + if (!smp_start_ipc(to_tcb, current)) + { + current->thread_state = TS_RUNNING; + goto restart_ipc_send; + } + transfer_message(current, to_tcb, snd_desc); + to_tcb->partner = current->myself; + smp_end_ipc(to_tcb, current); + } + + } + else /* activated by a receive */ + { + /* partner is already waiting -> transfer the message */ + spin_unlock(&to_tcb->tcb_spinlock); + transfer_message(current, to_tcb, snd_desc); + to_tcb->partner = current->myself; + smp_end_ipc(to_tcb, current); + } + + if (EXPECT_FALSE( !IS_RECEIVE )) + { + /* set ourself running and enqueue to ready */ + current->thread_state = TS_RUNNING; + return_ipc(0); + } + + /* we do not want to switch to the partner if + * he resides on a different cpu + */ + to_tcb = NULL; + } + } + else + { + /* ERROR - Destination is invalid. */ + return_ipc(IPC_ERR_EXIST); + } + + } /* IS_SEND */ + + + /*---------------------------------------------------------------- + * + * We are receiving (perhaps in conjunction with send). + * + */ + + /* UD: We can drop this check. If there was no send phase then there + MUST BE a receive phase. Confirmed by Jochen. + //if ( IS_RECEIVE ) + */ + { +restart_ipc_receive: + + tcb_t * from_tcb; + //printf("ipc: receive branch (%x)\n", current); + + if (EXPECT_FALSE( current->intr_pending & IRQ_IN_SERVICE )) + { + unmask_interrupt((current->intr_pending & ~IRQ_IN_SERVICE) - 1); + current->intr_pending = 0; + } + + if (EXPECT_TRUE( !IS_OPEN_WAIT )) + { + + /*--- receive from ---*/ + from_tcb = tid_to_tcb(dest); + + /* special cases... taskid == 0 */ + if (EXPECT_FALSE( IS_KERNEL_ID(dest) )) + { + current->msg_desc = 0; + return_ipc_args(dest, ipc_handle_kernel_id(current, dest), current); + } + + if (EXPECT_FALSE( from_tcb->myself.raw != dest.raw )) + { + /* + * Destination is invalid. This can happen if we do a + * receive-only. Otherwise, the send branch has + * tested this already. + */ + return_ipc(IPC_ERR_EXIST); + } + IPC_SPIN_LOCK(¤t->tcb_spinlock); + //printf("ipc: receive from: %x\n", from_tcb); + } + else /* OPEN WAIT */ + { + if (EXPECT_FALSE( current->intr_pending )) + { + dword_t irq; + /* Interrupt is pending. Receive it. */ + irq = current->intr_pending; + current->intr_pending = IRQ_IN_SERVICE | irq; + + if ( to_tcb ) + { + /* + * If we did a send, we must make sure that the + * receiver is woken up. We can not simply make + * him RUNNING since that will cause him to return + * with an IPC_ERR_TIMEOUT. + */ + current->thread_state = TS_RUNNING; + thread_enqueue_ready(current); + + ipc_switch_to_thread(current, to_tcb); + } + /* empty msg desc */ + current->msg_desc = 0; + return_ipc_args(irq, 0, current); + } + + IPC_SPIN_LOCK(¤t->tcb_spinlock); + from_tcb = current->send_queue; + //printf("ipc: wait sq: %x\n", from_tcb); + } + + current->msg_desc = rcv_desc; + + /* + * no partner || partner does not exist || + * partner does not receive from me + */ + if ( EXPECT_FALSE(!from_tcb) || + EXPECT_TRUE(!IS_POLLING(from_tcb)) || + (from_tcb->partner != current->myself) ) + { + /* + * Partner is not ready to send to me yet or no partner. + */ + + if (EXPECT_FALSE( !IS_INFINITE_RECV_TIMEOUT(current->ipc_timeout) )) + { + /* + * We have a recv timeout. Enqueue into wakeup queue. + */ + qword_t absolute_timeout = + TIMEOUT(current->ipc_timeout.timeout.rcv_exp, + current->ipc_timeout.timeout.rcv_man); + + if ( !absolute_timeout ) + return_ipc(IPC_ERR_RECVTIMEOUT); + + current->absolute_timeout = absolute_timeout + + get_current_time(); + + thread_enqueue_wakeup(current); +// printf("enqueue %p into wakeup; timeout: 0x%x", +// current, current->ipc_timeout.raw); + } + + // this is not obvious - from_tcb can be only zero in one + // case - if we have an open wait. Otherwise the tcb does + // not exist (and we do not reach this path) or we have + // a valid tcb. thus, by checking for an open wait we are safe. + current->partner = EXPECT_FALSE(IS_OPEN_WAIT) ? L4_NIL_ID : from_tcb->myself; + current->thread_state = TS_WAITING; + IPC_SPIN_UNLOCK(¤t->tcb_spinlock); + + /* + * Start waiting for message to arrive. If we are + * also sending to the partner, switch to him. + */ + + if (EXPECT_TRUE( to_tcb != NULL )) + ipc_switch_to_thread(current, to_tcb); + else + ipc_switch_to_idle(current); + + if (EXPECT_FALSE( current->thread_state == TS_RUNNING )) + /* Reactivated because of a timeout. */ + return_ipc(IPC_ERR_RECVTIMEOUT); + + /* ok, got a message... */ + /* we could - but this is no clean solution - do + if (EXPECT_FALSE( current->queue_state & TS_QUEUE_WAKEUP )) + here to avoid calling the function if not needed */ + thread_dequeue_wakeup(current); + } + else + { + /* + * Partner is ready to send to me. + */ + + if (EXPECT_TRUE (from_tcb->cpu == get_cpu_id()) ) + { + /* + * if we don't switch to from_tcb we must + * enqueue from_tcb into the ready queue + */ + from_tcb->thread_state = TS_LOCKED_RUNNING; + thread_enqueue_ready(from_tcb); + + /* + * The sender is waiting for us. As such, he is in + * our send-queue. Dequeue him. + */ + + thread_dequeue_send(current, from_tcb); + current->thread_state = TS_LOCKED_WAITING; + + /* this lock secured our thread state as well as + * the send queue */ + IPC_SPIN_UNLOCK(¤t->tcb_spinlock); + + + /* + * Switch to our waiting partner. + * If we don't switch to the woken up we have + * to dequeue him from the wakeup queue + */ + thread_dequeue_wakeup(from_tcb); + + if ( to_tcb ) + ipc_switch_to_thread(current, to_tcb); + else + ipc_switch_to_thread(current, from_tcb); + if (from_tcb->myself != current->partner) + enter_kdebug("oops partner invalid"); + } + else + { + /* other cpu */ + current->thread_state = TS_LOCKED_WAITING; + IPC_SPIN_UNLOCK(¤t->tcb_spinlock); + + /* the partner dequeues himself from the send + * queue on an ipi */ + if (!smp_start_receive_ipc(from_tcb, current)) { + current->thread_state = TS_LOCKED_RUNNING; + goto restart_ipc_receive; + } + + /* ok, ipc send starts on other cpu now - switch + * to other thread and wait for re-activation */ + + if ( to_tcb ) + ipc_switch_to_thread(current, to_tcb); + else + switch_to_idle(current); + } + } + + current->thread_state = TS_RUNNING; + return_ipc_args(current->partner, 0, current); + } +enter_kdebug("endof_ipc"); + return_ipc(0); +} +#endif /* defined(CONFIG_SMP) */ diff --git a/kernel/src/x86/smpipc.o b/kernel/src/x86/smpipc.o new file mode 100644 index 0000000..3187af9 Binary files /dev/null and b/kernel/src/x86/smpipc.o differ diff --git a/kernel/x86-kernel b/kernel/x86-kernel new file mode 100644 index 0000000..12f969e Binary files /dev/null and b/kernel/x86-kernel differ diff --git a/kernel/x86-kernel.stripped b/kernel/x86-kernel.stripped new file mode 100644 index 0000000..b348d67 Binary files /dev/null and b/kernel/x86-kernel.stripped differ diff --git a/kernel/xconfig/.config b/kernel/xconfig/.config new file mode 100644 index 0000000..48511fb --- /dev/null +++ b/kernel/xconfig/.config @@ -0,0 +1,91 @@ +# +# Automatically generated make config: don't edit +# + +# +# Architecture +# +CONFIG_ARCH_X86=y +CONFIG_ARCH_ARM=n +CONFIG_ARCH_MIPS=n +CONFIG_ARCH_SH=n +CONFIG_ARCH_M68K=n +CONFIG_ARCH_ARM_DNARD=y +CONFIG_ARCH_ARM_BRUTUS=n +CONFIG_ARCH_ARM_PLEB=n +CONFIG_ARCH_ARM_IPAQ=n +CONFIG_ARCH_ARM_EP7211=n +CONFIG_ARCH_X86_I586=n +CONFIG_ARCH_X86_I686=y +CONFIG_ARCH_X86_P4=n +CONFIG_IA32_FEATURE_PSE=y +CONFIG_IA32_FEATURE_PGE=y +CONFIG_IA32_FEATURE_SEP=y +CONFIG_IA32_FEATURE_FXSR=y +CONFIG_IA32_FEATURE_MSR=y +CONFIG_IA32_FEATURE_CMOV=y +CONFIG_ARCH_MIPS_R4000=y + +# +# Kernel Configuration +# +CONFIG_JOCHEN_BUGS=n +CONFIG_SIGMA0_ENTRY=n +CONFIG_ROOTTASK_ENTRY=n +CONFIG_SMP=n +CONFIG_X86_IOAPIC=n +CONFIG_X86_APICTIMER=n +CONFIG_X86_INKERNEL_PIC=y +CONFIG_PERFMON=n +CONFIG_X86_WBINVD_EMULATION=n +CONFIG_ENABLE_PROFILING=n +CONFIG_IPC_FASTPATH=n +CONFIG_ENABLE_SMALL_AS=n +CONFIG_SMALL_AREA_512MB=n +CONFIG_SMALL_AREA_1GB=n +CONFIG_SMALL_AREA_2GB=n +CONFIG_IO_FLEXPAGES=y +CONFIG_AUTO_IO_MAP=n +CONFIG_ENABLE_PVI=n +CONFIG_CACHEABILITY_BITS=n + +# +# Debug Configuration +# +CONFIG_DEBUGGER_KDB=y +CONFIG_DEBUGGER_NEW_KDB=n +CONFIG_DEBUGGER_IO_INKBD=n +CONFIG_DEBUGGER_IO_INCOM=y +CONFIG_DEBUGGER_IO_OUTSCRN=n +CONFIG_DEBUGGER_IO_OUTCOM=y +CONFIG_DEBUGGER_COMPORT=3F8 +CONFIG_DEBUGGER_COMSPEED=115200 +CONFIG_DEBUGGER_IO_SCREEN_VGA=y +CONFIG_DEBUGGER_IO_SCREEN_HERCULES=n +CONFIG_DEBUG_DISAS=n +CONFIG_KEEP_LAST_BRANCHES=n +CONFIG_USERMODE_NOIRQ=n +CONFIG_DEBUG=y +CONFIG_DEBUG_DOUBLE_PF_CHECK=n +CONFIG_DEBUG_BREAKIN=y +CONFIG_DEBUG_KDB_ONSTART=y +CONFIG_DEBUG_SANITY=n + +# +# Trace Settings +# +CONFIG_DEBUG_TRACE_KPF=y +CONFIG_DEBUG_TRACE_UPF=y +CONFIG_DEBUG_TRACE_IRQS=n +CONFIG_DEBUG_TRACE_IPC=y +CONFIG_DEBUG_TRACE_SYSCALLS=n +CONFIG_DEBUG_TRACE_MDB=y +CONFIG_DEBUG_TRACE_SMP=n +CONFIG_DEBUG_TRACE_IPI=n +CONFIG_DEBUG_TRACE_MISC=n +CONFIG_DEBUG_TRACE_INIT=n +CONFIG_DEBUG_SPIN=n +CONFIG_TRACEBUFFER=n +CONFIG_ENABLE_TRACEPOINTS=n +CONFIG_ENABLE_SWITCH_TRACE=n +CONFIG_MEASURE_INT_LATENCY=n diff --git a/kernel/xconfig/.cvsignore b/kernel/xconfig/.cvsignore new file mode 100644 index 0000000..347f119 --- /dev/null +++ b/kernel/xconfig/.cvsignore @@ -0,0 +1,5 @@ +.config +config.h +tkparse +config.tk +*.i *.ii *.s diff --git a/kernel/xconfig/Makefile b/kernel/xconfig/Makefile new file mode 100644 index 0000000..55a6f94 --- /dev/null +++ b/kernel/xconfig/Makefile @@ -0,0 +1,45 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: Makefile +## +## @LICENSE@ +## +## $Id: Makefile,v 1.8 2001/11/22 15:57:34 skoglund Exp $ +## +###################################################################### +SHELL=bash + +ifeq ($(MACHTYPE), i686-pc-cygwin) + WISH=cygitkwish30 +else +ifneq ($(shell type -p wish8.3),) + WISH=wish8.3 +else + WISH=wish +endif +endif + +-include ../Makeconf.local + +doit: config.tk + @$(WISH) -f config.tk + @echo Rewriting Makeconf.local + @awk -F'[_=]' '/^CONFIG_ARCH_[^_]*=y/ { ARCH=$$3 } /^CONFIG_ARCH_[^_]*_[^_]*=y/ { if ($$3 == ARCH) { printf(",s/^PLATFORM=.*/PLATFORM=%s/\nwq\n", tolower($$4)) }}' .config | ed -s ../Makeconf.local + +config.tk: $(wildcard *.in) header.tk tail.tk tkparse + cat header.tk > config.tk && \ + ./tkparse < config.in >> config.tk && \ + echo "set defaults \"defconfig\"" >> config.tk && \ + cat tail.tk >> config.tk + +tkparse: tkparse.o tkcond.o tkgen.o + ${CC} -o tkparse tkparse.o tkcond.o tkgen.o + +../Makeconf.local: + @echo Creating default Makeconf.local + @echo "PLATFORM=i686" >> ../Makeconf.local + +clean: + rm -f *.o tkparse config.tk diff --git a/kernel/xconfig/arch.in b/kernel/xconfig/arch.in new file mode 100644 index 0000000..679ae66 --- /dev/null +++ b/kernel/xconfig/arch.in @@ -0,0 +1,89 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: arch.in +## Description: Configuration of hardware architectures. +## +## @LICENSE@ +## +## $Id: arch.in,v 1.16 2002/01/24 07:07:26 uhlig Exp $ +## +###################################################################### + +mainmenu_option next_comment +comment 'Architecture' + +if [ "1" != "0" ]; then + define_bool _CONFIG_ARCH y +fi + +choice 'Major CPU Architecture' \ + "x86 CONFIG_ARCH_X86 \ + arm CONFIG_ARCH_ARM \ + mips CONFIG_ARCH_MIPS \ + superh CONFIG_ARCH_SH \ + m68k CONFIG_ARCH_M68K" x86 $_CONFIG_ARCH + +if [ "$CONFIG_ARCH_ARM" = "y" ]; then + choice 'ARM Board Type' \ + "DNARD CONFIG_ARCH_ARM_DNARD \ + Brutus CONFIG_ARCH_ARM_BRUTUS \ + PLEB CONFIG_ARCH_ARM_PLEB \ + IPaq CONFIG_ARCH_ARM_IPAQ \ + EP7211 CONFIG_ARCH_ARM_EP7211" DNARD $CONFIG_ARCH_ARM +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + choice 'x86 Model' \ + "Pentium CONFIG_ARCH_X86_I586 \ + P-II/P-III CONFIG_ARCH_X86_I686 \ + P4 CONFIG_ARCH_X86_P4" i686 $CONFIG_ARCH_X86 + + if [ "$CONFIG_ARCH_X86_I586" = "y" ]; then + define_bool CONFIG_IA32_FEATURE_PSE y + define_bool CONFIG_IA32_FEATURE_PGE n + define_bool CONFIG_IA32_FEATURE_SEP n + define_bool CONFIG_IA32_FEATURE_FXSR n + fi + + if [ "$CONFIG_ARCH_X86_I686" = "y" ]; then + define_bool CONFIG_IA32_FEATURE_PSE y + define_bool CONFIG_IA32_FEATURE_PGE y + define_bool CONFIG_IA32_FEATURE_SEP y + define_bool CONFIG_IA32_FEATURE_FXSR y + define_bool CONFIG_IA32_FEATURE_MSR y + define_bool CONFIG_IA32_FEATURE_CMOV y + fi + + if [ "$CONFIG_ARCH_X86_P4" = "y" ]; then + define_bool CONFIG_IA32_FEATURE_PSE y + define_bool CONFIG_IA32_FEATURE_PGE y + define_bool CONFIG_IA32_FEATURE_SEP y + define_bool CONFIG_IA32_FEATURE_FXSR y + define_bool CONFIG_IA32_FEATURE_MSR y + define_bool CONFIG_IA32_FEATURE_CMOV y + fi +fi + + + +if [ "$CONFIG_ARCH_MIPS" = "y" ]; then + choice 'MIPS CPU Model' \ + "R4000 CONFIG_ARCH_MIPS_R4000" R4000 $CONFIG_ARCH_MIPS +fi + +#if [ "$CONFIG_ARCH_SH" = "y" ]; then +# choice 'SuperH Model' \ +# "Emulator CONFIG_ARCH_SH_EMU \ +# SH3 CONFIG_ARCH_SH_SH3 \ +# SH4 CONFIG_ARCH_SH_SH4" SH3 $CONFIG_ARCH_SH +#fi + + +#if [ "$CONFIG_ARCH_M68K" = "y" ]; then +# choice 'm68k CPU Model' \ +# "Dragonball CONFIG_ARCH_M68K_DRAGONBALL" Dragonball $CONFIG_ARCH_M68K +#fi + + diff --git a/kernel/xconfig/config.help b/kernel/xconfig/config.help new file mode 100644 index 0000000..5e5a450 --- /dev/null +++ b/kernel/xconfig/config.help @@ -0,0 +1,513 @@ +###################################################################### +## +## Copyright (C) 1999-2002, Karlsruhe University +## +## File path: xconfig/config.help +## Description: Help file for configuration tool. +## +## @LICENSE@ +## +## $Id: config.help,v 1.30 2002/06/07 17:02:29 skoglund Exp $ +## +###################################################################### + +architecture selection +CONFIG_ARCH_X86 + Architecture selection + + Those who don't know what this is all about shoudn't care about it at all. +_ + +platform selection for ARM +CONFIG_ARCH_ARM_DNARD + Select the flavour of your ARM-based box + + DNARD: The Digital Network Appliance Reference Design + http://www.research.digital.com/SRC/iag/ + + Brutus: intel's SA-1100 based evaluation board + http://developer.intel.com/design/strong/quicklist/\ + eval-plat/sa-1100me.htm + + EP7211: Cirrus Logic's ARM7 based evaluation board + http://www.cirrus.com/design/products/overview/\ + index.cfm?ProductID=110 +_ + +platform selection for x86 +CONFIG_ARCH_X86_I586 + Select the flavour of your x86 box + + i586: Pentium + i686: PII, PIII + P4: Pentium 4 +_ + +CONFIG_ARCH_MIPS_R4000 + Oooops. I feel as if someone had mentioned the word MIPS. What's that? + + + BUMMER! +_ + +CONFIG_JOCHEN_BUGS + Jochen-bug compatibility mode + + Due to the possibility of interpreting the L4 specification differently, + certain operations might be implemented differently in kernels. Whether + a certain implementation is a bug or not heavily depends on your reading + of the specification. + + Saying Y here implements some operations like the assembly kernel does: + - a thread is not allowed to do IPC with itself + - offset of actually transfered dwords in long messages + + If you want to use Flick/L4 you have to say Y here. + + Be warned that saying N here could break your existing software. However, + then this kernel implements _OUR_ understanding of the specification. + + Note: This doesn't influence those parts of the specification that are + not implemented yet in this kernel. +_ + +default sigma0 entry point +CONFIG_SIGMA0_ENTRY + Turning this on initializes the kernel info page with the given + values. Hence, there's no need for the boot process to write the + sigma0 initial IP and SP values to the kernel info page. + + src/global.c +_ + +default root task entry point +CONFIG_ROOTTASK_ENTRY + Turning this on initializes the kernel info page with the given + values. Hence, there's no need for the boot process to write the + initial IP and SP values for the root task to the kernel info page. + + src/global.c +_ + +Architecture specific kmemory +CONFIG_HAVE_ARCH_KMEM + If set, the architecture specific kernel memory allocator will + be activeted instead of the generic one (i.e. kmem_alloc() and + kmem_free()). + + src/kmemory.c +_ + +CONFIG_SMP + Symmetric Multi Processoring with L4 is considered HIGHLY EXPERIMENTAL. + Interfaces to control migration are still floating, semantics of some + system calls that are fine on uniprocessors are not completely defined + on SMPs (system calls executed serially before may run in parallel now), + scheduling relying on hard priorities renders halfways useless if there + are multiple parallel time axes, etc. ... + + L4 on SMP is currently only tested on i440BX chipsets. In contrast to + what one would expect, an SMP kernel may not work on uniprocessors. + + Despite that, everybody is encouraged to mess around with this feature. +_ + +CONFIG_SMP_MAX_CPU + Sometimes it may be desirable to limit the number of actived CPUs. + This is an upper limit only, not a must-have. + + Btw, Intel's PIII systems seem to be limited to 15 processors anyway. +_ + +Marcus SMP XP IPC playground +CONFIG_MARCUS_XP_IPC + This is only effective, if the SMP Nucleus was configured. Turning + this on uses an experimental IPC path with proxy threads instead + of the normal IPI handler based approach. +_ + +CONFIG_X86_IOAPIC + The IO-APIC is the Advanced I/O Programmable Interrupt Controller found + in SMP PC boxes. It's required to distribute IRQs across multiple CPUs. + There is at least one IO-APIC per SMP system and one APIC in every CPU. +_ + +CONFIG_X86_APICTIMER + The APIC is the Advanced Programmable Interrupt Controller found in SMP- + capable IA32 CPUs. In contrast to the IO-APIC, there is an APIC per CPU. + + In today's L4 user land, every device driver thinks that it must reenable + and sometimes even acknowledge/disable the IRQ on the PIC. Without proper + locking this can lead to totally messed up PIC states easily. If a driver + fails to handle the PIC correctly, timer interrupts could be disabled and + scheduling stops. + When using the APIC timer instead, a driver can no longer to accidently + disable the kernel timer. However, it still could disable IRQs ... :-( +_ + +CONFIG_X86_INKERNEL_PIC + Enables automatic PIC acknowledgement similar to the APIC (which is not + exported to user mode). When an interrupt occurs, the IRQ on the PIC is + is disabled. It is re-enabled on the next IPC which may potentially receive + an interrupt. (receive(#irq) or wait) + +- + +CONFIG_PERFMON + Allows kernel debugger to set up the Performance Monitoring Counters, and + user-level applications to access them using the RDPMC instruction. +_ + +CONFIG_X86_WBINVD_EMULATION + The wbinvd instruction flushes the internal caches. That is used by + some L4Linux drivers. This button allows to enable full emulation (i.e. + WBINVD is executed by the kernel). Otherwise, the instruction is simply + skipped. +- + +CONFIG_X86_P4_BTS + Allow the the Pentium 4 Branch Trace Store to be enabled and accessed + from within in the kernel debugger. The branch trace store keeps track + of the most recent branches the processor has taken, and can be used for, + e.g., dubugging purposes. Enabling the trace store will, however, + seriously degrade the performance of your system. +_ + +CONFIG_X86_P4_BTS_BUFSIZE + The amount of memory used for storing branch traces (in KB). Each + branch trace is 12 bytes. A 4KB buffer can as such contain up to 341 + branch trace records. +_ + +CONFIG_X86_P4_PEBS + Allow the Pentium 4 Precise Event-Based Sampling to be enabled and + accessed from within the kernel debugger. Precise Event-Based Sampling + requires the CPU to have an APIC. +_ + +CONFIG_X86_P4_PEBS_BUFSIZE + The amount of memory used for storing precise event samples (in KB). + Each branch trace is 40 bytes. A 64KB buffer can as such contain up to + 1638 precise event samples. +_ + +CONFIG_ENABLE_PROFILING + Allows continuous profiling to be performed on user-level and kernel- + level code. The profiling may be triggered by various events, and + samples (registers or events) may be measured for single instructions. + Profiling requires the CPU to have an APIC. +_ + +CONFIG_PROFILING_WITH_NMI + Enables profiling events to be triggered using Non Maskable Interrupts. + This had the advantage that even the kernel or user-level drivers with + interrupts disabled can be profiled. Needless to say, if you want + to profile the kernel you must enable this option. +_ + +CONFIG_PROFILING_MAX_VAL + An upper limit on the number of value samples per instruction that + you can log in your profiling log. Raising this number means that + you can collect more statistics about each sampled instruction but + also that more memory will be used for each sample (i.e., it lowers + the maximum number of profile log entries). +_ + +CONFIG_IPC_FASTPATH + Hazelnut supports a fast IPC implementation which is 100% pure assembly. + This feature is currently still experimental but works in most cases. +_ + +CONFIG_ENABLE_SMALL_AS + Small address spaces is a mechanism for avoiding TLB flushes on address + space switches. Currently, small spaces is only implmented on IA-32. It + emulates tagged TLBs (and physically tagged Trace Caches in the case of + Pentium 4) using the IA-32 segmentation model. +_ + +CONFIG_GLOBAL_SMALL_SPACES + Put small spaces into global pages. This avoids TLB entries for small + address spaces to be flushed on normal TLB flush operations. +_ + +CONFIG_SMALL_AREA_512MB + The size of the area used for small spaces (default 512MB). The size of + the area also dictates the minimum size of a small space and the area + remaining to be used for large spaces. + + Size Min. space size Used virtual area + ---- --------------- ----------------- + 512MB 4MB 0xC0000000 - 0xE0000000 + 1GB 8MB 0xA0000000 - 0xE0000000 + 2GB 16MB 0x60000000 - 0xE0000000 + + Note that the user-level API for setting small spaces does not change + to reflect the larger small space area size. A request for a 4MB space + will thus be treated as a request for a 8MB or 16MB space for the 1GB + and 2GB case, respectively. +_ + +CONFIG_ENABLE_TCB_PAGER + This stuff is related to the persistence in L4 approach. Actually, it's + not ment to be in here. + + It's considered somewhere between EXTREMELY EXPERIMENTAL and DANGEROUS. + Don't turn this on unless you are at least one of the probably not more + than 1.5 people that could know what it's all about. You've been warned! +_ + +CONFIG_CACHEABILITY_BITS + + Enable ability to specify bits in the fpage of a map operation + controlling the cacheability and/or bufferability of the mapped page + frames. Note that the cacheability and bufferability bits are hardware + dependent and may not produce the desired result. +_ + + +CONFIG_DEBUGGER_KDB + This enables the built-in kernel debugger. This is a must. + + There was the idea of having alternative debugger interfaces like GDB, + but the need for that was not strong enough. +_ + +CONFIG_DEBUGGER_GDB + Forget this tunable. Reenable the L4/Ka Kernel Debugger! +_ + +CONFIG_DEBUGGER_NEW_KDB + The new debugger. Get more information at + http://i30www.ira.uka.de/~swagner +_ + +CONFIG_DEBUGGER_IO_INKBD + This option selects the input device for the kernel debugger. + +- + +CONFIG_DEBUGGER_IO_OUTSCRN + This option selects the output device for the kernel debugger. + +- + +CONFIG_DEBUGGER_COMPORT + Select the com-port address for the kernel debugger output. That + feature is only available if 'serial' was selected as input and/or + output device. + + Common ports are: + COM1: 3F8 + COM2: 2E8 + +- + +CONFIG_DEBUGGER_COMSPEED + Selects the speed of the serial line for debugger output. This feature + is only available if 'serial' was selected as input and/or output device. + +- + +CONFIG_DEBUGGER_IO_SCREEN_VGA + Screen output device. This feature is only available if 'screen' was + selected as output device + +- + +CONFIG_DEBUGGER_IO_KBD_DE + Keyboard layout for the kernel debugger. (Not implemented ;) + +- + +Enable Disassembler +CONFIG_DEBUG_DISAS + This enables the disassembler in the built-in kernel debugger. + The disassembler uses binutil's libopcodes. + + Be warned that this enlarges your kernel by ~60k for x86 + and by ~13k for ARM. +_ + +CONFIG_KEEP_LAST_BRANCHES + Keep the state of the last-branch model specific registers upon + exceptions and enter kdebug instructions. Useful for seeing where the + last branch occured in user level (e.g., where a branch to an invalid + instruction occured). + +_ +Disable INTs in user mode +CONFIG_USERMODE_NOIRQ + Setting this option to YES creates all user threads with disabled + interrupts. This could easily disable timer triggered events like + scheduling, IPC timeouts, etc. + + create_user_stack_frame in include/arch/thread.h +_ + +CONFIG_DEBUG + Enables debugging features and turns on ASSERT macros. + +- + +CONFIG_DEBUG_BREAKIN + Allows to remotely breakin into the kernel debugger by hitting ESC. + Currently, that feature is only available when using the serial line as + input device. + +- + +CONFIG_DEBUG_KDB_ONSTART + The kernel enters the kernel debugger before switching to the root task. +_ + +CONFIG_DEBUG_SANITY + Enables some sanity additional checks. Do not use this feature when + benchmarking - you may experience a major slow-down. + +- + +Trace kernel page faults +CONFIG_DEBUG_TRACE_KPF + If set to yes, kernel page faults are reported. + + This means that also page faults in the temporary mapping area are + reported (which tends to confuse even experienced users from time to + time ;-). + + src/arch/memory.c +_ + +Trace user page faults +CONFIG_DEBUG_TRACE_UPF + If set to yes, user page faults are reported. + + src/arch/memory.c +_ + +Trace interrupts +CONFIG_DEBUG_TRACE_IRQS + If set, detection of an interrupt is reported. + + src/arch/interrupt.c +_ + +CONFIG_DEBUG_TRACE_SYSCALLS + If set, system calls are traced with their parameters. + + This will cause a major slowdown and the will also have influence on + the scheduling behaviour (Never assume that what you see with tracing + will happen the same way without syscall tracing!!!) +_ + +CONFIG_DEBUG_TRACE_IPC + Trace IPCs in a single-entry trace buffer. Depending on the KDB, all + the interesting parameters of the IPC system call are dumped with + optionally entering the kernel debugger. + + Setting this to Y will cause a certain slowdown of the IPC system call + since the parameters are recorded. However activating IPC tracing in + the KDB then will cause a major slowdown because the messages are then + printed. +_ + +Trace Mapping Database +CONFIG_DEBUG_TRACE_MDB + If set, calls to mdb_map() and mdb_flush() are reported. + + src/mapping.c + +- + +Trace SMP +CONFIG_DEBUG_TRACE_SMP + Traces SMP events (processor detection and startup) +- + +CONFIG_DEBUG_TRACE_IPI + Enables IPI tracing - carefull, this is lots of output. +_ + +CONFIG_DEBUG_TRACE_MISC + Enable loads of informative/debugging output during normal operation. + + This can induce major slowdown. +_ + +CONFIG_DEBUG_TRACE_INIT + Enable loads of informative/debugging output during initialization. +_ + +CONFIG_DEBUG_SPIN + Enables "spinning wheels" in the upper right corner of the screen. To + be honest, these are not really wheels. It's a simply an increment of + whatever value is in the video memory at that position. + On SMPs, the wheels are per CPU - CPU 0 is in the top line. + + Horizontal positions (events may be disabled by other means): + + 79: idle loop schedule.c:362 + 78: end of timeslice schedule.c:301 + 77: hardware interrupt ipc.c:309 + 75: switch_to(L4_NIL_ID) schedule.c:378 +_ + +CONFIG_TRACEBUFFER + Enables tracebuffer support. The tracebuffer is used by the kernel + to record the occurrence of certain events (such as syscalls, interrupts, + pagefaults...) together with an associated timestamp. This is useful + for debugging because the sequence of events that caused a particular + problem can be identified. The buffer is also mapped writable to user + level, so applications can record events as well. + + This feature causes the kernel to run considerably slower. + If unsure, say N. +_ + +CONFIG_ENABLE_TRACEPOINTS + Enables tracepoint support in the kernel. Tracepoints can be used to + keep track of how often certain event occur in the kernel, and + optionally print debugging information and enter kernel debugger when + these events occur. +_ + +CONFIG_ENABLE_SWITCH_TRACE + Enables tracing of thread switches, recording the instruction pointers + and stack pointers of both the source and the destination thread. +_ + +CONFIG_SWITCH_TRACE_SIZE + Number of thread switches which are recorded. Traces are recorded in + a circular buffer. When the buffer overflows the oldest traces are + overwritten. +_ + +CONFIG_IO_FLEXPAGES + This enables support for IO-FlexPages + +- + +CONFIG_AUTO_IO_MAP + Saying yes to this option will create a default IO-mapping of 64K for + all new Tasks, which results in every task per default being able to + access IO ports. This behaviour is inheritant; a task lacking full + permissions to access all IO-ports creating a new task will result + in the new one having no access at all. + +- +CONFIG_ENABLE_PVI + As cli and sti are IO instructions, too, enabling IO FlexPages will + result in only the kernel being able to clear and set interrupts + anymore; user tasks will raise an exception 13 instead. Protected + Mode Virtual Interrupts (PVI) solve that problem transparently. + If running in PVI mode, user level tasks can use cli and sti. + The PVI implementation is EXPERIMENTAL, rudimentary, and does not + care about priority problems at all. +- + +CONFIG_MEASURE_INT_LATENCY + Turn on interrupt latency measurements. Upon each interrupt we store + the value of the local APIC timer (upon interrupt handler entry) in dw0 + of the returned interrupt IPC. We store the rdtsc value of the + interrupt handler entry in dw1, and the rdtsc value just before returning + from sys_ipc() in dw2. +_ diff --git a/kernel/xconfig/config.in b/kernel/xconfig/config.in new file mode 100644 index 0000000..43eca77 --- /dev/null +++ b/kernel/xconfig/config.in @@ -0,0 +1,25 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: config.in +## Description: Main configuration specification file. +## +## @LICENSE@ +## +## $Id: config.in,v 1.4 2001/11/22 15:57:34 skoglund Exp $ +## +###################################################################### + +mainmenu_name "L4/KA Configuration" + +source arch.in + +source kernel.in + +source debugger.in + +source trace.in + +endmenu + diff --git a/kernel/xconfig/debugger.in b/kernel/xconfig/debugger.in new file mode 100644 index 0000000..08e6a17 --- /dev/null +++ b/kernel/xconfig/debugger.in @@ -0,0 +1,68 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, Karlsruhe University +## +## File path: debugger.in +## Description: Configuration for various debug options. +## +## @LICENSE@ +## +## $Id: debugger.in,v 1.22 2001/12/13 03:21:14 ud3 Exp $ +## +###################################################################### + +mainmenu_option next_comment +comment 'Debug Configuration' + +# these two are mutually exclusive +if [ "$CONFIG_DEBUGGER_GDB" != "y" ]; then +bool 'L4/KA Kernel Debugger' CONFIG_DEBUGGER_KDB y +fi + +if [ "$CONFIG_DEBUGGER_KDB" != "y" ]; then +bool 'Remote GDB Debugger' CONFIG_DEBUGGER_GDB n +fi + +if [ "$CONFIG_DEBUGGER_KDB" != "y" ] + define_bool _HAVE_KDB n +else + bool 'Use new KDB' CONFIG_DEBUGGER_NEW_KDB n + define_bool _HAVE_KDB y + choice 'debugger input device' \ + "kbd CONFIG_DEBUGGER_IO_INKBD \ + serial CONFIG_DEBUGGER_IO_INCOM" serial $_HAVE_KDB + choice 'debugger output device' \ + "screen CONFIG_DEBUGGER_IO_OUTSCRN \ + serial CONFIG_DEBUGGER_IO_OUTCOM" serial $_HAVE_KDB +fi + +if [ "$CONFIG_DEBUGGER_KDB" = "y" -a "$CONFIG_DEBUGGER_IO_INCOM" = "y" -o "$CONFIG_DEBUGGER_KDB" = "y" -a "$CONFIG_DEBUGGER_IO_OUTCOM" = "y" -o "$CONFIG_DEBUGGER_GDB" = "y" ] + hex 'Serial port address' CONFIG_DEBUGGER_COMPORT 3F8 + int 'Serial port speed' CONFIG_DEBUGGER_COMSPEED 115200 +fi + +if [ "$CONFIG_DEBUGGER_IO_OUTSCRN" = "y" -a "$CONFIG_ARCH_X86" = "y" ] + choice 'debugger output screen type' \ + "vga CONFIG_DEBUGGER_IO_SCREEN_VGA \ + hercules CONFIG_DEBUGGER_IO_SCREEN_HERCULES" hercules +fi + +if [ "$CONFIG_DEBUGGER_KDB" = "y" ] + bool 'Enable disassembler' CONFIG_DEBUG_DISAS n + if [ "$CONFIG_ARCH_X86" = "y" ] + bool 'Keep last branches' CONFIG_KEEP_LAST_BRANCHES n + fi +fi + +bool 'Disable INTs in user mode' CONFIG_USERMODE_NOIRQ n + +bool 'Enable debugging' CONFIG_DEBUG y + +if [ "$CONFIG_DEBUG" = "y" ] + bool 'Double pagefault check' CONFIG_DEBUG_DOUBLE_PF_CHECK n + bool 'Remote enter-KDB' CONFIG_DEBUG_BREAKIN n + bool 'Enter KDB on start' CONFIG_DEBUG_KDB_ONSTART n +fi +bool 'Enable Sanity checks' CONFIG_DEBUG_SANITY n + +endmenu diff --git a/kernel/xconfig/defconfig b/kernel/xconfig/defconfig new file mode 100644 index 0000000..178704e --- /dev/null +++ b/kernel/xconfig/defconfig @@ -0,0 +1,37 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, 2003, Karlsruhe University +## +## File path: xconfig/defconfig +## Description: Default configuration. +## +## @LICENSE@ +## +## $Id: defconfig,v 1.8 2003/04/26 22:57:05 ud3 Exp $ +## +###################################################################### +# +CONFIG_ARCH_X86=y +# +CONFIG_ARCH_X86_I686=y +CONFIG_ARCH_ARM_DNARD=y +CONFIG_ARCH_MIPS_R4000=y +CONFIG_ARCH_SH_EMU=y +CONFIG_ARCH_M68K_DRAGONBALL=y +# +CONFIG_VERSION_X0=y +CONFIG_JOCHEN_BUGS=n +# +CONFIG_DEBUGGER_KDB=y +CONFIG_DEBUGGER_IO_INCOM=y +CONFIG_DEBUGGER_IO_OUTCOM=y +CONFIG_DEBUGGER_IO_SCREEN_VGA=y +CONFIG_DEBUGGER_IO_KBD_US=y + +CONFIG_DEBUG=y +CONFIG_DEBUG_TRACE_KPF=y +CONFIG_DEBUG_TRACE_UPF=y +CONFIG_DEBUG_TRACE_IPC=y +CONFIG_DEBUG_TRACE_MDB=y +CONFIG_DEBUG_BREAKIN=y +CONFIG_DEBUG_KDB_ONSTART=y diff --git a/kernel/xconfig/header.tk b/kernel/xconfig/header.tk new file mode 100644 index 0000000..7921002 --- /dev/null +++ b/kernel/xconfig/header.tk @@ -0,0 +1,485 @@ +# FILE: header.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1999, Michael Elizabeth Chastain, +# - Remove unused do_cmd function (part of the 2.0 sound support). +# - Arrange buttons in three columns for better screen fitting. +# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like: +# dep_tristate 'foo' CONFIG_FOO m +# +# 23 January 1999, Michael Elizabeth Chastain, +# - Shut vfix the hell up. +# +# 24 January 1999, Michael Elizabeth Chastain, +# - Improve the exit message (Jeff Ronne). + +# +# This is a handy replacement for ".widget cget" that requires neither tk4 +# nor additional source code uglification. +# +proc cget { w option } { + return "[lindex [$w configure $option] 4]" +} + +# +# Function to compensate for broken config.in scripts like the sound driver, +# which make dependencies on variables that are never even conditionally +# defined. +# +proc vfix { var } { + global $var + if [ catch {eval concat $$var} ] { + set $var 0 + } +} + +# +# Constant values used by certain dep_tristate commands. +# +set CONSTANT_Y 1 +set CONSTANT_M 2 +set CONSTANT_N 0 + +# +# Create a "reference" object to steal colors from. +# +button .ref + +# +# On monochrome displays, -disabledforeground is blank by default; that's +# bad. Fill it with -foreground instead. +# +if { [cget .ref -disabledforeground] == "" } { + .ref configure -disabledforeground [cget .ref -foreground] +} + + +# +# Define some macros we will need to parse the config.in file. +# + +proc mainmenu_name { text } { + wm title . "$text" +} + +proc menu_option { w menu_num text } { + global menus_per_column +# if { $menu_num <= $menus_per_column } then { +# set myframe left +# } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { +# set myframe middle +# } else { +# set myframe right +# } + if { $menu_num <= 6 } then { + set myframe arch + } elseif { $menu_num <= [expr 2 * $menus_per_column] } then { + set myframe apps + } else { + set myframe control + } + button .f0.x$menu_num -anchor w -text "$text" \ + -command "$w .$w \"$text\"" + pack .f0.x$menu_num -pady 0 -side top -fill x -in .f0.$myframe +} + +proc load_configfile { w title func } { + catch {destroy $w} + toplevel $w -class Dialog + global loadfile + frame $w.x + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + label $w.x.l -text "Enter filename:" -relief raised + entry $w.x.x -width 35 -relief sunken -borderwidth 2 \ + -textvariable loadfile + pack $w.x.l $w.x.x -anchor w -side left + pack $w.x -side top -pady 10 + wm title $w "$title" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "destroy $w; focus $oldFocus;$func .fileio" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc maybe_exit { w } { + catch {destroy $w} + toplevel $w -class Dialog + label $w.bm -bitmap questhead + pack $w.bm -pady 10 -side top -padx 10 + message $w.m -width 400 -aspect 300 \ + -text "Changes will be lost. Are you sure?" -relief flat + pack $w.m -pady 10 -side top -padx 10 + wm title $w "Are you sure?" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" -width 20 \ + -command "exit" + button $w.f.canc -text "Cancel" \ + -width 20 -command "destroy $w; focus $oldFocus" + pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 + pack $w.f -pady 10 -side bottom -padx 10 -anchor w + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc read_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 && [file readable $loadfile] == 1 } then { + read_config $loadfile + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to read file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "Bummer" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc write_config_file { w } { + global loadfile + if { [string length $loadfile] != 0 + && ([file writable $loadfile] == 1 || ([file exists $loadfile] == 0 && [file writable [file dirname $loadfile]] == 1)) } then { + writeconfig $loadfile /dev/null + } else { + catch {destroy $w} + toplevel $w -class Dialog + message $w.m -width 400 -aspect 300 -text \ + "Unable to write file $loadfile" \ + -relief raised + label $w.bm -bitmap error + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "Xconfig Internal Error" + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + } +} + +proc read_config { filename } { + set file1 [open $filename r] + clear_choices + while { [gets $file1 line] >= 0} { + if [regexp {([0-9A-Za-z_]+)=([ynm])} $line foo var value] { + if { $value == "y" } then { set cmd "global $var; set $var 1" } + if { $value == "n" } then { set cmd "global $var; set $var 0" } + if { $value == "m" } then { set cmd "global $var; set $var 2" } + eval $cmd + } + if [regexp {# ([0-9A-Za-z_]+) is not set} $line foo var] { + set cmd "global $var; set $var 0" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)=([0-9A-Fa-f]+)} $line foo var value] { + set cmd "global $var; set $var $value" + eval $cmd + } + if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { + set cmd "global $var; set $var \"$value\"" + eval $cmd + } + } + close $file1 + update_choices + update_mainmenu .rdupd +} +proc write_comment { file1 file2 text } { + puts $file1 "" + puts $file1 "#" + puts $file1 "# $text" + puts $file1 "#" + puts $file2 "/*" + puts $file2 " * $text" + puts $file2 " */" +} + +proc write_tristate { file1 file2 varname variable dep } { + if { $variable == 0 } \ + then { puts $file1 "$varname=n"; } \ + elseif { $variable == 1 && $dep == 0 } \ + then { puts $file1 "$varname=y"; } \ + elseif { $variable == 1 && $dep == 1 } \ + then { puts $file1 "$varname=y"; \ + puts $file2 "#define $varname 1" } \ + else { \ + puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ + } +} + +#proc write_tristate { file1 file2 varname variable dep } { +# if { $variable == 0 } \ +# then { puts $file1 "# $varname is not set"; \ +# puts $file2 "#undef $varname"} \ +# elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \ +# then { puts $file1 "$varname=m"; \ +# puts $file2 "#undef $varname"; \ +# puts $file2 "#define ${varname}_MODULE 1" } \ +# elseif { $variable == 1 && $dep != 2 } \ +# then { puts $file1 "$varname=y"; \ +# puts $file2 "#define $varname 1" } \ +# else { \ +# puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ +# } +#} + +proc write_int { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname $variable"; \ + } +} + +proc write_hex { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=$variable"; \ + puts $file2 "#define $varname 0x$variable"; \ + } +} + +proc write_string { file1 file2 varname variable dep } { + if { $dep == 0 } \ + then { puts $file1 "# $varname is not set"; \ + puts $file2 "#undef $varname"} \ + else { + puts $file1 "$varname=\"$variable\""; \ + puts $file2 "#define $varname \"$variable\""; \ + } +} + +proc option_name {w mnum line text helpidx} { + button $w.x$line.l -text "$text" -relief groove -anchor w + $w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ + -activeback [cget $w.x$line.l -bg] + button $w.x$line.help -text "Help" -relief raised \ + -command "dohelp .dohelp $helpidx" + pack $w.x$line.help -side right -fill y + pack $w.x$line.l -side right -fill both -expand on +} + +proc toggle_switch2 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc toggle_switch3 {w mnum line text variable} { + frame $w.x$line -relief sunken + radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ + -relief groove -width 2 -command "update_menu$mnum .menu$mnum" + + option_name $w $mnum $line $text $variable + + global CONFIG_MODULES + if {($CONFIG_MODULES == 0)} then { + $w.x$line.m configure -state disabled + } + pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y +} + +proc bool {w mnum line text variable} { + toggle_switch2 $w $mnum $line $text $variable + $w.x$line.m configure -state disabled + pack $w.x$line -anchor w -fill both -expand on +} + +proc tristate {w mnum line text variable } { + toggle_switch3 $w $mnum $line $text $variable + pack $w.x$line -anchor w -fill both -expand on +} + +proc dep_tristate {w mnum line text variable depend } { + tristate $w $mnum $line $text $variable +} + +proc int { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc hex { w mnum line text variable } { + int $w $mnum $line $text $variable +} + +proc istring { w mnum line text variable } { + frame $w.x$line + entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ + -textvariable $variable + option_name $w $mnum $line $text $variable + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc minimenu { w mnum line text variable helpidx } { + frame $w.x$line + menubutton $w.x$line.x -textvariable $variable -menu \ + $w.x$line.x.menu -relief raised \ + -anchor w + option_name $w $mnum $line $text $helpidx + pack $w.x$line.x -anchor w -side right -fill y + pack $w.x$line -anchor w -fill both -expand on +} + +proc comment {w line text } { +#nothing done for comments now. +} + +proc dohelp {w var } { + catch {destroy $w} + toplevel $w -class Dialog + + set filefound 0 + set found 0 + set lineno 0 + + if { [file readable config.help] == 1} then { + set filefound 1 + # First escape sed regexp special characters in var: + set var [exec echo "$var" | sed s/\[\]\[\/.^$*\]/\\\\&/g] + # Now pick out right help text: + set message [exec sed -n " + /^$var\[ \]*\$/,\${ + /^$var\[ \]*\$/c\\ +${var}:\\ + + /^#/b + /^\[^ \]/q + s/^ // + p + } + " config.help] + set found [expr [string length "$message"] > 0] + } + + frame $w.f1 + + if { $found == 0 } then { + if { $filefound == 0 } then { + message $w.f1.m -width 750 -aspect 300 -relief flat -text \ + "No help available - unable to open file config.help. This file should have come with your kernel." + } else { + message $w.f1.m -width 400 -aspect 300 -relief flat -text \ + "No help available for $var" + } + label $w.f1.bm -bitmap error + wm title $w "RTFM" + } else { + text $w.f1.m -width 73 -relief flat -wrap word + $w.f1.m insert 0.0 $message + $w.f1.m conf -state disabled -height [$w.f1.m index end] + + label $w.f1.bm -bitmap info + wm title $w "Configuration help" + } + pack $w.f1.bm $w.f1.m -side left -padx 10 + pack $w.f1 -side top + set oldFocus [focus] + + # Do the OK button + # + frame $w.f2 + button $w.f2.ok -text "OK" \ + -width 10 -command "destroy $w; focus $oldFocus" + pack $w.f2.ok -side bottom -pady 6 -anchor n + pack $w.f2 -side bottom -padx 10 -anchor s + + # Finish off the window + # + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy +} + +proc wrapup {w } { + catch {destroy $w} + toplevel $w -class Dialog + + message $w.m -width 400 -aspect 300 -relief raised -justify center -text \ + "Check the top-level Makefile for additional configuration." + + label $w.bm -bitmap info + pack $w.bm $w.m -pady 10 -side top -padx 10 + wm title $w "End of L4/KA kernel configuration." + + set oldFocus [focus] + frame $w.f + button $w.f.back -text "OK" \ + -width 10 -command "exit" + pack $w.f.back -side bottom -pady 10 -anchor s + pack $w.f -pady 10 -side top -padx 10 -anchor s + focus $w + global winx; global winy + set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] + wm geometry $w +$winx+$winy + +} + +# +# Next set up the particulars for the top level menu, and define a few +# buttons which we will stick down at the bottom. +# + +frame .f0 +frame .f0.arch +frame .f0.apps +frame .f0.control + diff --git a/kernel/xconfig/kernel.in b/kernel/xconfig/kernel.in new file mode 100644 index 0000000..f289aa2 --- /dev/null +++ b/kernel/xconfig/kernel.in @@ -0,0 +1,129 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University +## +## File path: xconfig/kernel.in +## Description: Variuos kernel configurations. +## +## @LICENSE@ +## +## $Id: kernel.in,v 1.53 2002/08/15 14:20:43 haeber Exp $ +## +###################################################################### + +mainmenu_option next_comment +comment 'Kernel Configuration' + +bool 'Jochen-bug compatibility mode' CONFIG_JOCHEN_BUGS n +bool 'specify sigma0 entry point' CONFIG_SIGMA0_ENTRY n +if [ "$CONFIG_SIGMA0_ENTRY" = "y" ] +hex ' sigma0 entry IP' CONFIG_SIGMA0_IP 0C000000 +hex ' sigma0 entry SP' CONFIG_SIGMA0_SP 00000000 +fi + +bool 'specify root task entry point' CONFIG_ROOTTASK_ENTRY n +if [ "$CONFIG_ROOTTASK_ENTRY" = "y" ] +hex ' root task entry IP' CONFIG_ROOTTASK_IP 0C100000 +hex ' root task entry SP' CONFIG_ROOTTASK_SP 00000000 +fi + +if [ "$CONFIG_ARCH_ARM" = "y" ]; then + bool 'arm - Architecture specific kmemory' CONFIG_HAVE_ARCH_KMEM n +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + + # XXX: Need to test SMP with i585 and Pentium 4 + if [ "$CONFIG_ARCH_X86_I686" = "y" ]; then + bool 'SMP' CONFIG_SMP n + fi + + if [ "$CONFIG_SMP" = "y" ]; then + int ' number of processors' CONFIG_SMP_MAX_CPU 2 + bool ' Marcus XP IPC' CONFIG_MARCUS_XP_IPC n + define_bool CONFIG_X86_APICTIMER y + define_bool CONFIG_X86_IOAPIC y + define_bool CONFIG_X86_INKERNEL_PIC n + else + # XXX: Need to test IO-APIC with i585 and Pentium 4 + if [ "$CONFIG_ARCH_X86_I686" = "y" ]; then + bool 'x86 - Use IO-APIC' CONFIG_X86_IOAPIC n + fi + if [ "$CONFIG_X86_IOAPIC" = "y" -o "$CONFIG_ENABLE_PROFILING" = "y" ]; then + define_bool CONFIG_X86_APICTIMER y + else + bool 'x86 - Use APIC timer' CONFIG_X86_APICTIMER n + fi + if [ "$CONFIG_X86_IOAPIC" != "y" ]; then + bool 'x86 - In-kernel PIC handling' CONFIG_X86_INKERNEL_PIC n + else + define_bool CONFIG_X86_INKERNEL_PIC n + fi + fi + + # XXX: Need to implement performance counters for i585 + if [ "$CONFIG_ARCH_X86_I686" = "y" -o "$CONFIG_ARCH_X86_P4" = "y" ]; then + bool 'x86 - performance monitoring' CONFIG_PERFMON n + fi + + bool 'x86 - enable WBINVD emulation' CONFIG_X86_WBINVD_EMULATION n + + if [ "$CONFIG_ARCH_X86_P4" = "y" -a "$CONFIG_SMP" != "y" ]; then + bool 'x86 - Branch Target Store' CONFIG_X86_P4_BTS n + if [ "$CONFIG_X86_P4_BTS" = "y" ]; then + int ' BTS buffer size (KB)' CONFIG_X86_P4_BTS_BUFSIZE 4 + fi + bool 'x86 - Precise Event-Based Sampling' CONFIG_X86_P4_PEBS n + if [ "$CONFIG_X86_P4_PEBS" = "y" ]; then + int ' PEBS buffer size (KB)' CONFIG_X86_P4_PEBS_BUFSIZE 64 + fi + fi + + # XXX: Need to implement profiling for Pentium 4 + if [ "$CONFIG_ARCH_X86_I686" = "y" ]; then + bool 'x86 - Enable profiling' CONFIG_ENABLE_PROFILING n + if [ "$CONFIG_ENABLE_PROFILING" = "y" ]; then + bool ' do profiling with NMI' CONFIG_PROFILING_WITH_NMI y + int ' max profile sample values' CONFIG_PROFILING_MAX_VAL 2 + fi + fi + + if [ "$CONFIG_X86_APICTIMER" = "y" -o "$CONFIG_X86_IOAPIC" = "y" -o \ + "$CONFIG_ENABLE_PROFILING" = "y" -o "$CONFIG_X86_P4_PEBS" = "y" ]; then + define_bool CONFIG_X86_APIC y + fi +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + bool 'Enable IPC FastPath' CONFIG_IPC_FASTPATH n + bool 'Enable small address spaces' CONFIG_ENABLE_SMALL_AS n + if [ "$CONFIG_ENABLE_SMALL_AS" = "y" ]; then + bool 'Small spaces in global pages' CONFIG_GLOBAL_SMALL_SPACES n + fi + if [ "$CONFIG_ENABLE_SMALL_AS" = "y" ]; then + choice 'Small space area size' \ + "512MB CONFIG_SMALL_AREA_512MB \ + 1GB CONFIG_SMALL_AREA_1GB \ + 2GB CONFIG_SMALL_AREA_2GB" 512MB + fi +fi +if [ "$CONFIG_ARCH_X86" = "y" -a "$CONFIG_ENABLE_SMALL_AS" = "n" \ + -a "$CONFIG_IPC_FASTPATH" = "n" ]; then + bool 'Enable IO-Flexpages' CONFIG_IO_FLEXPAGES n +fi + +if [ "$CONFIG_IO_FLEXPAGES" = "y" ]; then + bool 'Implicit IO-mapping' CONFIG_AUTO_IO_MAP n +fi + +if [ "$CONFIG_IO_FLEXPAGES" = "y" -a "$CONFIG_USERMODE_NOIRQ" = "n" \ + -a "$CONFIG_X86_APICTIMER" = "n" -a "$CONFIG_X86_IOAPIC" = "n"]; then + + bool 'Enable Virtual Interrupts' CONFIG_ENABLE_PVI n +fi + +bool 'Enable cacheability fpage bits' CONFIG_CACHEABILITY_BITS n + +endmenu + + diff --git a/kernel/xconfig/tail.tk b/kernel/xconfig/tail.tk new file mode 100644 index 0000000..90f6554 --- /dev/null +++ b/kernel/xconfig/tail.tk @@ -0,0 +1,69 @@ +# FILE: tail.tk +# This file is boilerplate TCL/TK function definitions for 'make xconfig'. +# +# CHANGES +# ======= +# +# 8 January 1998, Michael Elizabeth Chastain, +# Arrange buttons in three columns for better screen fitting. +# + +# +# Read the user's settings from .config. These will override whatever is +# in config.in. Don't do this if the user specified a -D to force +# the defaults. +# +if { [file readable .config] == 1} then { + if { $argc > 0 } then { + if { [lindex $argv 0] != "-D" } then { + read_config .config + } + else + { + read_config $defaults + } + } else { + read_config .config + } +} else { + read_config $defaults +} + +update_mainmenu .f0 + +button .f0.control.save -anchor w -text "Save and Exit" \ + -command { writeconfig .config ../include/config.h; read_config .config; \ + writeconfig .config ../include/config.h; exit; wrapup .wrap } + +button .f0.control.quit -anchor w -text "Quit Without Saving" \ + -command { maybe_exit .maybe } + +button .f0.control.load -anchor w -text "Load Configuration from File" \ + -command { load_configfile .load "Load Configuration from file" read_config_file +} + +button .f0.control.store -anchor w -text "Store Configuration to File" \ + -command { load_configfile .load "Store Configuration to file" write_config_file } + +# +# Now pack everything. +# + +pack .f0.control.store .f0.control.load .f0.control.quit .f0.control.save \ + -padx 0 -pady 0 -side bottom -fill x +pack .f0.arch .f0.apps .f0.control -side left -padx 5 -pady 0 -fill y +pack .f0 -padx 5 -pady 5 + +# +# If we cannot write our config files, disable the write button. +# +if { [file exists .config] == 1 } then { + if { [file writable .config] == 0 } then { + .f0.control.save configure -state disabled + } + } else { + if { [file writable .] == 0 } then { + .f0.control.save configure -state disabled + } + } + diff --git a/kernel/xconfig/tkcond.c b/kernel/xconfig/tkcond.c new file mode 100644 index 0000000..89069da --- /dev/null +++ b/kernel/xconfig/tkcond.c @@ -0,0 +1,360 @@ +/* + * tkcond.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * This file takes the tokenized statement list and transforms 'if ...' + * statements. For each simple statement, I find all of the 'if' statements + * that enclose it, and attach the aggregate conditionals of those 'if' + * statements to the cond list of the simple statement. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact if + * you are interested in working on the replacement. + */ + +#include +#include +#include + +#include "tkparse.h" + + + +/* + * Transform op_variable to op_kvariable. + * + * This works, but it's gross, speed-wise. It would benefit greatly + * from a simple hash table that maps names to cfg. + * + * Note well: this is actually better than the loop structure xconfig + * has been staggering along with for three years, which performs + * this whole procedure inside *another* loop on active conditionals. + */ +void transform_to_kvariable( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + struct condition * cond; + + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + if ( cond->op == op_variable ) + { + /* Here's where it gets DISGUSTING. */ + struct kconfig * cfg1; + + for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next ) + { + if ( cfg1->token == token_bool + || cfg1->token == token_choice_item + || cfg1->token == token_dep_tristate + || cfg1->token == token_hex + || cfg1->token == token_int + || cfg1->token == token_string + || cfg1->token == token_tristate ) + { + if ( strcmp( cond->str, cfg1->optionname ) == 0 ) + { + cond->op = op_kvariable; + cond->str = NULL; + cond->cfg = cfg1; + break; + } + } + } + } + +#if 0 + /* + * Maybe someday this will be useful, but right now it + * gives a lot of false positives on files like + * drivers/video/Config.in that are meant for more + * than one architecture. Turn it on if you want to play + * with it though; it does work. -- mec + */ + if ( cond->op == op_variable ) + { + if ( strcmp( cond->str, "ARCH" ) != 0 + && strcmp( cond->str, "CONSTANT_Y" ) != 0 + && strcmp( cond->str, "CONSTANT_M" ) != 0 + && strcmp( cond->str, "CONSTANT_N" ) != 0 ) + { + fprintf( stderr, "warning: $%s used but not defined\n", + cond->str ); + } + } +#endif + } + } +} + + + +/* + * Make a new condition chain by joining the current condition stack with + * the "&&" operator for glue. + */ +struct condition * join_condition_stack( struct condition * conditions [], + int depth ) +{ + struct condition * cond_list; + struct condition * cond_last; + int i; + + cond_list = cond_last = NULL; + for ( i = 0; i < depth; i++ ) + { + struct condition * cond; + struct condition * cnew; + + /* add a '(' */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_lparen; + if ( cond_last == NULL ) + { cond_list = cond_last = cnew; } + else + { cond_last->next = cnew; cond_last = cnew; } + + /* duplicate the chain */ + for ( cond = conditions [i]; cond != NULL; cond = cond->next ) + { + cnew = malloc( sizeof(*cnew) ); + cnew->next = NULL; + cnew->op = cond->op; + cnew->str = cond->str ? strdup( cond->str ) : NULL; + cnew->cfg = cond->cfg; + cond_last->next = cnew; + cond_last = cnew; + } + + /* add a ')' */ + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_rparen; + cond_last->next = cnew; + cond_last = cnew; + + /* if i have another condition, add an '&&' operator */ + if ( i < depth - 1 ) + { + cnew = malloc( sizeof(*cnew) ); + memset( cnew, 0, sizeof(*cnew) ); + cnew->op = op_and; + cond_last->next = cnew; + cond_last = cnew; + } + } + + /* + * Remove duplicate conditions. + */ + { + struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f; + + for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next ) + { + if ( cond1->op == op_lparen ) + { + cond1b = cond1 ->next; if ( cond1b == NULL ) break; + cond1c = cond1b->next; if ( cond1c == NULL ) break; + cond1d = cond1c->next; if ( cond1d == NULL ) break; + cond1e = cond1d->next; if ( cond1e == NULL ) break; + cond1f = cond1e->next; if ( cond1f == NULL ) break; + + if ( cond1b->op == op_kvariable + && ( cond1c->op == op_eq || cond1c->op == op_neq ) + && cond1d->op == op_constant + && cond1e->op == op_rparen ) + { + struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f; + + for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next ) + { + if ( cond2->op == op_lparen ) + { + cond2b = cond2 ->next; if ( cond2b == NULL ) break; + cond2c = cond2b->next; if ( cond2c == NULL ) break; + cond2d = cond2c->next; if ( cond2d == NULL ) break; + cond2e = cond2d->next; if ( cond2e == NULL ) break; + cond2f = cond2e->next; + + /* look for match */ + if ( cond2b->op == op_kvariable + && cond2b->cfg == cond1b->cfg + && cond2c->op == cond1c->op + && cond2d->op == op_constant + && strcmp( cond2d->str, cond1d->str ) == 0 + && cond2e->op == op_rparen ) + { + /* one of these must be followed by && */ + if ( cond1f->op == op_and + || ( cond2f != NULL && cond2f->op == op_and ) ) + { + /* nuke the first duplicate */ + cond1 ->op = op_nuked; + cond1b->op = op_nuked; + cond1c->op = op_nuked; + cond1d->op = op_nuked; + cond1e->op = op_nuked; + if ( cond1f->op == op_and ) + cond1f->op = op_nuked; + else + cond2f->op = op_nuked; + } + } + } + } + } + } + } + } + + return cond_list; +} + + + +/* + * This is the main transformation function. + */ +void fix_conditionals( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + /* + * Transform op_variable to op_kvariable. + */ + transform_to_kvariable( scfg ); + + /* + * Transform conditions that use variables from "choice" statements. + * Choice values appear to the user as a collection of booleans, and the + * script can test the individual booleans. But internally, all I have is + * the N-way value of an unnamed temporary for the whole statement. So I + * have to tranform '"$CONFIG_M386" != "y"' + * into '"$tmpvar_N" != "CONFIG_M386"'. + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + struct condition * cond; + + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + if ( cond->op == op_kvariable && cond->cfg->token == token_choice_item ) + { + /* + * Look two more tokens down for the comparison token. + * It has to be "y" for this trick to work. + * + * If you get this error, don't even think about relaxing the + * strcmp test. You will produce incorrect TK code. Instead, + * look for the place in your Config.in script where you are + * comparing a 'choice' variable to a value other than 'y', + * and rewrite the comparison to be '= "y"' or '!= "y"'. + */ + struct condition * cond2 = cond->next->next; + const char * label; + + if ( strcmp( cond2->str, "y" ) != 0 ) + { + fprintf( stderr, "tkparse choked in fix_choice_cond\n" ); + exit( 1 ); + } + + label = cond->cfg->label; + cond->cfg = cond->cfg->cfg_parent; + cond2->str = strdup( label ); + } + } + } + + /* + * Walk the statement list, maintaining a stack of current conditions. + * token_if push its condition onto the stack. + * token_else invert the condition on the top of the stack. + * token_endif pop the stack. + * + * For a simple statement, create a condition chain by joining together + * all of the conditions on the stack. + */ + { + struct condition * cond_stack [32]; + int depth = 0; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_if: + cond_stack [depth++] = cfg->cond; + cfg->cond = NULL; + break; + + case token_else: + { + /* + * Invert the condition chain. + * + * Be careful to transfrom op_or to op_and1, not op_and. + * I will need this later in the code that removes + * duplicate conditions. + */ + struct condition * cond; + + for ( cond = cond_stack [depth-1]; + cond != NULL; + cond = cond->next ) + { + switch( cond->op ) + { + default: break; + case op_and: cond->op = op_or; break; + case op_or: cond->op = op_and1; break; + case op_neq: cond->op = op_eq; break; + case op_eq: cond->op = op_neq; break; + } + } + } + break; + + case token_fi: + --depth; + break; + + case token_bool: + case token_choice_item: + case token_comment: + case token_define_bool: + case token_hex: + case token_int: + case token_mainmenu_option: + case token_string: + case token_tristate: + cfg->cond = join_condition_stack( cond_stack, depth ); + break; + + case token_dep_tristate: + /* + * Same as the other simple statements, plus an additional + * condition for the dependency. + */ + cond_stack [depth] = cfg->cond; + cfg->cond = join_condition_stack( cond_stack, depth+1 ); + break; + } + } + } +} diff --git a/kernel/xconfig/tkgen.c b/kernel/xconfig/tkgen.c new file mode 100644 index 0000000..d31ca16 --- /dev/null +++ b/kernel/xconfig/tkgen.c @@ -0,0 +1,1067 @@ +/* Generate tk script based upon config.in + * + * Version 1.0 + * Eric Youngdale + * 10/95 + * + * 1996 01 04 + * Avery Pennarun - Aesthetic improvements. + * + * 1996 01 24 + * Avery Pennarun - Bugfixes and more aesthetics. + * + * 1996 03 08 + * Avery Pennarun - The int and hex config.in commands work right. + * - Choice buttons are more user-friendly. + * - Disabling a text entry line greys it out properly. + * - dep_tristate now works like in Configure. (not pretty) + * - No warnings in gcc -Wall. (Fixed some "interesting" bugs.) + * - Faster/prettier "Help" lookups. + * + * 1996 03 15 + * Avery Pennarun - Added new sed script from Axel Boldt to make help even + * faster. (Actually awk is downright slow on some machines.) + * - Fixed a bug I introduced into Choice dependencies. Thanks + * to Robert Krawitz for pointing this out. + * + * 1996 03 16 + * Avery Pennarun - basic "do_make" support added to let sound config work. + * + * 1996 03 25 + * Axel Boldt - Help now works on "choice" buttons. + * + * 1996 04 06 + * Avery Pennarun - Improved sound config stuff. (I think it actually works + * now!) + * - Window-resize-limits don't use ugly /usr/lib/tk4.0 hack. + * - int/hex work with tk3 again. (The "cget" error.) + * - Next/Prev buttons switch between menus. I can't take + * much credit for this; the code was already there, but + * ifdef'd out for some reason. It flickers a lot, but + * I suspect there's no "easy" fix for that. + * - Labels no longer highlight as you move the mouse over + * them (although you can still press them... oh well.) + * - Got rid of the last of the literal color settings, to + * help out people with mono X-Windows systems. + * (Apparently there still are some out there!) + * - Tabstops seem sensible now. + * + * 1996 04 14 + * Avery Pennarun - Reduced flicker when creating windows, even with "update + * idletasks" hack. + * + * 1997 12 08 + * Michael Chastain - Remove sound driver special cases. + * + * 1997 11 15 + * Michael Chastain - For choice buttons, write values for all options, + * not just the single chosen one. This is compatible + * with 'make config' and 'make oldconfig', and is + * needed so smart-config dependencies work if the + * user switches from one configuration method to + * another. + * + * 1998 03 09 + * Axel Boldt - Smaller layout of main menu - it's still too big for 800x600. + * - Display help in text window to allow for cut and paste. + * - Allow for empty lines in help texts. + * - update_define should not set all variables unconditionally to + * 0: they may have been set to 1 elsewhere. CONFIG_NETLINK is + * an example. + * + * 1999 01 04 + * Michael Elizabeth Chastain + * - Call clear_globalflags when writing out update_mainmenu. + * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4. + * + * 8 January 1999, Michael Elizabeth Chastain + * - Emit menus_per_column + * + * 14 January 1999, Michael Elizabeth Chastain + * - Steam-clean this file. I tested this by generating kconfig.tk for every + * architecture and comparing it character-for-character against the output + * of the old tkparse. + * - Fix flattening of nested menus. The old code simply assigned items to + * the most recent token_mainmenu_option, without paying attention to scope. + * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu". + * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c + * and bool-d in *menu-2*. This hosed the nested submenus in + * drives/net/Config.in and other places. + * - Fix menu line wraparound at 128 menus (some fool used a 'char' for + * a counter). + * + * 23 January 1999, Michael Elizabeth Chastain + * - Remove bug-compatible code. + */ + +#include +#include +#include "tkparse.h" + + + +/* + * Total number of menus. + */ +static int tot_menu_num = 0; + + + +/* + * Generate portion of wish script for the beginning of a submenu. + * The guts get filled in with the various options. + */ +static void start_proc( char * label, int menu_num, int flag ) +{ + if ( flag ) + printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label ); + printf( "proc menu%d {w title} {\n", menu_num ); + printf( "\tcatch {destroy $w}\n" ); + printf( "\ttoplevel $w -class Dialog\n" ); + printf( "\twm withdraw $w\n" ); + printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" ); + printf( "\t\t\"%s\" -relief raised\n", label ); + printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); + printf( "\twm title $w \"%s\" \n\n", label ); + + /* + * Attach the "Prev", "Next" and "OK" buttons at the end of the window. + */ + printf( "\tset oldFocus [focus]\n" ); + printf( "\tframe $w.f\n" ); + printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); + printf( "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n" ); + printf( "\tbutton $w.f.next -text \"Next\" \\\n" ); + printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 ); + if ( menu_num == tot_menu_num ) + printf( "\t$w.f.next configure -state disabled\n" ); + printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" ); + printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1 ); + if ( menu_num == 1 ) + printf( "\t$w.f.prev configure -state disabled\n" ); + printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); + printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" ); + + /* + * Lines between canvas and other areas of the window. + */ + printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.topline -side top -fill x\n\n" ); + printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" ); + printf( "\tpack $w.botline -side bottom -fill x\n\n" ); + + /* + * The "config" frame contains the canvas and a scrollbar. + */ + printf( "\tframe $w.config\n" ); + printf( "\tpack $w.config -fill y -expand on\n\n" ); + printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" ); + printf( "\tpack $w.config.vscroll -side right -fill y\n\n" ); + + /* + * The scrollable canvas itself, where the real work (and mess) gets done. + */ + printf( "\tcanvas $w.config.canvas -height 1\\\n" ); + printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" ); + printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" ); + printf( "\tframe $w.config.f\n" ); + printf( "\tpack $w.config.canvas -side right -fill y\n" ); + printf("\n\n"); +} + + + +/* + * Each proc we create needs a global declaration for any global variables we + * use. To minimize the size of the file, we set a flag each time we output + * a global declaration so we know whether we need to insert one for a + * given function or not. + */ +void clear_globalflags( struct kconfig * scfg ) +{ + struct kconfig * cfg; + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + cfg->global_written = 0; +} + + + +/* + * Output a "global" line for a given variable. Also include the + * call to "vfix". (If vfix is not needed, then it's fine to just printf + * a "global" line). + */ +void global( const char *var ) +{ + printf( "\tglobal %s; vfix %s\n", var, var ); +} + + + +/* + * This function walks the chain of conditions that we got from cond.c + * and creates a TCL conditional to enable/disable a given widget. + */ +void generate_if( struct kconfig * cfg, struct condition * ocond, + int menu_num, int line_num ) +{ + struct condition * cond; + + /* + * First write any global declarations we need for this conditional. + */ + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_variable: + global( cond->str ); + break; + + case op_kvariable: + if ( ! cond->cfg->global_written ) + { + cond->cfg->global_written = 1; + global( cond->cfg->optionname ); + } + break; + } + } + + /* + * Now write this option. + */ + if ( ! cfg->global_written && cfg->optionname != NULL ) + { + cfg->global_written = 1; + global( cfg->optionname ); + } + + /* + * Generate the body of the conditional. + */ + printf( "\tif {" ); + for ( cond = ocond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: + break; + + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", cond->str ); + break; + + case op_kvariable: + printf( "$%s", cond->cfg->optionname ); + break; + + case op_constant: + if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then { " ); + + /* + * Generate a procedure call to write the value. + * This code depends on procedures in header.tk. + */ + switch ( cfg->token ) + { + default: + printf( " }\n" ); + break; + + case token_bool: + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state normal;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal;", + menu_num, line_num ); + printf( "set %s [expr $%s&15];", + cfg->optionname, cfg->optionname ); + printf( "} else { "); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;", + menu_num, line_num ); + printf( "set %s [expr $%s|16];}\n", + cfg->optionname, cfg->optionname ); + break; + + case token_choice_header: + fprintf( stderr, "Internal error on token_choice_header\n" ); + exit( 1 ); + + case token_choice_item: + printf(".menu%d.config.f.x%d.x configure -state normal} else { .menu%d.config.f.x%d.x configure -state disabled}\n", + menu_num, cfg->cfg_parent->menu_line, + menu_num, cfg->cfg_parent->menu_line ); + break; + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_define_bool: + printf( "set %s %s } \n", + cfg->optionname, cfg->value ); + break; + + case token_dep_tristate: + case token_tristate: + if ( cfg->token == token_dep_tristate ) + { + global( cfg->depend ); + printf( "if { $%s != 1 && $%s != 0 } then {", + cfg->depend, cfg->depend ); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( "} else {" ); + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num); + printf( "}; " ); + } + else + { + printf( ".menu%d.config.f.x%d.y configure -state normal;", + menu_num, line_num ); + } + + printf( ".menu%d.config.f.x%d.n configure -state normal;", + menu_num, line_num ); + printf( "global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state normal;", + menu_num, line_num ); + + /* + * Or in a bit to the variable - this causes all of the radiobuttons + * to be deselected (i.e. not be red). + */ + printf( "set %s [expr $%s&15];", + cfg->optionname, cfg->optionname ); + printf( "} else { " ); + printf( ".menu%d.config.f.x%d.y configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.n configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.m configure -state disabled;", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;", + menu_num, line_num ); + + /* + * Clear the disable bit to enable the correct radiobutton. + */ + printf( "set %s [expr $%s|16];}\n", + cfg->optionname, cfg->optionname ); + break; + + case token_hex: + case token_int: + case token_string: + printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", + menu_num, line_num); + printf( ".menu%d.config.f.x%d.l configure -state normal; ", + menu_num, line_num); + printf( "} else { " ); + printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ];", + menu_num, line_num ); + printf( ".menu%d.config.f.x%d.l configure -state disabled;}\n", + menu_num, line_num ); + break; + + case token_mainmenu_option: + printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", + menu_num, menu_num ); + break; + } +} + + + +/* + * Generate a line that writes a variable to the output file. + */ +void generate_writeconfig( struct kconfig * cfg ) +{ + struct condition * cond; + + /* + * Generate global declaration for this symbol. + */ + if ( cfg->token != token_comment ) + { + if ( ! cfg->global_written ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + } + } + + /* + * Generate global declarations for the condition chain. + */ + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch( cond->op ) + { + default: + break; + + case op_variable: + global( cond->str ); + break; + + case op_kvariable: + if ( ! cond->cfg->global_written ) + { + cond->cfg->global_written = 1; + global( cond->cfg->optionname ); + } + break; + } + } + + /* + * Generate indentation. + */ + if ( cfg->token != token_choice_header ) + printf( "\t" ); + + /* + * Generate the conditional. + */ + if ( cfg->cond != NULL ) + { + printf( "if {" ); + for ( cond = cfg->cond; cond != NULL; cond = cond->next ) + { + switch ( cond->op ) + { + default: break; + case op_bang: printf( " ! " ); break; + case op_eq: printf( " == " ); break; + case op_neq: printf( " != " ); break; + case op_and: printf( " && " ); break; + case op_and1: printf( " && " ); break; + case op_or: printf( " || " ); break; + case op_lparen: printf( "(" ); break; + case op_rparen: printf( ")" ); break; + + case op_variable: + printf( "$%s", cond->str ); + break; + + case op_kvariable: + printf( "$%s", cond->cfg->optionname ); + break; + + case op_constant: + if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); + else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); + else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); + else + printf( "\"%s\"", cond->str ); + break; + } + } + printf( "} then {" ); + } + + /* + * Generate a procedure call to write the value. + * This code depends on the write_* procedures in header.tk. + */ + switch ( cfg->token ) + { + default: + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_bool: + case token_tristate: + if ( cfg->cond ) + printf( " " ); + printf( "write_tristate $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_choice_header: + /* + * This is funky code -- it fails if there were any conditionals. + * Fortunately all the conditionals got stripped off somewhere + * else. + */ + { + struct kconfig * cfg1; + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + if (cfg->depend) + printf("\tglobal %s\n\tif { $%s == \"%s\"} then { write_tristate $cfg $autocfg %s 1 $%s } else { write_tristate $cfg $autocfg %s 0 $%s }\n", + cfg->depend, cfg->optionname, cfg1->label, + cfg1->optionname, cfg->depend, + cfg1->optionname, cfg->depend ); + else + printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n", + cfg->optionname, cfg1->label, + cfg1->optionname, + cfg1->optionname ); + + } + } + break; + + case token_choice_item: + fprintf( stderr, "Internal error on token_choice_item\n" ); + exit( 1 ); + + case token_comment: + printf( "write_comment $cfg $autocfg \"%s\"", + cfg->label ); + if ( cfg->cond != NULL ) + printf( "}" ); + printf( "\n" ); + break; + + case token_define_bool: + if (cfg->optionname[0] != '_') + { + if ( cfg->cond == NULL ) + { + printf( "write_tristate $cfg $autocfg %s $%s $notmod\n", + cfg->optionname, cfg->optionname ); + } + else + { + printf( "write_tristate $cfg $autocfg %s %s $notmod }\n", + cfg->optionname, cfg->value ); + } + } + else + printf( " set %s %s }\n", cfg->optionname, cfg->value); + break; + + case token_dep_tristate: + if ( cfg->cond ) + printf( " " ); + printf( "write_tristate $cfg $autocfg %s $%s $%s", + cfg->optionname, cfg->optionname, cfg->depend ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( " \n" ); + break; + + case token_hex: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_hex $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_int: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_int $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + + case token_string: + if ( cfg->cond != NULL ) + printf( " " ); + printf( "write_string $cfg $autocfg %s $%s $notmod", + cfg->optionname, cfg->optionname ); + if ( cfg->cond != NULL ) + printf( " }" ); + printf( "\n" ); + break; + } +} + + + +/* + * Generates the end of a menu procedure. + */ +static void end_proc( struct kconfig * scfg, int menu_num ) +{ + struct kconfig * cfg; + + printf( "\n\n\n" ); + printf( "\tfocus $w\n" ); + printf( "\tupdate_menu%d $w.config.f\n", + menu_num ); + printf( "\tglobal winx; global winy\n" ); + printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); + printf( "\twm geometry $w +$winx+$winy\n" ); + + /* + * Now that the whole window is in place, we need to wait for an "update" + * so we can tell the canvas what its virtual size should be. + * + * Unfortunately, this causes some ugly screen-flashing because the whole + * window is drawn, and then it is immediately resized. It seems + * unavoidable, though, since "frame" objects won't tell us their size + * until after an update, and "canvas" objects can't automatically pack + * around frames. Sigh. + */ + printf( "\tupdate idletasks\n" ); + printf( "\t$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" ); + printf( "\t$w.config.canvas configure \\\n" ); + printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" ); + printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" ); + printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" ); + + /* + * If the whole canvas will fit in 3/4 of the screen height, do it; + * otherwise, resize to around 1/2 the screen and let us scroll. + */ + printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" ); + printf( "\tset scry [expr [winfo screenh $w] / 2]\n" ); + printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" ); + printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" ); + printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" ); + printf( "\t\t$w.config.canvas configure -height $canvtotal\n" ); + printf( "\t} else {\n" ); + printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" ); + printf( "\t}\n" ); + + /* + * Limit the min/max window size. Height can vary, but not width, + * because of the limitations of canvas and our laziness. + */ + printf( "\tupdate idletasks\n" ); + printf( "\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" ); + printf( "\twm minsize $w [winfo width $w] 100\n\n" ); + printf( "\twm deiconify $w\n" ); + printf( "}\n\n\n" ); + + /* + * Now we generate the companion procedure for the menu we just + * generated. This procedure contains all of the code to + * disable/enable widgets based upon the settings of the other + * widgets, and will be called first when the window is mapped, + * and each time one of the buttons in the window are clicked. + */ + printf( "proc update_menu%d {w} {\n", menu_num ); + printf( "\tupdate_define\n" ); + + /* + * Clear all of the booleans that are defined in this menu. + */ + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num && cfg->token == token_define_bool + && cfg->optionname != NULL ) + { + if ( ! cfg->global_written ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tset %s 0\n", cfg->optionname ); + } + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->menu_number == menu_num + && cfg->token != token_mainmenu_option +/* && cfg->token != token_choice_item*/) + { + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + else + { + /* + * Treat tristate like conditional here. + */ + if ( cfg->token == token_dep_tristate ) + { + global( cfg->depend ); + printf( "\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n", + cfg->depend, cfg->depend, + menu_num, cfg->menu_line, + menu_num, cfg->menu_line ); + } + } + } + } + + printf("\n\tupdate_mainmenu $w\n"); + printf("}\n\n\n"); +} + + + +/* + * This is the top level function for generating the tk script. + */ +void dump_tk_script( struct kconfig * scfg ) +{ + int menu_depth; + int menu_num [64]; + struct kconfig * menu_first [256]; + struct kconfig * menu_last [256]; + int imenu; + struct kconfig * cfg; + struct kconfig * cfg1 = NULL; + const char * name = "No Name"; + + /* + * Thread the menu pointers so I can walk each menu separately. + */ + tot_menu_num = 0; + menu_depth = 0; + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_mainmenu_name: + name = cfg->label; + break; + + case token_mainmenu_option: + if ( ++menu_depth >= 64 ) + { fprintf( stderr, "menus too deep\n" ); exit( 1 ); } + if ( ++tot_menu_num >= 256 ) + { fprintf( stderr, "too many menus\n" ); exit( 1 ); } + menu_num [menu_depth] = tot_menu_num; + menu_first [tot_menu_num] = cfg; + menu_last [tot_menu_num] = cfg; + break; + + case token_endmenu: + /* flatten menus with proper scoping */ + if ( --menu_depth < 0 ) + { fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); } + break; + + case token_bool: + case token_choice_header: + case token_choice_item: + case token_dep_tristate: + case token_hex: + case token_int: + case token_string: + case token_tristate: + if ( menu_depth == 0 ) + { fprintf( stderr, "statement not in menu\n" ); exit( 1 ); } + menu_last [menu_num [menu_depth]]->menu_next = cfg; + menu_last [menu_num [menu_depth]] = cfg; + cfg->menu_next = NULL; + break; + + case token_define_bool: + break; + } + } + + /* + * Generate menus per column setting. + * There are: + * four extra buttons for save/quit/load/store; + * one blank button + * add two to round up for division + */ + printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 ); + + /* + * Generate the menus. + */ + printf( "mainmenu_name \"%s\"\n", name ); + for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) + { + int menu_line = 0; + + clear_globalflags( scfg ); + start_proc( menu_first[imenu]->label, imenu, 1 ); + + for ( cfg = menu_first[imenu]; cfg != NULL; cfg = cfg->menu_next ) + { + cfg->menu_number = imenu; + + switch ( cfg->token ) + { + default: + break; + + case token_bool: + cfg->menu_line = menu_line++; + printf( "\tbool $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_choice_header: + /* + * I need the first token_choice_item to pick out the right + * help text from Documentation/Configure.help. + */ + cfg->menu_line = menu_line++; + printf( "\tglobal %s\n", cfg->optionname ); + printf( "\tminimenu $w.config.f %d %d \"%s\" %s %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname, cfg->next->optionname ); + printf( "\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line ); + cfg1 = cfg; + break; + + case token_choice_item: + /* note: no menu line; uses choice header menu line */ + printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n", + cfg1->menu_line, cfg->label, cfg1->optionname, + cfg->label, cfg1->menu_number, cfg1->menu_number ); + break; + + case token_dep_tristate: + cfg->menu_line = menu_line++; + printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname, cfg->depend ); + break; + + case token_hex: + cfg->menu_line = menu_line++; + printf( "\thex $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_int: + cfg->menu_line = menu_line++; + printf( "\tint $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_string: + cfg->menu_line = menu_line++; + printf( "\tistring $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + + case token_tristate: + cfg->menu_line = menu_line++; + printf( "\ttristate $w.config.f %d %d \"%s\" %s\n", + cfg->menu_number, cfg->menu_line, cfg->label, + cfg->optionname ); + break; + } + } + + end_proc( scfg, imenu ); + } + + /* + * The top level menu also needs an update function. When we exit a + * submenu, we may need to disable one or more of the submenus on + * the top level menu, and this procedure will ensure that things are + * correct. + */ + clear_globalflags( scfg ); + printf( "proc update_mainmenu {w} {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_mainmenu_option && cfg->cond != NULL ) + generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); + } + printf( "}\n\n\n" ); + +#if 0 + /* + * Generate code to set the variables that are "defined". + */ + for ( cfg = config; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_define_bool ) + { + if ( cfg->cond != NULL ) + generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); + else + printf( "\twrite_define %s %s\n", cfg->optionname, cfg->value ); + } + } + #endif + + /* + * Generate code to load the default settings into the variables. + * The script in tail.tk will attempt to load .config, + * which may override these settings, but that's OK. + */ + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_item: + case token_dep_tristate: + case token_tristate: + printf( "set %s 0\n", cfg->optionname ); + break; + + case token_choice_header: + printf( "set %s \"(not set)\"\n", cfg->optionname ); + break; + + case token_hex: + case token_int: + printf( "set %s %s\n", cfg->optionname, cfg->value ? cfg->value : "0"); + break; + + case token_string: + printf( "set %s \"%s\"\n", cfg->optionname, cfg->value ? cfg->value : ""); + break; + } + } + + /* + * Generate a function to write all of the variables to a file. + */ + printf( "proc writeconfig {file1 file2} {\n" ); + printf( "\tset cfg [open $file1 w]\n" ); + printf( "\tset autocfg [open $file2 w]\n" ); + printf( "\tset notmod 1\n" ); + printf( "\tset notset 0\n" ); + printf( "\tputs $cfg \"#\"\n"); + printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n"); + printf( "\tputs $cfg \"#\"\n" ); + + printf( "\tputs $autocfg \"/*\"\n" ); + printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" ); + printf( "\tputs $autocfg \" */\"\n" ); + printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" ); + + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + switch ( cfg->token ) + { + default: + break; + + case token_bool: + case token_choice_header: + case token_comment: + case token_define_bool: + case token_dep_tristate: + case token_hex: + case token_int: + case token_string: + case token_tristate: + generate_writeconfig( cfg ); + break; + } + } + printf( "\tclose $cfg\n" ); + printf( "\tclose $autocfg\n" ); + printf( "}\n\n\n" ); + + /* + * Generate a simple function that updates the master choice + * variable depending upon what values were loaded from a .config + * file. + */ + printf( "proc clear_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s; set %s 0\n", + cfg1->optionname, cfg1->optionname ); + } + } + } + printf( "}\n\n\n" ); + + printf( "proc update_choices { } {\n" ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_choice_header ) + { + printf( "\tglobal %s\n", cfg->optionname ); + for ( cfg1 = cfg->next; + cfg1 != NULL && cfg1->token == token_choice_item; + cfg1 = cfg1->next ) + { + printf( "\tglobal %s\n", cfg1->optionname ); + printf( "\tif { $%s == 1 } then { set %s \"%s\" }\n", + cfg1->optionname, cfg->optionname, cfg1->label ); + } + } + } + printf( "}\n\n\n" ); + + printf( "proc update_define { } {\n" ); + clear_globalflags( scfg ); + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if ( cfg->token == token_define_bool ) + { + cfg->global_written = 1; + printf( "\tglobal %s\n", cfg->optionname ); + } + } + + for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) + { + if( cfg->token == token_define_bool ) + { + if ( cfg->cond == NULL ) + printf( "\tset %s %s\n", cfg->optionname, cfg->value ); + else + generate_if( cfg, cfg->cond, -1, 0 ); + } + } + printf( "}\n\n\n" ); + + /* + * That's it. We are done. The output of this file will have header.tk + * prepended and tail.tk appended to create an executable wish script. + */ +} diff --git a/kernel/xconfig/tkparse.c b/kernel/xconfig/tkparse.c new file mode 100644 index 0000000..5a0ecf3 --- /dev/null +++ b/kernel/xconfig/tkparse.c @@ -0,0 +1,619 @@ +/* + * tkparse.c + * + * Eric Youngdale was the original author of xconfig. + * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. + * + * Parse a config.in file and translate it to a wish script. + * This task has three parts: + * + * tkparse.c tokenize the input + * tkcond.c transform 'if ...' statements + * tkgen.c generate output + * + * Change History + * + * 7 January 1999, Michael Elizabeth Chastain, + * - Teach dep_tristate about a few literals, such as: + * dep_tristate 'foo' CONFIG_FOO m + * Also have it print an error message and exit on some parse failures. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one. + * + * 14 January 1999, Michael Elizabeth Chastain, + * - Steam-clean this file. I tested this by generating kconfig.tk for + * every architecture and comparing it character-for-character against + * the output of the old tkparse. + * + * 23 January 1999, Michael Elizabeth Chastain, + * - Remove bug-compatible code. + * + * TO DO: + * - xconfig is at the end of its life cycle. Contact if + * you are interested in working on the replacement. + */ + +#include +#include +#include + +#include "tkparse.h" + +static struct kconfig * config_list = NULL; +static struct kconfig * config_last = NULL; +static const char * current_file = ""; +static int lineno = 0; + +static void do_source( const char * ); + +#undef strcmp +int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } +#define strcmp my_strcmp + + + +/* + * Report a syntax error. + */ +static void syntax_error( const char * msg ) +{ + fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); + exit( 1 ); +} + + + +/* + * Get a string. + */ +static const char * get_string( const char * pnt, char ** label ) +{ + const char * word; + + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' ) + break; + pnt++; + } + + *label = malloc( pnt - word + 1 ); + memcpy( *label, word, pnt - word ); + (*label)[pnt - word] = '\0'; + + if ( *pnt != '\0' ) + pnt++; + return pnt; +} + + + +/* + * Get a quoted string. + * Insert a '\' before any characters that need quoting. + */ +static const char * get_qstring( const char * pnt, char ** label ) +{ + char quote_char; + char newlabel [1024]; + char * pnt1; + + /* advance to the open quote */ + for ( ; ; ) + { + if ( *pnt == '\0' ) + return pnt; + quote_char = *pnt++; + if ( quote_char == '"' || quote_char == '\'' ) + break; + } + + /* copy into an intermediate buffer */ + pnt1 = newlabel; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated quoted string" ); + if ( *pnt == quote_char && pnt[-1] != '\\' ) + break; + + /* copy the character, quoting if needed */ + if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' ) + *pnt1++ = '\\'; + *pnt1++ = *pnt++; + } + + /* copy the label into a permanent location */ + *pnt1++ = '\0'; + *label = (char *) malloc( pnt1 - newlabel ); + memcpy( *label, newlabel, pnt1 - newlabel ); + + /* skip over last quote and next whitespace */ + pnt++; + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + return pnt; +} + + +/* + * Tokenize an 'if' statement condition. + */ +static struct condition * tokenize_if( const char * pnt ) +{ + struct condition * list; + struct condition * last; + + /* eat the open bracket */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt != '[' ) + syntax_error( "bad 'if' condition" ); + pnt++; + + list = last = NULL; + for ( ; ; ) + { + struct condition * cond; + + /* advance to the next token */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + syntax_error( "unterminated 'if' condition" ); + if ( *pnt == ']' ) + return list; + + /* allocate a new token */ + cond = malloc( sizeof(*cond) ); + memset( cond, 0, sizeof(*cond) ); + if ( last == NULL ) + { list = last = cond; } + else + { last->next = cond; last = cond; } + + /* determine the token value */ + if ( *pnt == '-' && pnt[1] == 'a' ) + { cond->op = op_and; pnt += 2; continue; } + + if ( *pnt == '-' && pnt[1] == 'o' ) + { cond->op = op_or; pnt += 2; continue; } + + if ( *pnt == '!' && pnt[1] == '=' ) + { cond->op = op_neq; pnt += 2; continue; } + + if ( *pnt == '=' ) + { cond->op = op_eq; pnt += 1; continue; } + + if ( *pnt == '!' ) + { cond->op = op_bang; pnt += 1; continue; } + + if ( *pnt == '"' ) + { + const char * word; + + /* advance to the word */ + pnt++; + if ( *pnt == '$' ) + { cond->op = op_variable; pnt++; } + else + { cond->op = op_constant; } + + /* find the end of the word */ + word = pnt; + for ( ; ; ) + { + if ( *pnt == '\0' ) + syntax_error( "unterminated double quote" ); + if ( *pnt == '"' ) + break; + pnt++; + } + + /* store a copy of this word */ + { + char * str = malloc( pnt - word + 1 ); + memcpy( str, word, pnt - word ); + str [pnt - word] = '\0'; + cond->str = str; + } + + pnt++; + continue; + } + + /* unknown token */ + syntax_error( "bad if condition" ); + } +} + + + +/* + * Tokenize a choice list. Choices appear as pairs of strings; + * note that I am parsing *inside* the double quotes. Ugh. + */ +static const char * tokenize_choices( struct kconfig * cfg_choose, + const char * pnt ) +{ + for ( ; ; ) + { + struct kconfig * cfg; + + /* skip whitespace */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == '\0' ) + return pnt; + + /* allocate a new kconfig line */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* fill out the line */ + cfg->token = token_choice_item; + cfg->cfg_parent = cfg_choose; + pnt = get_string( pnt, &cfg->label ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + pnt = get_string( pnt, &cfg->optionname ); + } + + return pnt; +} + + + + + +/* + * Tokenize one line. + */ +static void tokenize_line( const char * pnt ) +{ + static struct kconfig * last_menuoption = NULL; + enum e_token token; + struct kconfig * cfg; + + /* skip white space */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + /* + * categorize the next token + */ + +#define match_token(t, s) \ + if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; } + + token = token_UNKNOWN; + switch ( *pnt ) + { + default: + break; + + case '#': + case '\0': + return; + + case 'b': + match_token( token_bool, "bool" ); + break; + + case 'c': + match_token( token_choice_header, "choice" ); + match_token( token_comment, "comment" ); + break; + + case 'd': + match_token( token_define_bool, "define_bool" ); + match_token( token_dep_tristate, "dep_tristate" ); + break; + + case 'e': + match_token( token_else, "else" ); + match_token( token_endmenu, "endmenu" ); + break; + + case 'f': + match_token( token_fi, "fi" ); + break; + + case 'h': + match_token( token_hex, "hex" ); + break; + + case 'i': + match_token( token_if, "if" ); + match_token( token_int, "int" ); + break; + + case 'm': + match_token( token_mainmenu_name, "mainmenu_name" ); + match_token( token_mainmenu_option, "mainmenu_option" ); + break; + + case 's': + match_token( token_source, "source" ); + match_token( token_string, "string" ); + break; + + case 't': + match_token( token_then, "then" ); + match_token( token_tristate, "tristate" ); + break; + + case 'u': + match_token( token_unset, "unset" ); + break; + } + +#undef match_token + + if ( token == token_source ) + { + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + do_source( pnt ); + return; + } + + if ( token == token_then ) + { + if ( config_last != NULL && config_last->token == token_if ) + return; + syntax_error( "bogus 'then'" ); + } + + if ( token == token_unset ) + { + fprintf( stderr, "Ignoring 'unset' command\n" ); + return; + } + + if ( token == token_UNKNOWN ) + syntax_error( "unknown command" ); + + /* + * Allocate an item. + */ + cfg = malloc( sizeof(*cfg) ); + memset( cfg, 0, sizeof(*cfg) ); + if ( config_last == NULL ) + { config_last = config_list = cfg; } + else + { config_last->next = cfg; config_last = cfg; } + + /* + * Tokenize the arguments. + */ + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + cfg->token = token; + switch ( token ) + { + default: + syntax_error( "unknown token" ); + + case token_bool: + case token_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + break; + + case token_choice_header: + { + static int choose_number = 0; + char * choice_list; + + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_qstring ( pnt, &choice_list ); + pnt = get_string ( pnt, &cfg->value ); + if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->depend ); + } + + cfg->optionname = malloc( 32 ); + sprintf( cfg->optionname, "tmpvar_%d", choose_number++ ); + + tokenize_choices( cfg, choice_list ); + free( choice_list ); + } + break; + + case token_comment: + pnt = get_qstring(pnt, &cfg->label); + if ( last_menuoption != NULL ) + { + pnt = get_qstring(pnt, &cfg->label); + last_menuoption->label = cfg->label; + last_menuoption = NULL; + } + break; + + case token_define_bool: + pnt = get_string( pnt, &cfg->optionname ); + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0"; + else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1"; + else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2"; + else + { + syntax_error( "unknown define_bool value" ); + } + break; + + case token_dep_tristate: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' + || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) + && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) + { + /* dep_tristate 'foo' CONFIG_FOO m */ + if ( pnt[0] == 'Y' || pnt[0] == 'y' ) + cfg->depend = strdup( "CONSTANT_Y" ); + else if ( pnt[0] == 'M' || pnt[0] == 'm' ) + cfg->depend = strdup( "CONSTANT_M" ); + else + cfg->depend = strdup( "CONSTANT_N" ); + pnt++; + } + else if ( *pnt == '$' ) + { + pnt++; + pnt = get_string( pnt, &cfg->depend ); + } + else + { + syntax_error( "can't handle dep_tristate condition" ); + } + + /* + * Create a conditional for this object's dependency. + */ + { + char fake_if [1024]; + sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then", + cfg->depend, cfg->depend ); + cfg->cond = tokenize_if( fake_if ); + } + break; + + case token_else: + case token_endmenu: + case token_fi: + break; + + case token_hex: + case token_int: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_string ( pnt, &cfg->value ); + break; + + case token_string: + pnt = get_qstring ( pnt, &cfg->label ); + pnt = get_string ( pnt, &cfg->optionname ); + pnt = get_qstring ( pnt, &cfg->value ); + break; + + case token_if: + cfg->cond = tokenize_if( pnt ); + break; + + case token_mainmenu_name: + pnt = get_qstring( pnt, &cfg->label ); + break; + + case token_mainmenu_option: + if ( strncmp( pnt, "next_comment", 12 ) == 0 ) + last_menuoption = cfg; + else + pnt = get_qstring( pnt, &cfg->label ); + break; + } + + return; +} + + + +/* + * Implement the "source" command. + */ +static void do_source( const char * filename ) +{ + char buffer [1024]; + FILE * infile; + const char * old_file; + int old_lineno; + int offset; + + /* open the file */ + if ( strcmp( filename, "-" ) == 0 ) + infile = stdin; + else + infile = fopen( filename, "r" ); + + /* if that failed, try ../filename */ + if ( infile == NULL ) + { + sprintf( buffer, "../%s", filename ); + infile = fopen( buffer, "r" ); + } + + if ( infile == NULL ) + { + sprintf( buffer, "unable to open %s", filename ); + syntax_error( buffer ); + } + + /* push the new file name and line number */ + old_file = current_file; + old_lineno = lineno; + current_file = filename; + lineno = 0; + + /* read and process lines */ + for ( offset = 0; ; ) + { + char * pnt; + + /* read a line */ + fgets( buffer + offset, sizeof(buffer) - offset, infile ); + if ( feof( infile ) ) + break; + lineno++; + + /* strip the trailing return character */ + pnt = buffer + strlen(buffer) - 1; + if ( *pnt == '\n' ) + *pnt-- = '\0'; + + /* eat \ NL pairs */ + if ( *pnt == '\\' ) + { + offset = pnt - buffer; + continue; + } + + /* tokenize this line */ + tokenize_line( buffer ); + offset = 0; + } + + /* that's all, folks */ + if ( infile != stdin ) + fclose( infile ); + current_file = old_file; + lineno = old_lineno; + return; +} + + + +/* + * Main program. + */ +int main( int argc, const char * argv [] ) +{ + do_source ( "-" ); + fix_conditionals ( config_list ); + dump_tk_script ( config_list ); + return 0; +} diff --git a/kernel/xconfig/tkparse.h b/kernel/xconfig/tkparse.h new file mode 100644 index 0000000..0478eff --- /dev/null +++ b/kernel/xconfig/tkparse.h @@ -0,0 +1,104 @@ +/* + * tkparse.h + */ + +/* + * Token types (mostly statement types). + */ + +enum e_token +{ + token_UNKNOWN, + token_bool, + token_choice_header, + token_choice_item, + token_comment, + token_define_bool, + token_dep_tristate, + token_else, + token_endmenu, + token_fi, + token_hex, + token_if, + token_int, + token_mainmenu_name, + token_mainmenu_option, + token_source, + token_string, + token_then, + token_tristate, + token_unset, +}; + +/* + * Operator types for conditionals. + */ + +enum operator +{ + op_eq, + op_neq, + op_and, + op_and1, + op_or, + op_bang, + op_lparen, + op_rparen, + op_constant, + op_variable, + op_kvariable, + op_nuked +}; + +/* + * Conditions come in linked lists. + * Some operators take strings: + * + * op_constant "foo" + * op_variable "$ARCH", "$CONFIG_PMAC" + * op_kvariable "$CONFIG_EXPERIMENTAL" + * + * Most "$..." constructs refer to a variable which is defined somewhere + * in the script, so they become op_kvariable's instead. Note that it + * is legal to test variables which are never defined, such as variables + * that are meaningful only on other architectures. + */ + +struct condition +{ + struct condition * next; + enum operator op; + const char * str; /* op_constant, op_variable */ + struct kconfig * cfg; /* op_kvariable */ +}; + +/* + * A statement from a config.in file + */ + +struct kconfig +{ + struct kconfig * next; + enum e_token token; + char * optionname; + char * label; + char * value; + struct condition * cond; + char * depend; /* token_dep_tristate */ + struct kconfig * cfg_parent; /* token_choice_item */ + + /* used only in tkgen.c */ + char global_written; + int menu_number; + int menu_line; + struct kconfig * menu_next; +}; + + + +/* + * Prototypes + */ + +extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */ +extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */ diff --git a/kernel/xconfig/trace.in b/kernel/xconfig/trace.in new file mode 100644 index 0000000..a8edcdb --- /dev/null +++ b/kernel/xconfig/trace.in @@ -0,0 +1,45 @@ +###################################################################### +## +## Copyright (C) 1999, 2000, 2001, 2002, Karlsruhe University +## +## File path: xconfig/trace.in +## Description: Various trace configurations. +## +## @LICENSE@ +## +## $Id: trace.in,v 1.9 2002/05/07 19:20:04 skoglund Exp $ +## +###################################################################### + +mainmenu_option next_comment +comment 'Trace Settings' + +if [ "$CONFIG_DEBUGGER_NEW_KDB" != "y" ]; then + bool 'Trace kernel page faults' CONFIG_DEBUG_TRACE_KPF n + bool 'Trace user page faults' CONFIG_DEBUG_TRACE_UPF n + bool 'Trace interrupts' CONFIG_DEBUG_TRACE_IRQS n + bool 'Trace IPCs' CONFIG_DEBUG_TRACE_IPC n + bool 'Trace Syscalls' CONFIG_DEBUG_TRACE_SYSCALLS n + bool 'Trace Mapping Database' CONFIG_DEBUG_TRACE_MDB n + bool 'Trace SMP' CONFIG_DEBUG_TRACE_SMP n + bool 'Trace Inter-processor Communication' CONFIG_DEBUG_TRACE_IPI n + bool 'Trace Misc' CONFIG_DEBUG_TRACE_MISC n + bool 'Verbose startup' CONFIG_DEBUG_TRACE_INIT n + bool 'Visual spin' CONFIG_DEBUG_SPIN n + + if [ "$CONFIG_ARCH_X86" = "y" ]; then + bool 'Enable tracebuffer' CONFIG_TRACEBUFFER n + fi + + bool 'Enable tracepoints' CONFIG_ENABLE_TRACEPOINTS n + bool 'Enable thread switch trace' CONFIG_ENABLE_SWITCH_TRACE n + if [ "$CONFIG_ENABLE_SWITCH_TRACE" = "y" ]; then + int ' Thread switch trace size' CONFIG_SWITCH_TRACE_SIZE 128 + fi +fi + +if [ "$CONFIG_ARCH_X86" = "y" ]; then + bool 'Measure interrupt latency' CONFIG_MEASURE_INT_LATENCY n +fi + +endmenu diff --git a/l4-x86/l4-4-x/c-bind/new/compiler.h b/l4-x86/l4-4-x/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-4-x/c-bind/new/idt.h b/l4-x86/l4-4-x/c-bind/new/idt.h new file mode 100644 index 0000000..b7cec62 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/new/ipc-trent.c b/l4-x86/l4-4-x/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-4-x/c-bind/new/ipc.h b/l4-x86/l4-4-x/c-bind/new/ipc.h new file mode 100644 index 0000000..67932be --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-4-x/c-bind/new/kdebug.h b/l4-x86/l4-4-x/c-bind/new/kdebug.h new file mode 100644 index 0000000..871e0fe --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-4-x/c-bind/new/kernel.h b/l4-x86/l4-4-x/c-bind/new/kernel.h new file mode 100644 index 0000000..1977f60 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-4-x/c-bind/new/syscalls.h b/l4-x86/l4-4-x/c-bind/new/syscalls.h new file mode 100644 index 0000000..9ef3fe9 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/new/test.c b/l4-x86/l4-4-x/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-4-x/c-bind/new/types.h b/l4-x86/l4-4-x/c-bind/new/types.h new file mode 100644 index 0000000..e603f4d --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-4-x/c-bind/new/x-compiler.h b/l4-x86/l4-4-x/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-4-x/c-bind/new/x-idt.h b/l4-x86/l4-4-x/c-bind/new/x-idt.h new file mode 100644 index 0000000..0e37118 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/new/x-ipc.h b/l4-x86/l4-4-x/c-bind/new/x-ipc.h new file mode 100644 index 0000000..c66d84b --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-4-x/c-bind/new/x-kdebug.h b/l4-x86/l4-4-x/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..0f7cf48 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-4-x/c-bind/new/x-kernel.h b/l4-x86/l4-4-x/c-bind/new/x-kernel.h new file mode 100644 index 0000000..b9d7224 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-4-x/c-bind/new/x-lid.c b/l4-x86/l4-4-x/c-bind/new/x-lid.c new file mode 100644 index 0000000..58b23a0 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-4-x/c-bind/new/x-syscalls.h b/l4-x86/l4-4-x/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..675fccd --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/new/x-types.h b/l4-x86/l4-4-x/c-bind/new/x-types.h new file mode 100644 index 0000000..3dfab37 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:29:53 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-4-x/c-bind/orig/compiler.h b/l4-x86/l4-4-x/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-4-x/c-bind/orig/idt.h b/l4-x86/l4-4-x/c-bind/orig/idt.h new file mode 100644 index 0000000..9e50cf5 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/orig/ipc-trent.c b/l4-x86/l4-4-x/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-4-x/c-bind/orig/ipc.h b/l4-x86/l4-4-x/c-bind/orig/ipc.h new file mode 100644 index 0000000..1f43d77 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-4-x/c-bind/orig/kdebug.h b/l4-x86/l4-4-x/c-bind/orig/kdebug.h new file mode 100644 index 0000000..92e64dd --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-4-x/c-bind/orig/kernel.h b/l4-x86/l4-4-x/c-bind/orig/kernel.h new file mode 100644 index 0000000..732942c --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-4-x/c-bind/orig/syscalls.h b/l4-x86/l4-4-x/c-bind/orig/syscalls.h new file mode 100644 index 0000000..10cb80c --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/orig/types.h b/l4-x86/l4-4-x/c-bind/orig/types.h new file mode 100644 index 0000000..dd44fa3 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-4-x/c-bind/provisional/compiler.h b/l4-x86/l4-4-x/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-4-x/c-bind/provisional/idl.m4 b/l4-x86/l4-4-x/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-4-x/c-bind/provisional/idt.h b/l4-x86/l4-4-x/c-bind/provisional/idt.h new file mode 100644 index 0000000..9e50cf5 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/provisional/ipc-trent.c b/l4-x86/l4-4-x/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-4-x/c-bind/provisional/ipc.h b/l4-x86/l4-4-x/c-bind/provisional/ipc.h new file mode 100644 index 0000000..4a78feb --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-4-x/c-bind/provisional/kdebug.h b/l4-x86/l4-4-x/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..92e64dd --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-4-x/c-bind/provisional/kernel.h b/l4-x86/l4-4-x/c-bind/provisional/kernel.h new file mode 100644 index 0000000..732942c --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-4-x/c-bind/provisional/syscalls.h b/l4-x86/l4-4-x/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..10cb80c --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-4-x/c-bind/provisional/types.h b/l4-x86/l4-4-x/c-bind/provisional/types.h new file mode 100644 index 0000000..dd44fa3 --- /dev/null +++ b/l4-x86/l4-4-x/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:29:54 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-4-x/kernel/adrsman.asm b/l4-x86/l4-4-x/kernel/adrsman.asm new file mode 100644 index 0000000..a18d1e2 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/adrsman.asm @@ -0,0 +1,954 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 08, 08, 99, 9025 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 08.08.99 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86 + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + lno___task eax,ebp ; + load__proot eax,eax ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + lno___task edi,ebx ; + ; + call detach_associated_small_space ; + ; + load__proot edi,edi ; + ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + mov ecx,[(ecx*8)+task_proot].switch_ptr + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax ; + lea___tcb ebp,eax ; + ; + IFZ [edi*8+task_proot].proot_ptr,0 ; + mov edi,[edi*8+task_proot].switch_ptr ; + sub edi,ds:[empty_proot] ; + ELSE_ ; + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + pop eax + + lno___task ebp + store_proot eax,ebp + FI + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + + ret + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + + lno___task ebp,esi + lea edi,[ebp*8+task_proot] + + movzx eax,ah + movzx ecx,[edi].small_as + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*2)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*2)+small_associated_task],bp + FI + mov ecx,eax + mov [edi].small_as,al + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + mov [edi].switch_ptr,ecx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push eax + push edi + + movzx edi,[(ecx*2)+small_associated_task] + test edi,edi + IFNZ + mov word ptr [(ecx*2)+small_associated_task],0 + + call flush_small_pde_block_in_all_pdirs + + lea ecx,[(edi*8)+task_proot] + + mov eax,cr3 + mov cr3,eax + + mov eax,[ecx].proot_ptr + mov al,0 + mov [ecx].switch_ptr,eax + mov [ecx].proot_ptr,eax + FI + + lno___task eax,esp + IFZ eax,edi + call make_own_address_space_large + FI + + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; detach associated small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push ecx + + movzx ecx,[edi*8+task_proot].small_as + test ecx,ecx + IFNZ + call detach_small_space + FI + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; EDI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[edi].switch_ptr + mov edi,ds:[kernel_proot] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + lno___task edi,esp + + lea edi,[(edi*8)+task_proot] + mov eax,[edi].proot_ptr + mov al,0 + mov [edi].switch_ptr,eax + + mov edi,eax + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + mov fs,eax + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + mov edx,offset task_proot + DO + mov ebp,[edx].proot_ptr + add edx,8 + and ebp,0FFFFFF00h + REPEATZ + + EXITS + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + lno___task eax,esi + mov eax,[eax*8+task_proot].switch_ptr + + test eax,eax + IFNS + mov al,0 + ret + FI + + rol eax,8 + xchg al,ah + shr eax,22-16 + sub al,(offset small_virtual_spaces SHR 22) AND 0FFh + add al,al + add al,ds:[small_space_size_DIV_MB4] + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/atrace.asm b/l4-x86/l4-4-x/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-4-x/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-4-x/kernel/boot.asm b/l4-x86/l4-4-x/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-4-x/kernel/contents b/l4-x86/l4-4-x/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-4-x/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/cpuctr.asm b/l4-x86/l4-4-x/kernel/cpuctr.asm new file mode 100644 index 0000000..7f950a6 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/cpuctr.asm @@ -0,0 +1,1195 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 24,08,99, 68, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + + switch_thread con,ebx + + shr ebp,task_no + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + push eax + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + pop eax + + mov esi,ebp + shr ebp,task_no + + push ds + switch_space ; switch space may load user_linear space into ds + pop ds + + mov ebp,esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret + + +deallocate_ressources: + + push eax + + test [edi+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + mov eax,ebp + shr eax,task_no + mov eax,[(eax*8)+task_proot-(offset tcb_space SHR (task_no-3))] + CORA eax, + IFZ ds:[cpu_cr3],eax + + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd + push offset reallocate_ressources_by_ret + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],phys_mem_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/dispatch.asm b/l4-x86/l4-4-x/kernel/dispatch.asm new file mode 100644 index 0000000..3f1dac0 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/dispatch.asm @@ -0,0 +1,1419 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 11,03,99, 9089, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86 + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + klign 16 + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + ELIFZ ebx,[esi+int_preempter] + add dl,20h + ELIFZ ebx,[esi+ext_preempter] + add dl,30h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + FI + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFB_ ah,max_small_spaces + call attach_small_space + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov ebx,[esi+ext_preempter] + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + clign 4 + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + clign 16 + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/emuctr.asm b/l4-x86/l4-4-x/kernel/emuctr.asm new file mode 100644 index 0000000..1587a73 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/emuctr.asm @@ -0,0 +1,512 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86 + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + clign 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/idecode.asm b/l4-x86/l4-4-x/kernel/idecode.asm new file mode 100644 index 0000000..6a3760f --- /dev/null +++ b/l4-x86/l4-4-x/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],phys_mem_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-4-x/kernel/intctr.asm b/l4-x86/l4-4-x/kernel/intctr.asm new file mode 100644 index 0000000..9e6c3aa --- /dev/null +++ b/l4-x86/l4-4-x/kernel/intctr.asm @@ -0,0 +1,533 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 12,12,97, 57 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86 + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler + db dpl3 + dd offset initial_debug_exception_handler + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler + db dpl3 + dd offset overflow_handler + db dpl3 + dd offset bound_check_handler + db dpl3 + dd offset invalid_opcode_handler + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler + db dpl0 + dd offset stack_exception_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler + db dpl0 + dd offset alignment_check_handler + db dpl0 + dd offset machine_check_exception + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,phys_mem_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + mov ecx,linear_space ; + CORNZ [esp+ip_ds],ecx ; + mov edx,es ; + IFNZ edx,ecx ; + test byte ptr ss:[esp+ip_cs],11b + IFNZ ; + mov [esp+ip_ds],ecx; do not update DS + mov es,ecx ; (DS might be kernel seg) + FI ; if within kernel ! + ipost ; + FI ; + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + lno___task edi,esp + test byte ptr ss:[edi*8+task_proot+3].switch_ptr,80h + CANDNZ + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/ipcman.asm b/l4-x86/l4-4-x/kernel/ipcman.asm new file mode 100644 index 0000000..bf3a162 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/ipcman.asm @@ -0,0 +1,3520 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 12,01,00, 4000, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + shr ebp,task_no + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + + + push eax + push ebx + + cmp eax,virtual_space_size-MB4 + jae receive_only + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + mov [ebx+waiting_for],esi + and al,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + ; + and ebp,mask task_no ; + mov edx,ebx ; + ; + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + mov edx,[edx+ebp+redirection_table] ; + ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + and ebp,mask thread_no + + mov [ebx+mword2],edi + add ebp,offset tcb_space + + mov edi,[ebx+myself] + ;REDIR: and al,(NOT ipc_control_mask)+deceit+map_msg + + mov edx,[ebp+myself] + xor edi,esi + + test edi,mask chief_no + xc nz,to_chief,long + + cmp esi,edx + jnz ipc_dest_not_existent + + test al,deceit + xc nz,propagate_pre,long + + mov dl,[ebp+fine_state] + + + and dl,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + xc nz,pending_or_auto_propagating,long + FI + + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + + mov edx,[ebx+rcv_descriptor] + mov ch,running + + mov [ebp+fine_state],ch + cmp edx,virtual_space_size + + mov dh,[ebx+list_state] + IF____xc ae,send_only,long + + ELSE__ + and edx,(is_polled SHL 8) + nclos + + cmp edx,(is_polled SHL 8) + nclos + jz fetch_next + + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + +;;;;; switch_thread ipc,edi + mov cl,[edi+ressources] + + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + shr ebp,task_no + mov esi,[edi+myself] + + test al,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + + +;;;;;;;;;;;; switch_space + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + cmp byte ptr ds:[gdt+linear_space/8*8+7],0 + mov cr3,ebp + mov ebp,linear_space + IFZ + mov ds,ebp + pop ebp + iretd + FI + FI + mov ebp,00CCF300h + FI + + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + + mov ds:[gdt+linear_space_exec/8*8+4],ebp + mov ebp,linear_space + + mov es,ebp + + mov fs,ebp + + mov gs,ebp + + mov ds,ebp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pop ebp + iretd + + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z + + mov esi,[edi+virtual_sender] + xret + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + mov edi,[esp+iret_esp+3*4] ; must be read from user space, + sub edx,edx + + mov [ebx+propagatee_tcb],edx + mov edi,es:[edi] ; potentially small space + + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + mov [ebx+virtual_sender],edi + + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + test esi,mask task_no + IFZ + lea___tcb esi,edi + + test__page_writable esi + IFNC + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + CANDZ dl,closed_wait + CANDZ [ebx+myself],edi + + mov [ebx+propagatee_tcb],esi + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + xret ,long + FI + + + ;REDIR begin -------------------------------- + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + test edx,mask chief_no ; ; + xret z,long ; + ; + mov edx,[ebx+myself] ; + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; + ; + and ebp,mask task_no ; + mov esi,edi ; + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + pop ebp ; + pop ecx ; + xret ,long ; + OD ; + pop ebp ; + pop ecx ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + ;REDIR ends ----------------------------------- + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + mov edx,(locked_running SHL 8) + (locked_waiting AND 0FFh) + + mov [ebx+fine_state],dh + mov [ebp+fine_state],dl + + and al,ipc_control_mask + mov esi,[esp+4+4] + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + IFNZ + mov bl,al + mov eax,es:[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + ;; mov [ebx+com_partner],ebp + + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + ;;; mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w3 + nop + + mov eax,[eax*8+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w3] + + mov edi,[edx+32] + lea edi,[edx+msg_w3] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressource ebx,com_used + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + nop + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w3 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + IFB_ eax,ecx + mov ecx,eax + FI + IFB_ ebx,ecx + mov ecx,ebx + FI + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + + + if 0 ;----------------------------------------- + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w3-2*4] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w3-2*4] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + + push eax + push ebx + + mov eax,[edi+buf_addr] + mov [edi+str_len],ecx + mov [edi+str_addr],eax + + mov esi,[esi+str_addr] + mov edi,eax + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + + + endif ;-------------------------------------- + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +XHEAD prepare_small_string_source + + shl eax,16 + + lea edx,[esi+ecx] + sass__32 cmp,edx,MB4 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + align 16 + + + +fetch_next: + + add dl,locked_closed_waiting + mov [ebx+fine_state],dl + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/kdebug.asm b/l4-x86/l4-4-x/kernel/kdebug.asm new file mode 100644 index 0000000..ce284cb --- /dev/null +++ b/l4-x86/l4-4-x/kernel/kdebug.asm @@ -0,0 +1,5650 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 07,10,99, 76 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 07.10.99 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_proot +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86 + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,cs:[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_proot + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,cs:[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ cs:[no_breakpoint_thread],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ cs:[breakpoint_thread],0 + cmp cs:[breakpoint_thread],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp cs:[debug_exception_handler] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ cs:[bx_size],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + test cs:[physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + mov eax,cs:[kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + IFZ ebp,cs:[kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_proot + ELIFZ al,'t' + mov eax,offset task_proot + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ds + + popad + jmp cs:[page_fault_handler] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop ds + + popad + add esp,4 + jmp cs:[ipc_handler] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,cs:[monitored_exception] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,cs:[monitored_ec_min] + movzx ecx,cs:[monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop ds + + popad + + CORB cs:[monitored_exception],8 + IFA cs:[monitored_exception],14 + IFNZ cs:[monitored_exception],17 + add esp,4 + FI + FI + + jmp cs:[monitored_exception_handler] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop ds + + popad + add esp,4 + FI + + jmp cs:[timer_intr_handler] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_proot + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__proot edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0 + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov [trace_buffer_in_pointer],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + shr ecx,2 + sub eax,eax + cld + rep stosd + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + mov ecx,event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,event_select_msr + mov eax,ebx + wrmsr + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + IFAE esp,virtual_space_size + call open_trace_buffer + CANDNC + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + FI + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +event_select_msr equ 11h +event_counter0_msr equ 12h +event_counter1_msr equ 13h + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 00011111b +w_stall equ 00011001b +r_stall equ 00011010b +x_stall equ 00011011b +agi_stall equ 00011111b + +bus_util equ 00011000b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + + +set_performance_tracing: + + kd____clear_page + call show_trace_perf_monitoring_mode + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + sub ebx,ebx + IFZ al,'i' + mov ebx,instrs_ex + (instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,rw_miss + (ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,rw_tlb + (ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,r_stall + (w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,agi_stall + (bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,bus_util + (instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,event_select_msr + wrmsr + mov ecx,event_counter0_msr + wrmsr + mov ecx,event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,event_select_msr + wrmsr + FI + + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/kdiopc.asm b/l4-x86/l4-4-x/kernel/kdiopc.asm new file mode 100644 index 0000000..328080e --- /dev/null +++ b/l4-x86/l4-4-x/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86 + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/kernel.asm b/l4-x86/l4-4-x/kernel/kernel.asm new file mode 100644 index 0000000..185d2e7 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 40000 +kerneltxt EQU '12.01.00' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4 Ver 4-X Nucleus (x86), Copyright (C) IBM 1997 & University of Karlsruhe 1999,2000',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/ktest.asm b/l4-x86/l4-4-x/kernel/ktest.asm new file mode 100644 index 0000000..69d848c --- /dev/null +++ b/l4-x86/l4-4-x/kernel/ktest.asm @@ -0,0 +1,1058 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 02,09,97, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 02.09.97 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86 + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' +; +; +; +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; +; mov esi,MB1 +; mov ecx,1024 +; DO +; mov eax,[esi] +; mov eax,[esi+28] +; add esi,32 +; dec ecx +; REPEATNZ +; OD +; +; rdtsc +; sub eax,ebx +; sub eax,12 +; add eax,511 +; shr eax,10 +; push eax +; +; +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; kd____disp <13,10,'RAM cache-line read: '> +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,1000h + ; cmp byte ptr ds:[ebx],0 + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 1' + ; + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,MB16 + ; and ebx,-pagesize + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 2' + ; + + + + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma1_task +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + ; mov edx,ecx + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + mov eax,3 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + ;------------------- for translate test only: + ; or byte ptr ds:[MB4],0 + ;---------------------------------------- + + clign 16 + DO + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count mem2pipe,cnt_event,bank_conf,cnt_event +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 +; P_count r_stall,cnt_event_PL3,w_stall,cnt_event_PL3 + rdtsc + push eax + + clign 16 + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/memctr.asm b/l4-x86/l4-4-x/kernel/memctr.asm new file mode 100644 index 0000000..1d66a75 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/memctr.asm @@ -0,0 +1,519 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86 + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + load__proot ebx,<((sigma0_task AND mask task_no) SHR task_no)> + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/pagctr.asm b/l4-x86/l4-4-x/kernel/pagctr.asm new file mode 100644 index 0000000..e49fdac --- /dev/null +++ b/l4-x86/l4-4-x/kernel/pagctr.asm @@ -0,0 +1,1184 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 24,08,99, 116 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_proot + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + mov [edi+4],ecx + add edi,8 + cmp edi,offset proot_end_marker + REPEATB + OD + dec ecx + mov [edi],ecx + mov [edi+4],ecx + + + mov ds:[kernel_proot],edx + mov ds:[kernel_proot+4],edx + mov ds:[empty_proot],ebx + mov ds:[empty_proot+4],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/pagfault.asm b/l4-x86/l4-4-x/kernel/pagfault.asm new file mode 100644 index 0000000..72597f7 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/pagfault.asm @@ -0,0 +1,753 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 11,03,99, 9163, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86 + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_cs+4],phys_mem_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + IFNZ [ebp+fine_state],locked_running + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + push 0 + push phys_mem_exec + push offset ipcret + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + call push_ipc_state + + IFNZ + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + test__page_present edx + CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin + CANDBE eax,offset ipc_critical_region_end + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + mov ah,byte ptr ds:[gdt+(linear_space AND -8)+7] + mov al,byte ptr ds:[gdt+(linear_space AND -8)+4] + shl eax,16 + xor eax,edx + shr eax,22 + mov cl,ch + shr eax,cl + + mov esi,ebp + IFNZ + mov esi,[ebp+com_partner] + FI + lno___task esi,esi + load__proot esi,esi + add esi,PM + + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + mov ebp,edi + pop esi + REPEAT + OD + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__proot eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/pagmap.asm b/l4-x86/l4-4-x/kernel/pagmap.asm new file mode 100644 index 0000000..2ac9d4d --- /dev/null +++ b/l4-x86/l4-4-x/kernel/pagmap.asm @@ -0,0 +1,1908 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 05,02,00, 44 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 05.02.00 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86 + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_ + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page + jmp short do_fpage + FI + push offset unmap_write_page + jmp short do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page + jmp short do_fpage + FI + push offset flush_write_page + jmp short do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + push edx + + mov edx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,edx + mov bl,[edx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize;;;;;;;;0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + pop ebx + xc z,unmap_in_own_address_space + + pop edx + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + test ebx,1 + IFNZ + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + + ELSE_ + push edx + + mov ebx,[eax].pte_ptr + mov ebx,edx + and edx,(pagesize-1) AND -4 + shr ebx,log2_pagesize + shl edx,log2_pagesize-2 + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ebx,(pagesize-1) AND -4 + shl ebx,2*log2_pagesize-4 + add edx,ebx + invlpg [edx] + + pop edx + FI + + + mov ebx,[eax].pte_ptr + cmp edx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp edx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + pop ebx + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + + + test ebx,1 + IFZ + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -4 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -4 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + + + + FI + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + lno___task edx,ebp + load__proot edx,edx + add edx,PM + + mov ecx,cr3 + IFAE , + lno___task ecx,esp + load__proot ecx,ecx + FI + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-4-x/kernel/proj.err b/l4-x86/l4-4-x/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-4-x/kernel/sgmctr.asm b/l4-x86/l4-4-x/kernel/sgmctr.asm new file mode 100644 index 0000000..09e27ec --- /dev/null +++ b/l4-x86/l4-4-x/kernel/sgmctr.asm @@ -0,0 +1,256 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.09.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +.list + + +ok_for x86 + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS phys_mem_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6,phys_mem_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + + descriptor xr32, dpl0, PM, ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-4-x/kernel/sigma0.asm b/l4-x86/l4-4-x/kernel/sigma0.asm new file mode 100644 index 0000000..7c1a0e0 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/sigma0.asm @@ -0,0 +1,769 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-4-x/kernel/start.asm b/l4-x86/l4-4-x/kernel/start.asm new file mode 100644 index 0000000..f6f08f7 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/start.asm @@ -0,0 +1,354 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86 + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/startpc.asm b/l4-x86/l4-4-x/kernel/startpc.asm new file mode 100644 index 0000000..4bf695d --- /dev/null +++ b/l4-x86/l4-4-x/kernel/startpc.asm @@ -0,0 +1,1288 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + inrtc rtc_seconds + mov ah,al + DO + inrtc rtc_seconds + cmp ah,al + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-4-x/kernel/tables.asm b/l4-x86/l4-4-x/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/tcbman.asm b/l4-x86/l4-4-x/kernel/tcbman.asm new file mode 100644 index 0000000..93e6fb7 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/tcbman.asm @@ -0,0 +1,733 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 16,03,99, 9141 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + extrn sigma_1_installed:byte + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86 + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + cmp ebx,-1 + IFNZ + xchg ebx,[ebp+int_preempter] + ELSE_ + mov ebx,[ebp+int_preempter] + FI + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret + + mov dword ptr [esi+4],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; FI + mov [ebp+pager],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + ELSE_ + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/x.asm b/l4-x86/l4-4-x/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernel/y.asm b/l4-x86/l4-4-x/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-4-x/kernel/yoonseva.asm b/l4-x86/l4-4-x/kernel/yoonseva.asm new file mode 100644 index 0000000..f914529 --- /dev/null +++ b/l4-x86/l4-4-x/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),phys_mem_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/adrspac5.inc b/l4-x86/l4-4-x/kernifc/adrspac5.inc new file mode 100644 index 0000000..4f3d1de --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/adrspac5.inc @@ -0,0 +1,200 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ( 64*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ( 88*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00B63000h-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd tasks*dwords_per_task_proot dup (?) ; | + proot_end_marker dd dwords_per_task_proot dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd 0,0 + kernel_proot dd 0,0 + sigma0_proot dd 0,0 + +special_proots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) diff --git a/l4-x86/l4-4-x/kernifc/adrspace.inc b/l4-x86/l4-4-x/kernifc/adrspace.inc new file mode 100644 index 0000000..85947b8 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ x86 + +subtitle L4/x86 Version X + +kernel_type = x86 + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-4-x/kernifc/apic.inc b/l4-x86/l4-4-x/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/contents b/l4-x86/l4-4-x/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/cpucb.inc b/l4-x86/l4-4-x/kernifc/cpucb.inc new file mode 100644 index 0000000..4b3149c --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/cpucb.inc @@ -0,0 +1,7 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/l4-4-x/kernifc/cpucb5.inc b/l4-x86/l4-4-x/kernifc/cpucb5.inc new file mode 100644 index 0000000..826accb --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/cpucb5.inc @@ -0,0 +1,286 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-4-x/kernifc/intrifc.inc b/l4-x86/l4-4-x/kernifc/intrifc.inc new file mode 100644 index 0000000..c9101d5 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/intrifc.inc @@ -0,0 +1,323 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/kpage.inc b/l4-x86/l4-4-x/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-4-x/kernifc/l4const.inc b/l4-x86/l4-4-x/kernifc/l4const.inc new file mode 100644 index 0000000..df2a916 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/l4const.inc @@ -0,0 +1,95 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +linear_kernel_space equ 0008h + +linear_space equ (0010h+3) +linear_space_exec equ (0018h+3) + +phys_mem_exec equ 0020h +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/l4kd.inc b/l4-x86/l4-4-x/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-4-x/kernifc/l4pre.inc b/l4-x86/l4-4-x/kernifc/l4pre.inc new file mode 100644 index 0000000..a29ddfc --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/l4pre.inc @@ -0,0 +1,884 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxhl equ ax +ebxhl equ bx +ecxhl equ cx +edxhl equ dx +esihl equ si +edihl equ di +ebphl equ bp +eaxl equ al +ebxl equ bl +ecxl equ cl +edxl equ dl +eaxh equ ah +ebxh equ bh +ecxh equ ch +edxh equ dh +axl equ al +bxl equ bl +cxl equ cl +dxl equ dl +axh equ ah +bxh equ bh +cxh equ ch +dxh equ dh + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + +clign macro alignment,off + +ifb +aax=($-modstart) AND (alignment-1) +else +aax=($-modstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +klign macro alignment,off + +ifb +aax=($-kmodstart) AND (alignment-1) +else +aax=($-kmodstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + +sysenter macro +db 0Fh,34h +endm + + +sysexit macro +db 0Fh,35h +endm + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-4-x/kernifc/lbmac.inc b/l4-x86/l4-4-x/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-4-x/kernifc/pagcb.inc b/l4-x86/l4-4-x/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-4-x/kernifc/pagconst.inc b/l4-x86/l4-4-x/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-4-x/kernifc/pagmac.inc b/l4-x86/l4-4-x/kernifc/pagmac.inc new file mode 100644 index 0000000..bcb4b50 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/pagmac.inc @@ -0,0 +1,123 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +x86_proot struc + + switch_ptr dd 0 + proot_ptr dd 0 + +x86_proot ends + +x86_prootx struc + + dd 0 + small_as db 0 + db 0,0,0 + +x86_prootx ends + + +load__proot macro reg,task_no + + mov reg,ds:[(task_no*8)+task_proot+4] + IFIDN , + mov al,0 + ELSEIFIDN , + mov bl,0 + ELSEIFIDN , + mov cl,0 + ELSEIFIDN , + mov dl,0 + ELSE + and reg,0FFFFFF00h + ENDIF + endm + + +store_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + mov ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + +store_inactive_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot],reg + mov ds:[(task_no*8)+task_proot+4],0 + endm + + +chnge_proot macro reg,task_no + + test byte ptr ds:[(task_no*8)+task_proot+3],80h + IFZ + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + + diff --git a/l4-x86/l4-4-x/kernifc/perfmon.inc b/l4-x86/l4-4-x/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-4-x/kernifc/pnodes.inc b/l4-x86/l4-4-x/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-4-x/kernifc/schedcb.inc b/l4-x86/l4-4-x/kernifc/schedcb.inc new file mode 100644 index 0000000..8f80035 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-4-x/kernifc/schedcb2.inc b/l4-x86/l4-4-x/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-4-x/kernifc/small-as.inc b/l4-x86/l4-4-x/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-4-x/kernifc/tcb.inc b/l4-x86/l4-4-x/kernifc/tcb.inc new file mode 100644 index 0000000..5579288 --- /dev/null +++ b/l4-x86/l4-4-x/kernifc/tcb.inc @@ -0,0 +1,275 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + pager dd 0 + dd 0 + + com_partner dd 0 + waddr dd 0 + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + + + myself dd 0 + dd 0 + waiting_for dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + ext_preempter dd 0 + dd 0 + int_preempter dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:4,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_proot/(dwords_per_task_proot*4) GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_proot)/(dwords_per_task_proot*4) - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-4-x/l4-4-x-x86.pjt b/l4-x86/l4-4-x/l4-4-x-x86.pjt new file mode 100644 index 0000000..b36a327 --- /dev/null +++ b/l4-x86/l4-4-x/l4-4-x-x86.pjt @@ -0,0 +1,137 @@ +;Codewright Project File (do not remove or modify this line) +[ProjInit] +ProjSetConfigFlags=0x00010140 +ProjCheckPath='C:\LIEDTKE\l4-4-x\\' + +[Files] + +[State] +SysSetCwd='C:\LIEDTKE\l4-4-x\make' +SrchSetFlags=0x0519604a +FileSortMode=0x0 +_StateHistory=FILELIST,'C:\LIEDTKE\l4-x\x86\kdebug.lst','C:\LIEDTKE\l4-4-x\make\make-l4','C:\LIEDTKE\l4-4-x\make\ml-x86.bat','C:\LIEDTKE\l4-4-x\kernifc\L4pre.inc','C:\LIEDTKE\l4-4-x\kernel\adrsman.asm','C:\LIEDTKE\l4-4-x\kernel\ipcman.asm','C:\LIEDTKE\l4-4-x\kernifc\Intrifc.inc','C:\LIEDTKE\l4-4-x\x86\ipcman.lst','C:\LIEDTKE\l4-4-x\kernel\kernel.asm' +_StateHistory=SEARCH,'page_fault_handler','ipc_handler','remote_kd_intr','reset_rtc_timer_intr','apic','init_apic','reset','com','show_p','l4-x' +_StateHistory=REPLACE,' ','SU','pre_paging','l4.exe','$(a)','l4-x','l4','ml-x86','x86','l4-4-x' +_StateHistory=XSYMBOL,'__L4_TYPES_H__','L4_NIL_ID','L4_LOG2_SUPERPAGESIZE','LnInvalidThread','LId_FirstInterrupt','LId_Equal','ToLId','FromLId','SCRATCH_MEMORY' +_StateHistory=EDITFILE,'C:\LIEDTKE\ln-x\make\xml-pent.bat','C:\LIEDTKE\ln-x\make\make-ln','C:\LIEDTKE\ln-x\pent\ln.rsp','C:\LIEDTKE\ln-x\make\xml-pent.bat','C:\LIEDTKE\ln-x\make\make-l4','C:\LIEDTKE\ln-x\x86\l4.rsp','C:\LIEDTKE\l4-x\make\make-l4','C:\LIEDTKE\l4-x\make\ml-x86.bat','C:\LIEDTKE\l4-x\make\make-l4','C:\LIEDTKE\l4-4-x\make\ml-x86.bat' +_StateHistory=DIRECTORY,'C:\ln-21\src','C:\ln-x\src','C:\home\LIEDTKE\ln-x\make','C:\home\LIEDTKE\ln-x\src','C:\LIEDTKE\ln-x\kernel','C:\LIEDTKE\l4-x\make','C:\LIEDTKE\l4-x\kernifc','C:\LIEDTKE\l4-x\userifc','C:\LIEDTKE\l4-x','C:\LIEDTKE\l4-x\kernel' +_StateHistory=OUTNAME,'nick' +_StateHistory=DOSHISTORY,'x','exit' +_StateHistory=DIFFFILE,'C:\LIEDTKE\l4-x\kernel\kdebug.asm','C:\LIEDTKE\l4-x\kernel\sgmctr.asm','C:\LIEDTKE\l4-x\kernel\start.asm','C:\LIEDTKE\l4-x\kernel\tcbman.asm','C:\LIEDTKE\l4-x\kernel\intctr.asm','C:\LIEDTKE\l4-y\kernel\kdebug.asm' +_StateHistory=DIFFTARGET,'C:\LIEDTKE\l4-y\kernel\kdebug.asm','C:\LIEDTKE\l4-y\kernel\sgmctr.asm','C:\LIEDTKE\l4-y\kernel\start.asm','C:\LIEDTKE\l4-y\kernel\tcbman.asm','C:\LIEDTKE\l4-y\kernel\intctr.asm','C:\LIEDTKE\l4-x\kernel\kdebug.asm' +ProjLoadWorkspace='std',1 + +[Editor] +_RestoreSysFlags=0x63097fc8, 0xfffffffc, 0 +ClipboardSetTermStr='\r\n',0 +ClipboardEnableTermStr=1 +ClipboardSetSepStr='\r\n',0 +ClipboardEnableSepStr=1 +ScrapSetCount=1 +VCSProject='' +VCSProjectPath='' +VCSProjectLocalPath='' + +[Compiler] +TagSetCmd='${HOME}${WTAGS} -oc -d -t${TAGFILE}.tag -p${TAGFILE}.ptg',0x8000060 +BrowseSetFile='C:\l4-4-x\l4-4-x.ptg' +TagSetFile='C:\l4-4-x\l4-4-x.tag' +CompilerAddCmd='Microsoft Assembler','',1073741840,'',16,'',16,'',16,'',0,'',0,'','','','','' +CompilerAddResponse='Microsoft Assembler', +CompilerAddCmd='Default Compiler Settings','ml %r',1073741840,'',16,'',16,'',16,'',0,'',0,'','','','','' +CompilerAddResponse='Default Compiler Settings', +CompilerAddCmd='masm5','ml-pex2 %r %e %Q',1073741840,'',16,'',16,'',16,'',0,'',0,'','','','','' +CompilerAddResponse='masm5', +CompilerAddCmd='LaTeX','texv %r',1073741840,'',16,'',16,'',16,'',0,'',0,'','','','','' +CompilerAddResponse='LaTeX', +CompilerAddCmd='masm','ml-pex2 %r %e %Q',1073741840,'',16,'',16,'',16,'',0,'',0,'','','','','' +CompilerAddResponse='masm', +CompilerAddCmd='$_cw_proj_hash_$','',1073741904,'',80,'${FTEE} nmaker /F %v\liedtke\l4-4-x\make\make-l4 /B %v\liedtke\l4-4-x\x86\l4.exe',176,'${FTEE} nmake',176,'',0,'',0,'_ErrorInfoDefault','','','proj.err','C:\LIEDTKE\l4-4-x\make' +CompilerAddResponse='$_cw_proj_hash_$', +CompilerAddCmd='Microsoft C(NT-i386)','${FTEE} cl -DSTRICT -c -W3 -G3 -D_X86_=1 -DWIN32 %r%e',1073741936,'${FTEE} cl -DSTRICT -c -W3 -G3 -D_X86_=1 -DWIN32 %r%e',112,'',144,'',144,'',0,'',0,'_MicrosoftErrorInfo','','','','' +CompilerAddResponse='Microsoft C(NT-i386)', +CompilerNewExt=.htm +CompilerAssign='Microsoft C(NT-i386)','.c' +CompilerAssign='LaTeX','.psc' +CompilerNewExt=.pas +CompilerAssign='Microsoft C(NT-i386)','.h' +CompilerNewExt=.lst +CompilerAssign='masm','.inc' +CompilerNewExt=.ini +CompilerNewExt=.html +CompilerAssign='Microsoft C(NT-i386)','.cpp' +CompilerAssign='Default Compiler Settings','.*' +CompilerAssign='Microsoft C(NT-i386)','.cxx' +CompilerNewExt=.txt +CompilerAssign='masm','.asm' +CompilerAssign='Microsoft C(NT-i386)','.hpp' +CompilerAssign='LaTeX','.tex' +CompilerAssign='masm','.as5' + +[Extension.inc] +ExtSetBorderElements='.inc','/*','-','**','**','**','**','-','*/','/*','*/',1 +BufSetBackupSpec='' +BufSetTabStr='5 9' +BufSetMarginColumns=1,72 +BufSetAutoIndentMode=0x0000 +BufSetMaxTabCol=0x00c8 +BufSetMaxVirtualLines=0x0019 +ExtSetBufFlags=0x8800048e,0x301cff +ExtSetTemplateMacro=2,'@' +ExtSetTemplateMacro=1,'\t' +ExtSetTemplateMacro=0,'\n' +ExtSetStyle=.inc,1 + +[Extension] +ExtColorsAssoc='.asm',1 +ExtSetDelimiters=.asm,^A-Za-z0-9_ +ExtColorsAssoc='.h',1 +ExtSetDelimiters=.h,^A-Za-z0-9_ +ExtColorsAssoc='.cpp',1 +ExtSetDelimiters=.cpp,^A-Za-z0-9_ +ExtColorsAssoc='.htm',1 +ExtSetDelimiters=.htm,^A-Za-z0-9_ +ExtColorsAssoc='.html',1 +ExtSetDelimiters=.html,^A-Za-z0-9_ +ExtColorsAssoc='.lst',1 +ExtSetDelimiters=.lst,^A-Za-z0-9_ +ExtColorsAssoc='.c',1 +ExtSetDelimiters=.c,^A-Za-z0-9_ +ExtColorsAssoc='.txt',1 +ExtSetDelimiters=.txt,^A-Za-z0-9_ +ExtColorsAssoc='.pas',1 +ExtSetDelimiters=.pas,^A-Za-z0-9_ +ExtColorsAssoc='.ini',1 +ExtSetDelimiters=.ini,^A-Za-z0-9_ +ExtColorsAssoc='.inc',1 +ExtSetDelimiters=.inc,^A-Za-z0-9_ +ExtColorsAssoc='.*',1 +ExtSetDelimiters=.*,^A-Za-z0-9_ +ExtColorsAssoc='.as5',1 +ExtSetDelimiters=.as5,^A-Za-z0-9_ +ExtAlias=.htm,.html +ExtAlias=.jav,.java +ExtAlias=.as5,.asm + + +[Extension.asm] +ExtSetBorderElements='.asm',';','-',';',';',';',';','-',';',';','',1 +BufSetBackupSpec='' +BufSetTabStr='5 9' +BufSetMarginColumns=1,72 +BufSetAutoIndentMode=0x0000 +BufSetMaxTabCol=0x00c8 +BufSetMaxVirtualLines=0x0019 +ExtSetBufFlags=0x8800048e,0x301cff +ExtSetTemplateMacro=2,'@' +ExtSetTemplateMacro=1,'\t' +ExtSetTemplateMacro=0,'\n' +ExtSetStyle=.asm,1 +[Workspace.std] +StateWindowFrame=330,20,620,455,0x63097fc8 + +[Project] +ConfigSetLinkDBFilename='C:\CW32\cwright.ldb' +ConfigSetMarkDBFilename='C:\CW32\cwright.mrk' +ConfigSetSymbolDBFilename='C:\CW32\cwright.sbl' +EditSetPath='' diff --git a/l4-x86/l4-4-x/make/l4.rsp b/l4-x86/l4-4-x/make/l4.rsp new file mode 100644 index 0000000..4ceee3c --- /dev/null +++ b/l4-x86/l4-4-x/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-4-x/make/make-l4 b/l4-x86/l4-4-x/make/make-l4 new file mode 100644 index 0000000..b563953 --- /dev/null +++ b/l4-x86/l4-4-x/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-4-x\kernel\;\liedtke\l4-4-x\kernifc\;\liedtke\l4-4-x\userifc\} +a=d:\liedtke\l4-4-x\x86^\ +all_includes_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_x86) $(p)adrsman.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 adrsman asm + +$(a)cpuctr.obj : $(all_includes_x86) $(p)cpuctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 cpuctr asm + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman.obj : $(all_includes_x86) $(p)ipcman.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 ipcman asm + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 kernel asm + +$(a)ktest.obj : $(all_includes_x86) $(p)ktest.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 ktest asm + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr.obj : $(all_includes_x86) $(p)pagctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 pagctr asm + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap.obj : $(all_includes_x86) $(p)pagmap.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 pagmap asm + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 tcbman asm + +$(a)yoonseva.obj : $(all_includes_x86) $(p)yoonseva.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-4-x\x86 + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \liedtke\l4-4-x\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-4-x\x86 + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-4-x/make/ml-x86.bat b/l4-x86/l4-4-x/make/ml-x86.bat new file mode 100755 index 0000000..37080f7 --- /dev/null +++ b/l4-x86/l4-4-x/make/ml-x86.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=x86 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-4-x/make/proj.err b/l4-x86/l4-4-x/make/proj.err new file mode 100644 index 0000000..9325974 --- /dev/null +++ b/l4-x86/l4-4-x/make/proj.err @@ -0,0 +1,11 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\kernel.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-4-x/userifc/contents b/l4-x86/l4-4-x/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-4-x/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-4-x/userifc/msg.inc b/l4-x86/l4-4-x/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-4-x/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-4-x/userifc/scmac.inc b/l4-x86/l4-4-x/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-4-x/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-4-x/userifc/syscalls.inc b/l4-x86/l4-4-x/userifc/syscalls.inc new file mode 100644 index 0000000..ff0f980 --- /dev/null +++ b/l4-x86/l4-4-x/userifc/syscalls.inc @@ -0,0 +1,25 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 \ No newline at end of file diff --git a/l4-x86/l4-4-x/userifc/uid.inc b/l4-x86/l4-4-x/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-4-x/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-4test/kernel/adrsman4.asm b/l4-x86/l4-4test/kernel/adrsman4.asm new file mode 100644 index 0000000..c43ea57 --- /dev/null +++ b/l4-x86/l4-4test/kernel/adrsman4.asm @@ -0,0 +1,347 @@ +include l4pre.inc + + + Copyright GMD, L4.ADRSMAN.4, 16, 07, 96, 25 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 07.03.90 ****** +;****** modified: 16.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +.list + +ok_for i486,ppro + + + + assume ds:codseg + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+PM + call define_idt_gate + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager.low +; EBP pager.high +; ESI task id.low +; EDI task id.high +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id (low) / 0 +; EDI new task id (high / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + tpost eax + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + push esi + push ebx + push ebp + + mov ebp,esp + and ebp,-sizeof tcb + + mov ebx,[ebp+myself] + xor ebx,edi + test ebx,mask chief_no + IFZ + mov ebx,[ebp+chief] + cmp ebx,mask depth + jae task_new_failed + xor ebx,edi + test ebx,mask site_no + FI + jnz task_new_failed + + lea___tcb ebx,esi + test__page_present ebx + IFNC + CANDNZ [ebx+coarse_state],unused_tcb + + xor esi,[ebx+myself] + test esi,NOT (mask ver1 + mask ver0) + IFZ + cmp [ebx+chief],edi + FI + jnz task_new_failed + + + pushad ;------------------------- + ; + lno___task edi,ebx ; + load__proot edi,edi ; delete task + ; + mov cl,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec cl ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22 ; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool ; + ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + load__proot ecx,ecx + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + and edi,NOT mask task_no + or edi,eax + + lno___task ebx + shr eax,task_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,4*4 + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop edi + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov [ebp+myself],esi + mov eax,[ebx+myself] + mov edi,[ebx+chief] + and eax,mask task_no + and edi,NOT mask task_no + or edi,eax + IFNZ eax,root_chief + add edi,(1 SHL depth) + FI + mov [ebp+chief],edi + + tpost eax,ds,es + + + + + + + + icode + + + + +create_kernel_including_task: + + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + mov edi,root_chief + + call create_thread + + pop eax + + lno___task ebp + store_proot eax,ebp + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + + ret + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/adrsman5.as5 b/l4-x86/l4-4test/kernel/adrsman5.as5 new file mode 100644 index 0000000..8177726 --- /dev/null +++ b/l4-x86/l4-4test/kernel/adrsman5.as5 @@ -0,0 +1,917 @@ +include l4pre.inc + + + Copyright GMD, L4.ADRSMAN.5, 16, 07, 96, 25 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 07.03.90 ****** +;****** modified: 16.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public create_kernel_including_task + public init_small_address_spaces + public update_proot + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for pentium,k6 + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + mov ds:[highest_task],eax + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+PM + call define_idt_gate + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager.low +; EBP pager.high +; ESI task id.low +; EDI task id.high +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id (low) / 0 +; EDI new task id (high / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,4*4 + iretd + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + push esi + push ebx + push ebp + + mov ebp,esp + and ebp,-sizeof tcb + + mov ebx,[ebp+myself] + xor ebx,edi + test ebx,mask chief_no + IFZ + mov ebx,[ebp+chief] + cmp ebx,mask depth + jae task_new_failed + xor ebx,edi + test ebx,mask site_no + FI + jnz task_new_failed + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT (mask ver1 + mask ver0) + IFZ + cmp [ebx+chief],edi + FI + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + mov eax,[ebp+task_pdir] ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute in to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + mov edi,[ebx+task_pdir] ; + ; + mov cl,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec cl ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22 ; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool ; + ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + mov eax,ds:[kernel_proot] + xpdir ecx,ebx + mov eax,dword ptr [ecx*4+eax+PM] + test al,page_present + CORZ + and eax,-pagesize + xptab ecx,ebx + mov eax,dword ptr [ecx*4+eax+PM] + test eax,eax + IFZ + mov eax,booter_task + FI + + xor eax,ebp + test eax,mask task_no + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + and edi,NOT mask task_no + or edi,eax + + xpdir eax,ebx + shl eax,2 + add eax,ds:[kernel_proot] + mov eax,dword ptr [eax+PM] + test al,page_present + IFZ + ke 'task_ptab' + FI + and eax,-pagesize + xptab ebx,ebx + mov dword ptr [ebx*4+eax+PM],edi + + add esp,4*4 + push linear_space + pop ds + push linear_space + pop es + iretd + + FI + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + IFA esi,ds:[highest_task] + mov ds:[highest_task],esi + FI + + push eax + push ebx + push ecx + mov esi,ebx + mov ebx,ds:[empty_proot] + mov ecx,ebx + mov al,0 + call update_proot + pop ecx + pop ebx + pop eax + + pop edi + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov [ebp+myself],esi + mov eax,[ebx+myself] + mov edi,[ebx+chief] + and eax,mask task_no + and edi,NOT mask task_no + or edi,eax + IFNZ eax,root_chief + add edi,(1 SHL depth) + FI + mov [ebp+chief],edi + + + tpost eax,ds,es + + + + + + + + icode + + + + +create_kernel_including_task: + + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + mov edi,root_chief + + call create_thread + + pop ebx + mov ecx,ebx + mov al,0 + mov esi,ebp + call update_proot + FI + + ret + + + + icod ends + + + + + +;---------------------------------------------------------------------------- +; +; update proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL small as number +; EBX task pdir +; ECX thread proot +; ESI tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread_proot set in all threads of task +; +;---------------------------------------------------------------------------- + + +update_proot: + + push esi + push edx + + and esi,-(lthreads*sizeof tcb) + + mov edx,lthreads + DO + IF (lthreads*sizeof tcb) GT pagesize + test__page_writable esi + IFNC + mov [esi+thread_proot],ecx + mov [esi+task_pdir],ebx + mov [esi+small_as],al + add esi,sizeof tcb + dec edx + REPEATNZ + FI + add esi,pagesize + sub edx,pagesize/sizeof tcb + REPEATA + ELSE + mov [esi+thread_proot],ecx + mov [esi+task_pdir],ebx + mov [esi+small_as],al + add esi,sizeof tcb + dec edx + REPEATNZ + ENDIF + OD + + pop edx + pop esi + ret + + + + + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],22-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + mov ebp,esi + set___lthread ebp,0 + + movzx eax,ah + movzx ecx,[esi+small_as] + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*4)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*4)+small_associated_task],ebp + FI + mov ecx,eax + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + + push ebx + mov ebx,[esi+task_pdir] + call update_proot + pop ebx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push esi + + mov esi,[(ecx*4)+small_associated_task] + test esi,esi + IFNZ + push eax + push ebx + push ecx + + call flush_small_pde_block_in_all_pdirs + + mov eax,cr3 + mov cr3,eax + + mov ebx,[esi+task_pdir] + mov ecx,ebx + mov al,0 + call update_proot + + mov eax,esi + xor eax,esp + test eax,mask task_no + IFZ + call make_own_address_space_large + FI + + pop ecx + pop ebx + pop eax + FI + + pop esi + ret + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; ESI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[esi+thread_proot] + mov edi,ds:[kernel_proot] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + mov edi,esp + and edi,-sizeof tcb + + mov edi,[edi+task_pdir] + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + sub eax,eax + mov fs,eax + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push edi + push ebp + + mov edx,kernel_task + offset tcb_space - lthreads*sizeof tcb + DO + add edx,lthreads*sizeof tcb + cmp edx,ds:[highest_task] + EXITA + + test__page_present edx + REPEATC + + mov ebp,[edx+task_pdir] + + test ebp,ebp + REPEATZ + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + mov edi,ds:[linktab_base] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + + and byte ptr [eax*linksize+edi].pdir_link,NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edi + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + mov edx,ds:[linktab_base] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [eax*linksize+edx].pdir_link,01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + + lno___task eax,esi + mov al,[esi+small_as] + + test al,al + IFNZ + add al,al + add al,ds:[small_space_size_DIV_MB4] + FI + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/copy of ipcman5.as5 b/l4-x86/l4-4test/kernel/copy of ipcman5.as5 new file mode 100644 index 0000000..c597c59 --- /dev/null +++ b/l4-x86/l4-4test/kernel/copy of ipcman5.as5 @@ -0,0 +1,2862 @@ +include l4pre.inc + + + Copyright IBM, L4.IPCMAN.5, 25,07,97, 302, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for pentium + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX -ud- +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = offset tcb_space + + + +ipc_sc: + + + mov ecx,ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + mov edx,edi + and edi,mask thread_no + + mov [ebp+ipc_control],eax + jz receive_only + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],ecx + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + + test esi,esi + xc z,send_only + + xor edx,ss:[edi+ebp+myself+X] + xor ecx,ss:[edi+ebp+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+ebp+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+ebp+thread_state+X],ecx + mov ch,ss:[ebp+resources] + + or ecx,edx + xc nz,deallocate_resources_or_bad_segments + + mov ss:[ebp+thread_esp],esp + pop edx + + mov esp,ss:[edi+ebp+thread_esp+X] + mov ecx,ss:[edi+ebp+thread_proot+X] + + mov ebp,offset gdt + test ecx,ecx + + lea edi,[esp+iret_vec+4] + xc ns,switch_to_large_address_space + + mov byte ptr ss:[ebp+linear_space/8*8+1],ch + mov byte ptr ss:[ebp+linear_space_exec/8*8+1],ch + + mov ss:[ebp+cpu_esp0-offset gdt],edi + mov ch,0F3h + + mov dword ptr ss:[ebp+linear_space/8*8+4],ecx + mov ch,0FBh + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],ecx + + mov ebp,linear_space + pop edi + + mov ds,ebp + + mov es,ebp + + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+ebp+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+esi+X] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/copy of pagmap5.as5 b/l4-x86/l4-4test/kernel/copy of pagmap5.as5 new file mode 100644 index 0000000..7ef57a2 --- /dev/null +++ b/l4-x86/l4-4test/kernel/copy of pagmap5.as5 @@ -0,0 +1,1700 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGMAP.5, 09,01,97,200 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 17.07.96 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public map_or_grant_fpage + public flush_address_space + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + + + +ok_for pentium + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + mov edi,esi + mov al,0 + cld + rep stosb + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + imul eax,pnodes_per_frame-1 + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + +; mov ebx,M4_pnode_base +; DO +; mov [ebx].pte_ptr,0 +; mov [ebx].cache0,ebx +; mov [ebx].cache1,ebx +; inc ebx +; mov [ebx-1].child_pnode,ebx +; +; add ebx,sizeof pnode-1 +; cmp ebx,M4_pnode_base + max_M4_frames * sizeof pnode +; REPEATB +; OD + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page + jmp do_fpage + FI + push offset unmap_write_page + jmp do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page + jmp short do_fpage + FI + push offset flush_write_page + jmp short do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map or grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL operation +; EDX centerpoint +; EBX source fpage addr +; EBP dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_or_grant_fpage: + + + mov ch,al ; ch: opn + + mov eax,ebx + mov ebx,edi + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + mov edx,ebp + + push edi + push edx + push eax + push offset map_page + + test ch,fpage_grant + jz short do_fpage + + + mov ch,0FFh ; map mask: all + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + mov [esp],offset grant_page_ + jmp short do_fpage + + FI + + ret + + + + + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IF kernel_type EQ pentium + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + ENDIF + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,pagesize-1 + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax + FI + + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + push ecx + mov ecx,100 + mov eax,ebx + DO + ; dec ecx + ; IFZ + ; ke 's00' + ; FI + + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + ; dec ecx + ; IFZ + ; ke 's01' + ; FI + + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ecx + ret + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + jnz short void_or_access_attribute_widening + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,ebx + mov bl,[ebx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + xc z,unmap_in_own_address_space + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + +XHEAD unmap_in_own_address_space + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + mov ebx,[eax].pte_ptr + cmp ebx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp ebx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,max_physical_memory_size + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + + icod ends + + + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/cpuctr4.asm b/l4-x86/l4-4test/kernel/cpuctr4.asm new file mode 100644 index 0000000..f4e803b --- /dev/null +++ b/l4-x86/l4-4test/kernel/cpuctr4.asm @@ -0,0 +1,992 @@ +include l4pre.inc + + + Copyright GMD, L4.CPUCTR.4, 18,07,96, 62, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 12.03.90 ****** +;****** modified: 18.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_resources_int + public deallocate_resources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_num + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include schedcb.inc +.list + + +ok_for i486 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_cpuctr: + + IF uniprocessor + + mov eax,offset deallocate_resources + sub eax,offset fast_switch+5 + mov dword ptr ds:[fast_switch+1+PM],eax + + ENDIF + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + + + mov dword ptr ds:[cpu_label],' 68 ' + mov dword ptr ds:[cpu_label+4],' ' + + mov ds:[cpu_feature_flags],0 + + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[cpu_label],'3' + mov ds:[cpu_type],i386 + .listmacroall + ELIFZ eax,<(1 SHL ac_flag)> + .nolistmacro + mov ds:[cpu_label],'4' + mov ds:[cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + mov cl,ah + mov ds:[cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[cpu_feature_flags],edx + + FI + + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + + + mov ds:[cpu_no],0 + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + mov ax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+PM + call define_idt_gate + + bt ds:[cpu_feature_flags],machine_check_exception_bit + cmp eax,eax + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+PM + call define_idt_gate + + mov ecx,1 + rdmsr ; resets machine check type + + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,6 ; enable machine check + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-486_required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + klign 16 + + +switch_context: + + switch_thread con,ebx + + xor ebx,ebp + shr ebp,task_no + test ebx,mask task_no + + IFNZ + switch_space + FI + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + push eax + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + pop eax + + mov esi,ebp + shr ebp,task_no + + switch_space + + mov ebp,esi + + jmp ecx + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate resources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI source tcb +; EBP dest tcb +; +; [EDI+resources] resources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; resources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of resources: +; +; Ressources are: com_space +; numeric coprocessor +; debug register +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_resources_tunnel: + push offset switch_thread_tunnel_ret+PM + jmp short deallocate_resources + + +deallocate_resources_con: + mov edi,ebx + push offset switch_thread_con_ret+PM + jmp short deallocate_resources + + +deallocate_resources_int: + mov edi,ebx + push offset switch_thread_int_ret+PM + jmp short deallocate_resources + + +deallocate_resources_ipc: + push offset switch_thread_ipc_ret+PM + + +deallocate_resources: + + push eax + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+resources],NOT mask x87_used + IFZ + pop eax + ret + FI + + test [edi+resources],mask com_used + IFNZ + and [edi+resources],NOT mask com_used + + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + mov eax,ebp + xor eax,edi + test eax,mask task_no + IFZ + mov eax,cr3 + mov cr3,eax + FI + FI + + test [edi+resources],mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_resources_by_popebp_iretd+PM + push offset reallocate_resources_by_ret+PM + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate resources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; resources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_resources_by_popebp_iretd: + + call reallocate_resources + + pop ebp + iretd + + + + + +reallocate_resources_by_ret: + + add esp,3*4 + + + +reallocate_resources: + + push eax + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+resources] + + test al,mask dr_used + IFNZ + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+resources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_resources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_resources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec + + mov eax,dr7 + test al,10b + IFZ + CANDZ ss:[esp+ip_cs],linear_kernel_space_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov [(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov al,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov [edi+(eax*4)],ecx + + mov al,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+PM + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + mov cr0,eax + fninit + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_num: + + IFZ ds:[actual_co1_tcb],edx + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [edx+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; Machine Check Exception +; +;---------------------------------------------------------------------------- + + +machine_check_exception: + + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + mov ebx,eax + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/cpuctr5.as5 b/l4-x86/l4-4test/kernel/cpuctr5.as5 new file mode 100644 index 0000000..8453605 --- /dev/null +++ b/l4-x86/l4-4test/kernel/cpuctr5.as5 @@ -0,0 +1,1195 @@ +include l4pre.inc + + + Copyright GMD, L4.CPUCTR.5, 22,12,97, 301, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 12.03.90 ****** +;****** modified: 22.12.97 ****** +;****** ****** +;********************************************************************* + + + + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_resources + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + + + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include apic.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for pentium,k6 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + + + +cr4_enable_superpages equ 4 +cr4_enable_global_pages equ 7 + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + + + mov dword ptr ds:[cpu_label],' 68 ' + mov dword ptr ds:[cpu_label+4],' ' + + mov ds:[cpu_feature_flags],0 + + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[cpu_label],'3' + mov ds:[cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)>,long + + mov ds:[cpu_label],'4' + mov ds:[cpu_type],i486 + + ELSE_ long + + mov eax,1 + cpuid + + mov cl,ah + mov ds:[cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[cpu_feature_flags],edx + + IF kernel_type EQ k6 + + sub eax,eax + cpuid + cmp ebx,'htuA' + CORNZ + cmp edx,'itne' + CORNZ + cmp ecx,'DMAc' + CORNZ + mov eax,80000000h + cpuid + test eax,eax + CORZ + mov eax,80000001h + cpuid + mov ds:[amd_feature_flags],edx + bt edx,amd_syscall_ret_bit + IFNC + ke 'no K6' + FI + ENDIF + FI + + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+PM + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+PM + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,pentium + ke '-pentium_required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + FI + + + ret + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int+PM + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + FI + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + mov eax,offset apic_error_handler+PM + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP current thread (tcb address) +; EDI destination thread (tcb address) +; +; SS linear kernel space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,ESI values loaded by source thread +; EAX,EBP scratch +; +; DS,ES linear space (related to dest task) +; FS,GS 0 +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + + mov al,ss:[ebp+resources] + mov ss:[ebp+thread_esp],esp + + test al,NOT is_polled + ccall nz,deallocate_resources + + mov ebp,edi + + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,ss:[ebp+thread_esp] + mov eax,ss:[ebp+thread_proot] + + mov ebp,offset gdt + test eax,eax + IFNS ,,long + IFNZ ss:[ebp+cpu_cr3-offset gdt],eax,long + + mov ss:[ebp+cpu_cr3-offset gdt],eax + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],eax + mov cr3,eax + FI + mov eax,00CCF300h + FI + mov ss:[ebp+linear_space/8*8+4],eax + mov ah,0FBh + mov ss:[ebp+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov ds,eax + mov es,eax + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP current thread (tcb write addr) (must be locked_waiting!) +; EDI destination thread (tcb write addr) (must be locked_running!) +; +; DS linear kernel space ! +; +; SS linear kernel space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + mov eax,ds:[edi+thread_esp] + sub eax,4 + pop ecx + mov ds:[eax],ecx + mov ds:[edi+thread_esp],eax + + movi eax,ready + mov ds:[edi+thread_state],eax + add eax,locked-ready + mov ss:[ebp+thread_state],eax + + jmp switch_context + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate resources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address of current thread +; EDI tcb address of destination thread +; +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; resources switched and updated +; +; FS, GS (re)enforced to 0 +; +;---------------------------------------------------------------------------- +; Semantics of resources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + + +deallocate_resources: + + push eax + push ecx + + mov al,[ebp+resources] + sub ecx,ecx + + mov fs,ecx + + mov gs,ecx + + + test al,mask x87_used + IFNZ + mov ecx,cr0 + or ecx,1 SHL ts_bit + mov cr0,ecx + + and al,NOT mask x87_used + mov ss:[ebp+resources],al + test al,NOT is_polled + IFZ + pop ecx + pop eax + ret + FI + FI + + test al,mask com_used + IFNZ + push ebp + mov ebp,offset pdir+(com0_base SHR 20) + + sub ecx,ecx + mov ss:[ebp],ecx + + mov ss:[ebp+4],ecx + mov ss:[ebp+((com1_base-com0_base) SHR 20)],ecx + + mov ss:[ebp+((com1_base-com0_base) SHR 20)+4],ecx + pop ebp + + mov ecx,ss:[edi+thread_proot] + CORA ecx, + IFZ ss:[cpu_cr3],ecx + + mov ecx,cr3 + mov cr3,ecx + FI + + and al,NOT mask com_used + mov ss:[ebp+resources],al + test al,NOT is_polled + IFZ + pop ecx + pop eax + ret + FI + FI + + test al,mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + pop ecx + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov ss:[ebp+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop ecx + pop eax + pop ebp + + pushfd + push cs + push offset reallocate_resources_by_popebp_iretd+PM + push offset reallocate_resources_by_ret+PM + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate resources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; resources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_resources_by_popebp_iretd: + + call reallocate_resources + + pop ebp + iretd + + + + + +reallocate_resources_by_ret: + + add esp,3*4 + + + +reallocate_resources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+resources] + + test al,mask dr_used + IFNZ + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+resources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_resources_by_ret+PM + mov dword ptr ds:[eax+4],offset reallocate_resources_by_popebp_iretd+PM + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],linear_kernel_space_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov al,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov al,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+PM + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/dispatch.asm b/l4-x86/l4-4test/kernel/dispatch.asm new file mode 100644 index 0000000..155408f --- /dev/null +++ b/l4-x86/l4-4test/kernel/dispatch.asm @@ -0,0 +1,1285 @@ +include l4pre.inc + + + Copyright GMD, L4.DISPATCH, 31,01,97, 200, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 07.03.90 ****** +;****** modified: 27.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn flush_tcb:near + extrn init_rtc_timer:near + extrn physical_kernel_info_page:dword + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include pagconst.inc +include apic.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + IF kernel_type NE i486 + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + ENDIF + + + align 4 + + +present_chain_version dd 0 + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov ds:[scheduled_tcb],offset dispatcher_tcb + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[scheduled_tcb],offset dispatcher_tcb + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc+PM + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc+PM + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + llinit ebx,ready + + linit soon_wakeup + linit late_wakeup + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + IFZ ebp, + call init_dispatcher_tcb + FI + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + + test byte ptr [ebp+ipc_control],0F0h + CORZ + IFBE [ebp+thread_state],locked + + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + IFZ [ebp+thread_state],ready + test [ebp+list_state],is_ready + CANDZ + call insert_into_ready_list + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + lldel ebp,edx,eax,ready + IFZ ebp,ds:[scheduled_tcb] + mov cl,[edx+prio] + IFAE cl,[eax+prio] + mov eax,edx + FI + mov ds:[scheduled_tcb],eax + FI + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + klign 16 + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; schedule running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *not* in ready list +; +; SS linear kernel space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + + test ss:[ebp+list_state],is_ready + IFNZ + ke 'ihhh' + FI + + push eax + push edi + + mov al,ss:[ebp+prio] + mov edi,ebp + + mov ebp,ss:[scheduled_tcb] + + IFA al,ss:[ebp+prio] + + mov ss:[scheduled_tcb],edi + + ELSE_ + DO + mov ebp,ss:[ebp+ready_llink].pred + cmp al,ss:[ebp+prio] + REPEATB + OD + FI + + llins_ss edi,ebp,eax,ready + + mov ebp,edi + + pop edi + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ebp + mov edi,esi + + mark__ready ebp + + push offset switch_ret+PM + + lea___tcb edi,edi + cmp edi,dispatcher_tcb + jbe dispatch + + mov ebp,edi + + IFNZ edi,eax + test__page_writable ebp + CANDNC + + cmp [ebp+thread_state],ready + mov ebp,eax + jz switch_context + + FI + jmp dispatch + + + align 4 + + + + + + + +switch_ret: + + tpost eax + + + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate resources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; SS linear kernel space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebp,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov ebx,ebp + mov ss:[ebp+thread_esp],esp + + DO + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov ebp,ss:[scheduled_tcb] + + CORZ ebp,ebx + CORNZ ss:[ebp+thread_state],ready + IFLE ss:[ebp+rem_timeslice],0 + + mov al,ss:[ebp+prio] + mov ebp,ss:[ebp+ready_llink].succ + DO + cmp al,ss:[ebp+prio] + xc a,perhaps_back + + cmp ss:[ebp+thread_state],ready + EXITZ + + lldel_ss ebp,edi,edx,ready + mov ebp,edx + REPEAT + OD + + + mov ss:[scheduled_tcb],ebp + + mov al,ss:[ebp+rem_timeslice] + IFLE al,0 + add al,ss:[ebp+timeslice] + mov ss:[ebp+rem_timeslice],al + FI + FI + + cmp ebp,dispatcher_tcb + REPEATZ + OD + + mov edi,ebp + mov ebp,ebx + + cmp edi,ebp + + mov esp,ss:[ebp+thread_esp] + jnz switch_context + ret + + + + +XHEAD perhaps_back + + cmp ss:[ebp+thread_state],ready + xret nz + + DO + mov ebp,ss:[ebp+ready_llink].pred + cmp al,ss:[ebp+prio] + REPEATBE + OD + + mov ah,ss:[ebp+prio] + mov edx,ebp + mov ebp,ss:[ebp+ready_llink].succ + mov al,ss:[ebp+prio] + cmp al,ah + xret a + mov ebp,edx + xret + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + IF kernel_type NE i486 + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + ENDIF + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + + + IF kernel_type NE i486 + + jmp timer_int + + kcode + + + + align 16 + + + + + + apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + ENDIF + + + + +timer_int: + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebp+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub edi,edi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + IFNZ ebp,dispatcher_tcb + + sub [ebp+rem_timeslice],dl + + CORLE + test edi,edi + IFNZ + + mark__ready ebp + + push offset timer_int_ret+PM + + test edi,edi + jz dispatch + jmp switch_context + + + timer_int_ret: + FI + FI + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebp+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebx,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebx,ecx,soon_wakeup + xret z + + test byte ptr [ebx+ipc_control],0F0h + IFNZ + CANDA [ebx+thread_state],locked + + cmp [ebx+wakeup_low],eax + REPEATG + + IFNZ ebp,dispatcher_tcb + mov al,[ebp+prio] + CANDA [ebx+prio],al + + mov edi,ebx + mark__interrupted ebp + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebx,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebx,late_wakeup + clign 16 + DO + movl__next ebx,ecx,late_wakeup + xret z,long + + test byte ptr [ebx+ipc_control],0F0h + IFNZ + CANDA [ebx+thread_state],locked + + cmp [ebx+wakeup_low],eax + REPEATG + + test [ebx+list_state],is_soon_wakeup + IFZ + lins ebx,esi,soon_wakeup + FI + FI + ldel ebx,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebx,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + test byte ptr [ebx+ipc_control],0F0h + REPEATZ + cmp [ebx+thread_state],locked + REPEATBE + + test [ebx+list_state],is_late_wakeup + REPEATNZ + + cmp [ebx+wakeup_low],eax + REPEATG + + lins ebx,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter (low) / 0 +; EBP ext preempter (high) / 0 +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + IFZ + cmp [esi+chief],edi + FI + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ eax,ready + mov dl,00h + FI + ;; IFZ eax, ???? + ;; mov dl,40h + ;; FI + IFZ eax,locked + mov dl,80h + FI + IFZ eax,polling + mov dl,0D0h + FI + IFAE eax,waiting_none + mov dl,0C0h + FI + IFB_ dl,0C0h + mov eax,[esi+thread_state] + IFZ eax,polling + mov eax,[esi+com_partner] + FI + test eax,eax + IFNZ + IFZ eax,[esi+pager] + add dl,10h + ELIFZ eax,[esi+int_preempter] + add dl,20h + ELIFZ eax,[esi+ext_preempter] + add dl,30h + FI + FI + FI + + shl edx,12 + + IF kernel_type NE i486 + call get_small_space + mov dh,al + ENDIF + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + mov [esi+ext_preempter+4],ebp + FI + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + mov [esi+prio],al + + IFNZ dl,al + test [esi+list_state],is_ready + CANDNZ + pushad + mov ebp,esi + lldel ebp,ecx,edx,ready + IFZ ebp,ds:[scheduled_tcb] + mov al,[ecx+prio] + IFBE al,[edx+prio] + mov ecx,edx + FI + mov ds:[scheduled_tcb],ecx + FI + call insert_into_ready_list + popad + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IF kernel_type NE i486 + + IFB_ ah,max_small_spaces + call attach_small_space + FI + + ENDIF + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + ;; test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov ebx,[esi+ext_preempter] + ;; mov ebp,[esi+ext_preempter+4] + + ;; mov edi,[esi+waiting_for+4] + ;; mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/emuctr.asm b/l4-x86/l4-4test/kernel/emuctr.asm new file mode 100644 index 0000000..5b9a885 --- /dev/null +++ b/l4-x86/l4-4test/kernel/emuctr.asm @@ -0,0 +1,370 @@ +include l4pre.inc + + + Copyright GMD, L4.EMUCTR, 03,07,96, 40028 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 06.06.91 ****** +;****** modified: 03.07.96 ****** +;****** ****** +;********************************************************************* + + +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + ;public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +.list + + +ok_for i486,pentium,ppro,k6 + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +;v86_emu_tab dd gp_exception ; 0 +; dd gp_exception ; 1 +; dd gp_exception ; 2 +; dd gp_exception ; 3 +; dd gp_exception ; 4 +; dd gp_exception ; 5 +; dd gp_exception ; 6 +; dd gp_exception ; 7 +; dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler+PM + call define_idt_gate + + ; bt ds:[cpu_feature_flags],enhanced_v86_bit + ; IFC + ; db 0Fh,20h,0E0h + ; ; mov eax,cr4 + ; bts eax,0 ; enable enhanced v86 features + ; ; mov cr4,eax + ; db 0Fh,22h,0E0h + ; FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +;signal_virtual_interrupt: +; +; push ebp +; mov ebp,esp +; and ebp,-sizeof tcb +; +; lea___ip_bottom ebp,ebp +; bts [ebp+iv_eflags],vip_flag +; +; pop ebp +; ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +;XHEAD virtual_interrupt_pending +; +; test eax,(1 SHL vif_flag) +; xret z +; +; btr [esp+iv_eflags],vip_flag +; mov al,nmi +; jmp exception + + + + + + align 16 + + + + +general_protection_handler: + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + IFNZ + mov ebp,[esp+ip_error_code] + test ebp,0000FFFFh + CANDZ + + ; mov eax,ss:[esp+ip_eflags] + ; test eax,(1 SHL vm_flag) + ; IFNZ + ; ; note: V86 has always large + ; test eax,(1 SHL vip_flag) ; space! + ; xc nz,virtual_interrupt_pending ; + ; + ; movzx eax,[esp+iv_ip] + ; movzx esi,[esp+iv_cs] + ; add esi,esi + ; mov eax,ds:[eax+(esi*8)] + ; + ; cmp al,0Fh + ; jz short prefix_0F_operation + ; + ; movzx ebp,al + ; movzx ebp,ss:[ebp+opcode_type-80h+PM] + ; jmp ss:[(ebp*4)+v86_emu_tab+PM] + ; FI + + test byte ptr [esp+ip_cs],11b + IFNZ + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + cmp al,0Fh + jz short prefix_0F_operation + FI + FI + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi] + shr eax,8 + + IFZ al, + call emu_load_dr + + ELIFZ al, + call emu_store_dr + + ELIFZ ax,1801h + call emu_lidt_eax + + IF kernel_type NE i486 + ELIFZ al, + call emu_rdmsr + ELIFZ al, + call emu_wrmsr + ENDIF + + ELSE_ + jmp gp_exception + + FI + movzx eax,al + add [esp+ip_eip],eax + + + clign 16 + + +gp_return: + + ipost + + + IF kernel_type NE i486 + + +emu_rdmsr: + + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + mov al,2 + + ret + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + wrmsr + mov al,2 + ret + + + ENDIF + + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/intctr.asm b/l4-x86/l4-4test/kernel/intctr.asm new file mode 100644 index 0000000..e6f8250 --- /dev/null +++ b/l4-x86/l4-4test/kernel/intctr.asm @@ -0,0 +1,575 @@ +include l4pre.inc + + + Copyright GMD, L4.INTCTR, 02,01,97, 200 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 19.07.87 ****** +;****** modified: 12.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + extrn physical_kernel_info_page:dword + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include pagmac.inc +include cpucb.inc +.list +include syscalls.inc +.nolist +include kpage.inc +.list + + + IF kernel_type NE i486 + extrn make_own_address_space_large:near + ENDIF + + +ok_for i486,pentium,ppro,k6 + + + icode + + +idtvec dw sizeof idt+5*8-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler+PM + db dpl3 + dd offset initial_debug_exception_handler+PM + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler+PM + db dpl3 + dd offset overflow_handler+PM + db dpl3 + dd offset bound_check_handler+PM + db dpl3 + dd offset invalid_opcode_handler+PM + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler+PM + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler+PM + db dpl0 + dd offset stack_exception_handler+PM + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler+PM + db dpl0 + dd offset alignment_check_handler+PM + db dpl0 + dd offset machine_check_exception+PM + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset in PM +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,linear_kernel_space_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + IF kernel_type EQ i486 ;---------------------------------------------- + + +multi_exception: + + +exception: + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + ; data segment + mov ecx,linear_space ; + mov edx,ds ; + CORNZ edx,ecx ; + mov edx,es ; + IFNZ edx,ecx ; + mov ds,ecx ; + mov es,ecx ; + ipost ; + ; + align 16 ; + FI ; + FI ; + + + ENDIF + + + + + IF kernel_type NE i486 ;---------------------------------------------- + + + +multi_exception: + + push ds + + +exception: + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + mov ecx,linear_space ; + CORNZ [esp+ip_ds],ecx ; + mov edx,es ; + IFNZ edx,ecx ; + mov [esp+ip_ds],ecx + mov es,ecx ; + ipost ; + FI ; + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + CANDNZ [ebp+small_as],0 + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + ENDIF + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea ebp,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[ebp+4] + mov bx,[ebp] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + cmp esp,max_kdebug_tcb + ja shutdown_thread + + + + +kd_exception: + + + mov ss:[esp+ip_code],al + + IF kernel_type NE i486 + pop ds + ENDIF + popad + add esp,4 + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov al,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcman4.asm b/l4-x86/l4-4test/kernel/ipcman4.asm new file mode 100644 index 0000000..a1ae733 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcman4.asm @@ -0,0 +1,2620 @@ +include l4pre.inc + + + Copyright GMD, L4.IPCMAN.4, 27,07,96, 158, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 27.07.96 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public cancel_ipc + public get_bottom_state + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources_ipc:near + extrn deallocate_resources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include schedcb.inc +include cpucb.inc +include pagconst.inc +.list +include msg.inc +.nolist +include syscalls.inc +.list + + + +ok_for i486 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + +.list + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + + + + + align 16 + + + + +send_intr: + + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + test [ebp+fine_state],nwait+nclos + IFPE + IFZ + CANDZ [ebp+waiting_for],edx + cmp [ebp+waiting_for+4],0 + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz short intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+PM + + + +transfer_intr: + + switch_thread int,ebx + + xor ebx,ebp + shr ebp,task_no + + test ebx,mask task_no + IFNZ + + switch_space + + FI + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + +.listmacroall + ipost +.nolistmacro + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest.high +; EDI dest.low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source.low +; EDI source.high +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + iretd + + + + + + +XHEAD deceit_pre + + test al,redirected + IFNZ + push eax + push ebp + + mov edi,[esp+iret_esp+(4+2)*4] + mov esi,[edi] + mov edi,[edi+4] + mov [ebx+virtual_sender],esi + mov [ebx+virtual_sender+4],edi + mov ah,al + call nchief + xor al,ah + cmp al,from_inner_clan + + pop ebp + pop eax + CANDZ + lea edi,[ebx+virtual_sender-offset myself] + xret + FI + + mov edi,ebx + and al,NOT deceit + xret + + + + + + + align 16 + + + + +ipc_sc: + + push eax + push ebx + + mov ebx,esp + and ebx,-sizeof tcb + + cmp eax,virtual_space_size-MB4 + jae receive_only + + and al,(NOT ipc_control_mask)+deceit+map_msg + + mov [ebx+waiting_for],esi + mov [ebx+waiting_for+4],edi + mov [ebx+rcv_descriptor],ebp + + cmp [ebx+chief],edi + xc nz,to_chief,long + + lea___tcb ebp,esi + + cmp [ebp+myself],esi + jnz ipc_dest_not_existent + cmp [ebp+chief],edi + jnz ipc_dest_not_existent + + mov edi,ebx + + test al,deceit + xc nz,deceit_pre + + test [ebp+fine_state],nwait+nclos + IFPE + IFZ + mov esi,[edi+myself] + CANDZ [ebp+waiting_for],esi + mov esi,[edi+chief] + cmp [ebp+waiting_for+4],esi + FI + jnz pending + FI + + + + cmp___eax deceit + xc a,ipc_long,long + + + + mov [ebp+fine_state],running + + mov edi,[ebx+rcv_descriptor] + + cmp edi,virtual_space_size + IF____xc ae,send_only + + ELSE__ + mov ch,closed_wait+nwake + test edi,nclos + IFNZ + mov ch,open_wait+nwake + test [ebx+list_state],is_polled + jnz fetch_next + FI + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout + mov [ebx+fine_state],ch + + mov edi,ebx + pop ebx + FI____ + + + switch_thread ipc,edi + + test al,deceit+redirected + xc nz,deceit_or_redirected_post + + mov esi,ebp + shr ebp,task_no + + xor esi,edi + test esi,mask task_no + + mov esi,[edi+myself] + mov edi,[edi+chief] + + IFNZ + + switch_space + + FI + + pop ebp + iretd + + + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop ebx + push offset send_ok_ret+PM + + test [edi+list_state],is_ready + xret nz + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret + + + +XHEAD deceit_or_redirected_post + + mov ecx,[edi+waiting_for] + mov esi,[edi+waiting_for+4] + mov [esp],esi + + test al,deceit + xret z + + add edi,offset virtual_sender-offset myself + xret + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub ch,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov ch,running + push eax + mark__ready ebx + pop eax + mov dword ptr [esp+4],offset receive_timeout_ret + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + + mov [ebx+fine_state],locked_running + mov [ebp+fine_state],locked_waiting + + and al,ipc_control_mask + + mov esi,[esp+4] + mov edi,[ebp+rcv_descriptor] + + and esi,NOT (deceit+map_msg) + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + CANDNZ ,,long + + + sub al,ipc_cut + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + + sti + + + push edx + + mov edx,edi + + mov ecx,ebx + xor ecx,ebp + test ecx,mask task_no + IFNZ + mark__ressource ebx,com_used + + and edi,-MB4 + sub edx,edi + add edx,offset com0_space + shr edi,20 + lea___pdir ecx,ebp + mov ecx,[edi+ecx] + and cl,NOT page_user_permit + mov dword ptr [ebx+waddr0],edi ; waddr1 := 0 is ok here + + sub edi,edi + mov ds:[pdir+(com0_base SHR 20)],ecx + mov ds:[pdir+(com0_base SHR 20)+4],edi + FI + + + mov ecx,eax + shr ecx,md_mwords + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + + cmp ecx,edi + xc a,shorten_mwords,long + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + lea edi,[edx+msg_w2] + cld ; overrun into kernel area + rep movsd ; prohibited by firewall PF + + +; push eax +; +; test ecx,ecx +; IFNZ +; mov eax,[edi+16] +; DO +; mov eax,[esi] +; mov [edi],eax +; add esi,4 +; add edi,4 +; dec cl +; test cl,11b +; REPEATNZ +; OD +; +; test ecx,ecx +; CANDNZ +; +; DO +; mov eax,[edi+16] +; +; mov eax,[esi] +; mov [edi],eax +; mov eax,[esi+4] +; mov [edi+4],eax +; mov eax,[esi+8] +; mov [edi+8],eax +; mov eax,[esi+12] +; mov [edi+12],eax +; +; add edi,16 +; add esi,16 +; sub ecx,16/4 +; REPEATA +; OD +; FI +; pop eax + + sub edi,edx + sub esi,edi + FI + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + cli + + unmrk_ressource ebx,com_used + + mov ecx,[ebx+timeouts] + pop edx + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + + push eax + push ebx + push edx + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+PM + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w2].snd_base + mov eax,[esi+msg_w2].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + shr edx,20 + cmp [ebx+waddr0],dx + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + cld ; overrun into kernel_area + rep movsd ; prohibited by firewall PF + mov cl,dl ; + rep movsb + + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + mov [ebx+waddr1],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z + test edx,edx + xret z + + mov edx,cr3 + mov cr3,edx + xret + + + + + + + + align 16 + + + +fetch_next: + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + mov eax,[ebx+waiting_for+4] ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+fine_state],locked_running + mov [ebx+fine_state],locked_waiting + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + test esi,esi + jz nil_dest_not_existent + + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + xret z,long + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + xret z,long + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + or al,redirected + test ebp,mask thread_no + xret z,long + FI + + or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + xret ,long + + + + + + + align 16 + + +pending: + + pop edi + ; eax ; already pushed + cmp ebx,ebp + jz short sw_err3 + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+waiting_for+4] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz short send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+PM + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + +ret_from_poll: + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + mov [ebp+fine_state],closed_wait + mov eax,[ebx+myself] + mov [ebp+waiting_for],eax + mov eax,[ebx+chief] + mov [ebp+waiting_for+4],eax + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + +receive_only: + + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebx,esp + and ebx,-sizeof tcb + + mov [ebx+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + mov [ebx+waiting_for+4],edi + + + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + IFNZ [ebx+chief],edi + call nchief + FI + + lea___tcb ebp,esi + + cmp [ebp+myself],esi + jnz short r_source_not_existent + cmp [ebp+chief],edi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + ;;;;; mark__ready ebp + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebx + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebx,esp + and ebx,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebx+myself] + mov edi,[ebx+chief] + + iretd + FI + + sub eax,eax + call nchief + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+waiting_for+4] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+waiting_for+4],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + ke '-pi_err' + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc / cancel ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; cancel ipc PRECONDITION: +; +; AL bottom state of thread +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + call get_bottom_state + + +cancel_ipc: + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+timeouts],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+PM] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {ebp,edx are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret + + ELIFZ al, ;Ž92-12-21.. + test [ebp+coarse_state],ndead + CANDNZ + mov dword ptr [ecx],offset send_ok_ret + + ELSE_ ;..Ž + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcman5-7-27.as5 b/l4-x86/l4-4test/kernel/ipcman5-7-27.as5 new file mode 100644 index 0000000..a84d054 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcman5-7-27.as5 @@ -0,0 +1,2863 @@ +include l4pre.inc + + + Copyright IBM, L4.IPCMAN.5, 25,07,97, 302, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for pentium + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX rcv descriptor +; EDX snd.w0 +; EBX snd.w1 +; EBP snd.w2 +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX msg.w2 +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = offset tcb_space + + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + mov edx,edi + and edi,mask thread_no + + mov [ebp+ipc_control],eax + jz receive_only + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],ecx + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + + test esi,esi + xc z,send_only + + xor edx,ss:[edi+ebp+myself+X] + xor ecx,ss:[edi+ebp+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+ebp+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+ebp+thread_state+X],ecx + mov ch,ss:[ebp+resources] + + or ecx,edx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov esp,ss:[edi+ebp+thread_esp+X] + xc nz,deallocate_resources_or_bad_segments + + mov edi,ss:[edi+ebp+thread_proot+X] + mov ebp,offset gdt + + test edi,edi + xc ns,switch_to_large_address_space + + mov dword ptr ss:[ebp+linear_space/8*8+4],edi + add edi,0FB00h-0F300h + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],edi + lea edi,[esp+sizeof tcb] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iret_vec+4] + + and edi,-sizeof tcb + mov byte ptr ss:[ebp+linear_space/8*8+1],ah + + mov byte ptr ss:[ebp+linear_space_exec/8*8+1],ah + mov ss:[ebp+cpu_esp0-offset gdt],edi + + mov ebp,linear_space + pop edi + + mov ds,ebp + + mov es,ebp + + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+ebp+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+esi+X] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcman5-8.as5 b/l4-x86/l4-4test/kernel/ipcman5-8.as5 new file mode 100644 index 0000000..44bf10e --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcman5-8.as5 @@ -0,0 +1,2857 @@ +include l4pre.inc + + + Copyright IBM, L4.IPCMAN.5, 25,07,97, 302, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for pentium + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX -ud- +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = 0 ; offset tcb_space + + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + mov ecx,edi + + and edi,mask thread_no + jz receive_only + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],esi + + add edi,offset tcb_space + push edx + + mov edx,ss:[ebp+chief] + mov esi,ss:[ebp+myself] + + xor ecx,ss:[edi+ebp+myself+X] + xor edx,ss:[edi+ebp+chief+X] + + or edx,ecx + xc nz,to_chief,long + + mov ch,ss:[ebp+resources] + mov edx,ss:[edi+ebp+thread_state] + + xor edx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + + +ipc_post: + + mov edx,fs + + or ecx,edx + xc nz,deallocate_resources_or_bad_fs + + mov ss:[edi+ebp+thread_state+X],ecx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + test ecx,ecx + xc z,send_only + + mov ss:[edi+ebp+thread_state+X],ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + mov ecx,ss:[edi+ebp+thread_proot+X] + mov ebp,offset gdt + + test ecx,ecx + xc ns,switch_to_large_address_space + + mov byte ptr ss:[ebp+linear_space/8*8+1],ch + mov byte ptr ss:[ebp+linear_space_exec/8*8+1],ch + + lea edi,[esp+iret_vec+4] + mov ch,0F3h + + mov dword ptr ss:[ebp+linear_space/8*8+4],ecx + mov ch,0FBh + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],ecx + mov ss:[ebp+cpu_esp0-offset gdt],edi + + mov ebp,gs + + add ebp,linear_space + pop edi + + mov ds,ebp + + mov es,ebp + + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_fs + + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + sub ecx,ecx + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,ecx + + mov ss:[ebp+cpu_cr3-offset gdt],ecx + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],ecx + + mov cr3,ecx + FI + + mov ecx,00CCFF00h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+esi+X] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcman5.as5 b/l4-x86/l4-4test/kernel/ipcman5.as5 new file mode 100644 index 0000000..fcdc2b0 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcman5.as5 @@ -0,0 +1,2893 @@ +include l4pre.inc + + + Copyright IBM, L4.IPCMAN.5, 25,07,97, 302, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for pentium + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX rcv descriptor +; EDX snd.w0 +; EBX snd.w1 +; EBP snd.w2 +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX msg.w2 +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = offset tcb_space + + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + + + mov edx,edi + and edi,mask thread_no + + mov [ebp+ipc_control],eax + jz receive_only + + +; push eax +; push ecx +; mov eax,80000000h +; bsf ecx,eax +; bsf ecx,eax +; add ecx,1 +; pop ecx +; pop eax + +; push eax +; extrn ktest0_stack:dword +; IFZ edx,offset ktest0_stack +; mov eax,dword ptr ds:[edx] +; mov edx,dword ptr ds:[edx+4] +; FI +; push eax +; push edx + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],ecx + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + +; pop edx +; pop eax +; pop eax + + test esi,esi + xc z,send_only,long + + xor edx,ss:[edi+ebp+myself+X] + xor ecx,ss:[edi+ebp+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+ebp+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+ebp+thread_state+X],ecx + + or ecx,edx + movzx edx,ss:[ebp+resources] + or ecx,edx + + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov esp,ss:[edi+ebp+thread_esp+X] + xc nz,deallocate_resources_or_bad_segments + + mov edi,ss:[edi+ebp+thread_proot+X] + mov ebp,offset gdt + + test edi,edi + xc ns,switch_to_large_address_space,long + + mov dword ptr ss:[ebp+linear_space/8*8+4],edi + add edi,0FB00h-0F300h + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],edi + lea edi,[esp+sizeof tcb] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iret_vec+4] + + and edi,-sizeof tcb +;;; mov byte ptr ss:[ebp+linear_space/8*8+1],ah + +;;; mov byte ptr ss:[ebp+linear_space_exec/8*8+1],ah + mov ss:[ebp+cpu_esp0-offset gdt],edi + + mov ebp,linear_space + pop edi + + mov ds,ebp + + mov es,ebp + + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+ebp+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + push linear_space ;;;;;;;;;;;;;; + pop ds ;;;;;;;;;;;;;;;;; + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+esi+X] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcman5x.as5 b/l4-x86/l4-4test/kernel/ipcman5x.as5 new file mode 100644 index 0000000..1d9388e --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcman5x.as5 @@ -0,0 +1,2855 @@ +include l4pre.inc + + + Copyright IBM, L4.IPCMAN.5, 25,07,97, 302, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for pentium + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX -ud- +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = offset tcb_space + +Y = (offset gdt - linear_space) + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + mov ecx,edi + + and edi,mask thread_no + jz receive_only + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],esi + + push edx + mov edx,ss:[ebp+chief] + + xor ecx,ss:[edi+ebp+myself+X] + xor edx,ss:[edi+ebp+chief+X] + + or edx,ecx + xc nz,to_chief,long + + mov edx,ss:[edi+ebp+thread_state] + mov esi,ss:[ebp+myself] + + xor ecx,edx + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + + +ipc_post: + + mov edx,fs + + mov ecx,gs + + mov ch,ss:[ebp+resources] + mov ss:[edi+ebp+thread_state+X],edx + + or ecx,edx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov ss:[edi+ebp+thread_state+X],ecx + xc nz,deallocate_resources_or_bad_segments + + test ecx,ecx + xc z,send_only + + mov esp,ss:[edi+ebp+thread_esp+X] + mov ecx,ss:[edi+ebp+thread_proot+X] + + mov ebp,linear_space + lea edi,[esp+iret_vec+4] + + test ecx,ecx + xc ns,switch_to_large_address_space + + mov byte ptr ss:[ebp+linear_space/8*8+1+Y],ch + mov byte ptr ss:[ebp+linear_space_exec/8*8+1+Y],ch + + mov ss:[ebp+cpu_esp0-offset gdt+Y],edi + mov ch,0F3h + + mov dword ptr ss:[ebp+linear_space/8*8+4+Y],ecx + mov ch,0FBh + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4+Y],ecx + pop edi + + mov ds,ebp + + mov es,ebp + + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + sub ecx,ecx + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,ecx + + mov ss:[ebp+cpu_cr3-offset gdt+Y],ecx + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt+Y],ecx + + mov cr3,ecx + FI + + mov ecx,00CCFF00h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+esi+X] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcmank6-edi.as5 b/l4-x86/l4-4test/kernel/ipcmank6-edi.as5 new file mode 100644 index 0000000..1b2c081 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcmank6-edi.as5 @@ -0,0 +1,2911 @@ +include l4pre.inc + + + Copyright GMD, L4.IPCMAN.K6, 15,03,97, 202, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for k6 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX rcv descriptor +; EDX snd.w0 +; EBX snd.w1 +; EBP snd.w2 +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX msg.w2 +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + +X = 0 + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + jmp ipc_ + + + + +std_eflags equ (1 SHL i_flag)+(1 SHL r_flag) + + +ipc_syscall: + + mov ebp,ss:[cpu_esp0] + + mov ss:[ebp-20].iret_eip,ecx + mov ss:[ebp-20].iret_esp,esp + + mov ecx,esp + + mov esp,ds:[ecx] + mov ecx,ds:[ecx+4] + + mov dword ptr ss:[ebp-20].iret_cs,linear_space_exec + mov dword ptr ss:[ebp-20].iret_eflags,std_eflags + mov dword ptr ss:[ebp-20].iret_ss,linear_space + + mov ss:[ebp-20-4],esp + mov ss:[ebp-20-8],edx + + lea esp,[ebp-20-8] + + and ebp,-sizeof tcb + + + + + +ipc_: + + + mov edx,edi + and edi,mask thread_no + jz receive_only + add edi,offset tcb_space + + mov [ebp+ipc_control],eax + + mov ss:[ebp+rcv_descriptor],ecx + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + + test esi,esi + xc z,send_only + + xor edx,ss:[edi+myself+X] + xor ecx,ss:[edi+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+thread_state+X],ecx + mov ch,ss:[ebp+resources] + + or ecx,edx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov esp,ss:[edi+thread_esp+X] + xc nz,deallocate_resources_or_bad_segments + + mov edi,ss:[edi+thread_proot+X] + mov ebp,offset gdt + + test edi,edi + xc ns,switch_to_large_address_space + + mov dword ptr ss:[ebp+linear_space/8*8+4],edi + add edi,0FB00h-0F300h + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],edi + lea edi,[esp+sizeof iret_vec+4] + + mov ss:[ebp+cpu_esp0-offset gdt],edi + mov edi,linear_space + + mov ds,edi + +; mov es,edi + + pop edi +; and eax,ipc_control_mask + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,ss:[edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+edi+offset tcb_space] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov [ebp+ipc_control],eax + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +k6_extended_feature_enable equ 0C0000080h +k6_syscall_target_address equ 0C0000081h + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + + mov ecx,k6_extended_feature_enable + rdmsr + bts eax,0 + wrmsr + + mov ecx,k6_syscall_target_address + mov edx,linear_kernel_space_exec + mov eax,offset ipc_syscall+PM + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcmank6-orig.as5 b/l4-x86/l4-4test/kernel/ipcmank6-orig.as5 new file mode 100644 index 0000000..a058ab2 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcmank6-orig.as5 @@ -0,0 +1,2912 @@ +include l4pre.inc + + + Copyright GMD, L4.IPCMAN.K6, 15,03,97, 202, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for k6 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX rcv descriptor +; EDX snd.w0 +; EBX snd.w1 +; EBP snd.w2 +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX msg.w2 +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = offset tcb_space + + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + jmp ipc_ + + + + +std_eflags equ (1 SHL i_flag)+(1 SHL r_flag) + + +ipc_syscall: + + mov ebp,ss:[cpu_esp0] + + mov ss:[ebp-20].iret_eip,ecx + mov ss:[ebp-20].iret_esp,esp + + mov ecx,esp + + mov esp,ds:[ecx] + mov ecx,ds:[ecx+4] + + mov dword ptr ss:[ebp-20].iret_cs,linear_space_exec + mov dword ptr ss:[ebp-20].iret_eflags,std_eflags + mov dword ptr ss:[ebp-20].iret_ss,linear_space + + mov ss:[ebp-20-4],esp + mov ss:[ebp-20-8],edx + + lea esp,[ebp-20-8] + + and ebp,-sizeof tcb + + + + + +ipc_: + + + mov edx,edi + and edi,mask thread_no + + mov [ebp+ipc_control],eax + jz receive_only + + sub edi,ebp + mov ss:[ebp+rcv_descriptor],ecx + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + + test esi,esi + xc z,send_only + + xor edx,ss:[edi+ebp+myself+X] + xor ecx,ss:[edi+ebp+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+ebp+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+ebp+thread_state+X],ecx + mov ch,ss:[ebp+resources] + + or ecx,edx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov esp,ss:[edi+ebp+thread_esp+X] + xc nz,deallocate_resources_or_bad_segments + + mov edi,ss:[edi+ebp+thread_proot+X] + mov ebp,offset gdt + + test edi,edi + xc ns,switch_to_large_address_space + + mov dword ptr ss:[ebp+linear_space/8*8+4],edi + add edi,0FB00h-0F300h + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],edi + lea edi,[esp+sizeof iret_vec+4] + + mov ss:[ebp+cpu_esp0-offset gdt],edi + mov edi,linear_space + + mov ds,edi + +; mov es,edi + + pop edi +; and eax,ipc_control_mask + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+ebp+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+edi+offset tcb_space] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+offset tcb_space] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +k6_extended_feature_enable equ 0C0000080h +k6_syscall_target_address equ 0C0000081h + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + + mov ecx,k6_extended_feature_enable + rdmsr + bts eax,0 + wrmsr + + mov ecx,k6_syscall_target_address + mov edx,linear_kernel_space_exec + mov eax,offset ipc_syscall+PM + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/ipcmank6.as5 b/l4-x86/l4-4test/kernel/ipcmank6.as5 new file mode 100644 index 0000000..a3fbc1b --- /dev/null +++ b/l4-x86/l4-4test/kernel/ipcmank6.as5 @@ -0,0 +1,2914 @@ +include l4pre.inc + + + Copyright GMD, L4.IPCMAN.K6, 15,03,97, 202, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 22.07.90 ****** +;****** modified: 15.03.97 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_resources:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_or_grant_fpage:near + extrn irq0_intr:abs + extrn irq15:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include perfmon.inc +.list + + +ok_for k6 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+resources],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+resources],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+resources],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+resources],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+resources-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+resources],NOT is_polled + or [edi+resources],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + + + ; align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + ; align 8 + +intr_&irq: + push eax + mov al,irq + jmp short send_intr + + endm + + +.list + + + + + ; align 16 + + + +send_intr: + + ke 'INTR' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ecx + push edx + + push ebx + push ebp + + and eax,0FFh + mov ebp,offset intr_associated_tcb + + push esi + push edi + + mov ebp,ss:[(eax*4)+ebp] + mov edx,esp + + and edx,-sizeof tcb + add eax,40h + + mov ebx,ss:[ebp+thread_state] + mov ecx,eax + + xor eax,ebx + jg intr_pending + + mov ss:[ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + mov edi,ebp + mov ebp,edx + + and edi,mask thread_no + + sub edi,ebp + + cmp edx,dispatcher_tcb + IF____xc z,intr_while_dispatching + + ELSE__ + mark__interrupted ebp + push offset switch_from_intr+PM + FI____ + + + push ecx + sub ebx,ebx + + push ebx + mov esi,ecx + + sub eax,eax + jmp ipc_post + + + + + +XHEAD intr_while_dispatching + + mov ebp,ss:[cpu_esp0] ;;;;;;;;;; no longer correct + mov edi,edx + + and ebp,-sizeof tcb + and edi,mask thread_no + + mov esp,[ebp+thread_esp] + sub edi,ebp + xret + + ;; pop eax + ;; + ;; sub eax,eax ;;; + ;; mov ebx,eax ; + ;; mov esi,edx ; + ;; mov edi,ebx ; + ;; ; + ;; iretd ; + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + IFZ [ebp+thread_state],ready + CANDNZ ebp,edx + CANDNZ edx,dispatcher_tcb + + mov edi,ebp + mov ebp,edx + + mark__interrupted ebp + + push offset switch_from_intr+PM + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + lea eax,[esp+sizeof iret_vec+7*4] + mov ebp,offset cpu_esp0 + + pop edi + pop esi + + mov ss:[ebp],eax + pop ebp + + pop ebx + pop edx + + pop ecx + pop eax + + iretd + + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX rcv descriptor +; EDX snd.w0 +; EBX snd.w1 +; EBP snd.w2 +; ESI source +; EDI dest +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX completion code +; ECX msg.w2 +; EDX msg.w0 +; EBX msg.w1 +; EBP -ud- +; ESI source +; EDI -ud- / true dest +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + +X = 0 ; offset tcb_space + + + +ipc_sc: + + + push ebp + mov ebp,-sizeof tcb + + and ebp,esp + push edx + + jmp ipc_ + + + + +std_eflags equ (1 SHL i_flag)+(1 SHL r_flag) + + +ipc_syscall: + + mov ebp,ss:[cpu_esp0] + + mov ss:[ebp-20].iret_eip,ecx + mov ss:[ebp-20].iret_esp,esp + + mov ecx,esp + + mov esp,ds:[ecx] + mov ecx,ds:[ecx+4] + + mov dword ptr ss:[ebp-20].iret_cs,linear_space_exec + mov dword ptr ss:[ebp-20].iret_eflags,std_eflags + mov dword ptr ss:[ebp-20].iret_ss,linear_space + + mov ss:[ebp-20-4],esp + mov ss:[ebp-20-8],edx + + lea esp,[ebp-20-8] + + and ebp,-sizeof tcb + + + + + +ipc_: + + + mov [ebp+ipc_control],eax + mov ss:[ebp+rcv_descriptor],ecx + + mov edx,edi + and edi,mask thread_no + + jz receive_only + + add edi,offset tcb_space + sub edi,ebp + + mov ss:[ebp+thread_state],esi + mov ecx,ss:[ebp+chief] + + test esi,esi + xc z,send_only + + xor edx,ss:[edi+ebp+myself+X] + xor ecx,ss:[edi+ebp+chief+X] + + or edx,ecx + IF____xc nz,to_chief,long + + ELSE__ + mov esi,ss:[ebp+myself] + mov ecx,ss:[edi+ebp+thread_state+X] + + xor ecx,esi + jg pending ; S or Z => ok, not pending (note xor: ov=0) + + test al,al + xc nz,complex_ipc,long + FI____ + + +ipc_post: + + mov ecx,gs + + mov edx,fs + + mov ss:[edi+ebp+thread_state+X],ecx + mov ch,ss:[ebp+resources] + + or ecx,edx + pop edx + + mov ss:[ebp+thread_esp],esp + pop ecx + + mov esp,ss:[edi+ebp+thread_esp+X] + xc nz,deallocate_resources_or_bad_segments + + mov edi,ss:[edi+ebp+thread_proot+X] + mov ebp,offset gdt + + test edi,edi + xc ns,switch_to_large_address_space + + mov dword ptr ss:[ebp+linear_space/8*8+4],edi + add edi,0FB00h-0F300h + + mov dword ptr ss:[ebp+linear_space_exec/8*8+4],edi + lea edi,[esp+sizeof iret_vec+4] + + mov ss:[ebp+cpu_esp0-offset gdt],edi + mov edi,linear_space + + mov ds,edi + + mov es,edi + + pop edi +; and eax,ipc_control_mask + + iretd + + + + + +XHEAD send_only + + pop esi + pop ecx + + push offset send_ok_ret+PM + push ecx + + push esi + mov ecx,ss:[ebp+chief] + + test ss:[ebp+list_state],is_ready + xret nz,long + + IFDEF ready_llink + call insert_into_ready_list + ELSE + lins__ss ebp,esi,ready + ENDIF + xret ,long + + + + +XHEAD deallocate_resources_or_bad_segments + + mov esp,ss:[ebp+thread_esp] + + mov byte ptr ss:[edi+ebp+thread_state+X],0 ; repairing state, must be 0 + test ch,is_polled + + mov ecx,edi + IFNZ + cmp [ebp+thread_state],0 + jg fetch_next + FI + + lea edi,[ebp+edi+X] + call deallocate_resources + + mov edi,ecx + + pop ecx + mov esp,ss:[edi+ebp+thread_esp+X] + + xret ,long + + + +XHEAD switch_to_large_address_space + + IFNZ ,edi + + mov ss:[ebp+cpu_cr3-offset gdt],edi + mov dword ptr ss:[ebp+tlb_invalidated-offset gdt],edi + + mov cr3,edi + FI + + mov edi,00CCF300h + xret ,long + + + + + + +send_ok_ret: + + sub eax,eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; Complex IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; EBP current tcb address +; ESI myself +; EDI dest tcb address - EBP - offset tcb_space +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state source +; +; [ESP] snd.w0 +; [ESP+4] snd.w2 +; +; SS linear kernel space +; DS linear space (!) +; +;---------------------------------------------------------------------------- +; +; POSTCONDITION = PRECONDITION +; +;---------------------------------------------------------------------------- + + + +XHEAD complex_ipc + + mov ecx,eax + mov edx,eax + + and eax,ipc_control_mask + IFNZ + + mov edx,ss:[ebp+thread_state] + push edi + + mov ss:[ebp+thread_state],ready + lea ebp,[ebp+edi+X] + + push edx + test al,mem_msg+deceit + + mov ss:[ebp+thread_state],locked + xc nz,mem_or_deceit_pre,long + + mov edi,[ebp+rcv_descriptor] + push linear_kernel_space + + pop ds + + test al,map_msg + IF____xc nz,ipc_map,long + ELSE__ + test al,mem_msg + xc nz,ipc_mem,long + FI____ + + mov ebp,esp + pop ecx + + and ebp,-sizeof tcb + pop edi + + nop + nop + + mov edx,[ebp+ipc_control] + mov [ebp+thread_state],ecx + + mov ecx,edx + mov esi,[ebp+myself] + FI + + shr cl,4 + xret z,long + + + + +enter_receive_timeout: + + + and edx,0FF000000h + add cl,2 + + shr edx,cl + mov ch,wakeup_active + + shr edx,cl + IFNZ + + mov [ebp+aux_state],ch + add edx,ss:[system_clock_low] + + mov [ebp+wakeup_low],edx + + cmp cl,5+2 + xret le,long + + movi edx, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edx,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edx,cl + xret ,long + FI + + + mark__ready ebp + xret ,long + + + + + + + + +;------------------------------------------------------------- +; +; IPC MAP +; +;------------------------------------------------------------- +; PRECONDITION: +; +; EAX control word +; ECX -ud- +; EDX -ud- +; EBX snd.w1 +; ESI snd vector address / -ud- +; EDI rcv fpage +; EBP dest tcb address +; +; tcb.ipc_control control word +; tcb.rcv_descriptor rcv descriptor +; tcb.thread_state ready +; +; [ESP] -ud- +; [ESP+1*4] -ud- +; [ESP+2*4] snd.w0 +; [ESP+3*4] snd.w2 +; +; DS linear kernel space +; +;-------------------------------------------------------------- + + + +XHEAD ipc_map + + + test edi,map_msg + IFNZ + mov edx,ebp ; + xor edx,esp ; + and edx,mask task_no ; ignore intra-task mapping + CANDNZ + + mov edx,[esp+2*4] + + push eax + push ebx + call map_or_grant_fpage + pop ebx + pop eax + + test al,mem_msg + xret z,long + + push ebx + mov ecx,[esi+msg_dope] + + shr ecx,md_mwords + DO + test al,ipc_error_mask + EXITNZ + add esi,sizeof fpage_vector + sub ecx,sizeof fpage_vector/4 + EXITBE + + push ecx + mov edx,[esi+msg_w2-sizeof fpage_vector].snd_base + mov ebx,[esi+msg_w2-sizeof fpage_vector].snd_fpage + push eax + call map_or_grant_fpage + pop eax + pop ecx + REPEAT + OD + pop ebx + ELSE_ + add al,ipc_cut + FI + + xret ,long + + + + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + + + + + +XHEAD mem_or_deceit_pre + + ke 'y';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + push ebp + + mov esi,ss:[esp+iret_esp+(4+2+1)*4] + mov esi,ds:[esi] + mov ss:[ebp+virtual_sender],esi + call nchief + + pop ebp + xret ,long + + + + + + + + + + + + + + align 16 + + + + +XHEAD ipc_mem + + + mov esi,eax + and al,ipc_control_mask + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + nop + IFNZ + mov bl,al + mov eax,[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg + IFZ ,,long + + test eax,mask md_mwords-(2 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + mov [ebx+com_partner],ebp + + mov [ebx+aux_state],ipc_mem_active + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w2 + nop + + mov eax,[ebp+task_pdir] + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w2] + + mov edi,[edx+32] + lea edi,[edx+msg_w2] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + unmrk_ressource ebx,com_used + + cli + + mov [ebx+aux_state],0 + + FI + + xret ,long + + + + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w2 + IFB_ + add esi,eax + xret ,long + FI + + mov eax,[ebx+task_pdir] + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 +;; mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w2] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w2] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + mov esi,[esi+str_addr] + mov edi,[edi+buf_addr] + + push eax + push ebx + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base +;;;;;;;; lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + push linear_kernel_space + pop ds + + mov ebx,ebp + lea ebp,[ebp+edi+offset tcb_space] + + + mov esi,[ebx+myself] + mov edi,[ebx+chief] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + mov edi,[ebx+virtual_sender+4] + FI + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+thread_state] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp (scratch); + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+PM + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + mov [edx+thread_state],ready + mov [ebx+com_partner],edx + mov [ebx+thread_state],locked + + mov ebp,ebx + mov edi,edx + + jmp switch_context + + FI + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop edx + pop ebx + pop ebp + iretd + + + + + align 16 + + +XHEAD to_chief + + ke 'z';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + test esi,esi + jz nil_dest_not_existent + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + xor ebp,edi + xor ebp,esi + test ebp,mask task_no + EXITZ + + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + or ebp,NOT mask depth + sub ebp,[ebx+chief] + CANDNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + ;; or al,redirected + test ebp,mask thread_no + EXITZ + FI + + ;; or al,redirected+from_inner_clan + mov ebp,[ebx+chief] + lea___tcb ebp,ebp + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + OD + + lea___tcb ebp,esi + + xret ,long + + + + + align 16 + + +pending: + + test esi,esi + pop ecx + + pop esi + jz sw_err3 + + test eax,0F0h + IFNZ + test eax,000FF0000h + jz send_timeout_ret + FI + + push linear_kernel_space + pop ds + + push eax ; eax ; + push ss:[ebp+rcv_descriptor] ; ecx ; + push ecx ; edx ; + push ebx ; ebx ; + + mov ebx,ebp + lea ebp,[ebp+edi+X] + + push ebx ; temp (esp) ; + push esi ; ebp ; + mov esi,[ebx+thread_state] ; ; + xor edx,[ebp+myself] ; + push esi ; esi ; + push edx ; edi ; + + + mov [ebx+com_partner],ebp + mov ecx,eax + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + mov [ebx+thread_state],polling + + call wait_for_ipc_or_timeout + + + + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+thread_state],ready + + mov eax,[ebx+myself] + mov [ebp+thread_state],eax + + popad + jmp ipc_sc + + FI + + IFZ [ebx+thread_state],polling + mov ebp,ebx + delete_from_sndq + mov [ebx+thread_state],ready + FI + + popad + + + +send_timeout_ret: + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + +sw_err3: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + + push linear_kernel_space + pop ds + + mov ebx,ebp + + pop edx + + cmp ecx,virtual_space_size + jae w_err + + mov [ebx+rcv_descriptor],ecx + + + cmp esi,waiting_any + jnz receive_from + + test [ebx+resources],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+thread_state],locked + mov [ebx+com_partner],edx + mov [edx+thread_state],ready + mov [edx+com_partner],ebx + mov ebp,ebx + mov edi,edx + jmp switch_context + + FI + + + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov [ebp+thread_state],esi + + and cl,0Fh + IFNZ + mov edi,ecx + and edi,0FF000000h + jz short receive_timeout_ret + FI + + + +wait_for_ipc_or_timeout: + + IFNZ + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + or [ebx+aux_state],wakeup_active + + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + cmp [ebp+thread_state],ready + mov edi,ebp + mov ebp,ebx + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + pop eax + + and ebp,-sizeof tcb + + movi eax,ready + mov [ebp+thread_state],eax + + mov al,ipc_timeout ; eax<8..31> = 0 + + iretd + + + + align 16 + + +received_ok_ret: + + popad + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test esi,esi + IFNZ + test_intr_in_sndq ebx + + IFC + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + pop eax + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + + add esi,waiting_none + jmp wait_for_receive_or_timeout + + FI + + lea___tcb ebp,esi + mov edi,[ebx+chief] + IFNZ [ebp+chief],edi + call nchief + lea___tcb ebp,esi + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + mov [ebx+thread_state],esi + + IFZ [ebp+thread_state],polling + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+thread_state],ready + mark__ready ebp + mov [ebx+thread_state],locked + mov [ebx+com_partner],ebp + + mov edi,ebp + mov ebp,ebx + + jmp switch_context + + FI + + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread (low) / 0 +; EDI thread (high) / undef +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself (low) +; EDI myself (high) +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief (low) thread (low) +; EDI chief (high) thread (high) +; +; ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + mov edi,[ebp+chief] + + iretd + FI + + mov ebx,ebp + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + align 16 + + +nchief: + + mov al,0 + + DO + mov ebp,[ebx+chief] + xor ebp,edi + test ebp,mask site_no + IFZ + + mov ebp,[ebx+chief] + xor ebp,esi + test ebp,mask task_no + EXITZ + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask task_no + EXITZ + + mov ebp,edi + sub ebp,[ebx+chief] + IFNC + shr ebp,32 - width depth + CANDA ebp,1 + dec ebp + DO + lea___tcb edi,edi + mov esi,[edi+myself] + mov edi,[edi+chief] + dec ebp + REPEATNZ + OD + mov ebp,[ebx+myself] + xor ebp,edi + test ebp,mask thread_no + IFZ + ;; mov al,redirected+from_inner_clan + ret + FI + FI + FI + + mov esi,[ebx+chief] + lea___tcb ebp,esi + mov esi,[ebp+myself] + mov edi,[ebp+chief] + ;; mov al,redirected + OD + + ret + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'ready' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + movi eax,ready + xchg eax,[ebp+thread_state] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+ipc_control] + push eax + mov al,[ebp+state_sp] + push eax + + mov eax,esp + shr eax,2 + mov [ebp+state_sp],al + + mov ecx,[ebp+com_partner] +;; test [ebp+fine_state],nrcv +;; mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al +;; mov [ebp+fine_state],ah + shr eax,8 +;; mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+thread_state],eax + pop eax + mov [ebp+com_partner],eax + +;; test [eax+fine_state],nlock + IFZ + CANDZ [eax+com_partner],ebp + + jmp edi + FI + + + ke '-pi_err' + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,ready + ret + FI + + mov eax,[ebp+thread_state] + ret + FI + + ke 'complex_get_bottom_state' + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + IFZ [ebp+thread_state],polling + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + IFNZ eax,locked + test [ebp+aux_state],ipc_mem_active + CANDZ + IFNZ eax,ready + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof iret_vec-2*4] + IFZ [ebp+thread_state],ready + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+thread_state],ready + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'ready', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + ke 'adopt_ifc_ebp_ebx' + + ;; test [ebp+fine_state],nlock + IFNZ + push eax + push ecx + push edi + + ;; test [ebp+fine_state],npoll + IFZ + delete_from_sndq + ELSE_ + mov edi,[ebp+thread_esp] + sub edi,4 + mov [ebp+thread_esp],edi + mov dword ptr [edi],offset receive_timeout_ret + FI + ;; mov [ebp+fine_state],running + mark__ready ebp + + pop edi + pop ecx + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + ;; test [ebp+fine_state],npoll + ;; IFZ + ;; call enforce_restart_poll + ;; FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov eax,[ebp+thread_state] + + IFZ eax,polling + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+resources],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + ke 'no' +;; lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + +;; mov al,running +;; xchg [ebp+fine_state],al + +;; test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC ;Ž92-12-08 + sub esi,esi + FI + mov [ebp+ipc_control],esi ;..Ž + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0_P2 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + mov eax,offset intr_1 - offset intr_0 + imul eax,ecx + add eax,offset intr_0 + PM + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + + +;---------------------------------------------------------------------------- +; +; V2 IPC emulator +; +;---------------------------------------------------------------------------- + + +ipc_v2_sc: + + mov edi,esi + IFAE eax,virtual_space_size + sub edi,edi + sub eax,eax + ELSE_ + test eax,NOT 11b + IFNZ + ke 'v2_ipc_mem' + FI + FI + + test ebp,1 + IFNZ + dec ebp + mov esi,waiting_any + FI + + ror ecx,16 + shr ch,2 + shr cx,2 + rol ecx,16 + + or eax,ecx + mov ecx,ebp + + int ipc3 + + lea___tcb ebp,esi + + lea edi,[esp+sizeof iret_vec] + mov ss:[cpu_esp0],edi + + mov edi,ss:[ebp+chief] + + iretd + + + + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +k6_extended_feature_enable equ 0C0000080h +k6_syscall_target_address equ 0C0000081h + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc3 + mov eax,offset ipc_sc+PM + call define_idt_gate + + mov bl,ipc + mov eax,offset ipc_v2_sc+PM + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+PM + call define_idt_gate + + + mov ecx,k6_extended_feature_enable + rdmsr + bts eax,0 + wrmsr + + mov ecx,k6_syscall_target_address + mov edx,linear_kernel_space_exec + mov eax,offset ipc_syscall+PM + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/kdebug.asm b/l4-x86/l4-4test/kernel/kdebug.asm new file mode 100644 index 0000000..935cc46 --- /dev/null +++ b/l4-x86/l4-4test/kernel/kdebug.asm @@ -0,0 +1,4162 @@ +include l4pre.inc + + + dcode + + Copyright GMD, L4.KDEBUG, 01,01,97, 200 + + +;********************************************************************* +;****** ****** +;****** L4 Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** created: 26.03.91 ****** +;****** modified: 16.07.96 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include syscalls.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include pnodes.inc +include l4kd.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + +;94-11-15 jl new: no remote kdebug io before '+' char received remote + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn init_debug_screen:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + IF kernel_type EQ i486 + additional_kd_save_area_size equ 8 + ELSE + additional_kd_save_area_size equ 4 + ENDIF + + +kd_save_area struc + + kd_es dw 0,0 + kd_ds dw 0,0 + +kd_save_area ends + + + + + +kdpre macro + + push 0 + pushad + push ds + push es + + endm + + + +kdpost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + + + + + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_ko_flag db false +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + +page_fault_prot_state db 0 +ipc_prot_state db 0 + +niltext db 0 + + align 4 + +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh + + +page_fault_handler dd 0 + +ipc_handler dd 0 + + +timer_intr_handler dd 0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + db 'HISTORY:' +history dd 32 dup (0) + db ':END' +history_pointer dd offset history+PM + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + mov ebx,[ebx*4+kdebug_io_call_tab] + IFA esp, + add ebx,PM + FI + call ebx + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + call outdec + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + + kdpre + + lea ebp,[esp+additional_kd_save_area_size] + + + IFAE ebp, + push phys_mem + pop ds + FI + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,[ebp+ip_code] + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + and ebx,NOT PM + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_code],debug_exception + mov eax,dr7 + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'L4 Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'L4 Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'h' + IFNZ + cmp al,'g' + FI + jz exit_kdebug + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I' + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'v' + call virtual_address_info + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'T' + call tracing_on_off + ELIFZ al,' ' + call out_id_text + ELIFZ al,'*' + call init_debug_screen + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELSE_ + call out_help + FI + OD + REPEAT + OD + +exit_kdebug: + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'L4KD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'L4KD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[esp] + and eax,PM + mov eax,cs:[eax+kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + kd____disp <13,10,'a : all modules, axxxx : find module and rel addr'> + kd____disp <13,10,'b : show bkpnt, bi/w/a : set instr/wr/rdwr bkpnt'> + kd____disp <13,10,' b-/t/x : reset/strict bkpnt (thr/adr)'> + kd____disp <13,10,'t : current tcb, txxxxx : tcb of thread xxxx'> + kd____disp <13,10,' txxx.yy : task xxx, lthread yy'> + kd____disp <13,10,'d : dump mem, dxxxxxxxx : dump memory'> + kd____disp <13,10,'p : dump ptab, pxxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' pxxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings, mxxxx : mappings of frame xxxx'> + kd____disp <13,10,'k : display kernel data'> + kd____disp <13,10,'P : page fault prot P+ : on, P-: off, P* : on,running'> + kd____disp <13,10,'X : monit exception X+ xx [yyyy,zzzz]: on, X-: off'> + kd____disp <13,10,'I : ipc prot I+ : on, I-: off, I* : on,running'> + kd____disp <13,10,'R : kdebug activation by remote ESC'> + kd____disp <13,10,'i : in port i1/2/4xxxx: byte/word/dword'> + IF kernel_type NE i486 + kd____disp <13,10,' apic ia/i/xxxx : apic/io apic'> + ENDIF + kd____disp <13,10,'o : out port/apic o...'> + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'T : single step T+ : on, T-: off'> + kd____disp <13,10,'V : video mode a:automatic, c:cga, m:monochrom, h:hercules'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + IFZ al,'T' + call kd_outchar + mov eax,2F8h SHL 12 + 7 SHL 8 + 3 + call set_remote_info_mode + ELIFZ al,'-' + call kd_outchar + sub eax,eax + call set_remote_info_mode + + ELSE_ + push eax + kd____outchar + pop eax + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____outchar + call exit_kdebug + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+thread_state],dead + + DO + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + cmp word ptr [esi+8],'C(' + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + cmp word ptr [esi+8],'C(' + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + cmp word ptr [esi+8],'C(' + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + mov al,' ' + kd____disp <' (C) '> + + lea ebx,[esi+8+3] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <' '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov dr6,eax + mov [bx_size],al + mov [debug_exception_ko_flag],false + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + cmp al,'a' + setz cl + lea ecx,[(ecx*2)+1] + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'x',long + kd____outchar + kd____inchar + sub al,'0' + CORBE + CORZ al,3 + IFA al,4 + mov [bx_size],0 + mov al,'-' + kd____outchar + ret + FI + + mov [bx_size],al + add al,'0' + kd____outchar + kd____disp <' monit:'> + kd____inhex32 + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____outchar + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____outchar + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + IFZ al,'k' + kd____outchar + mov [debug_exception_ko_flag],true + ret + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ cs:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ cs:[breakpoint_thread+PM],0 + cmp cs:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + IFA esp,max_physical_memory_size + + push eax + push ebx + + mov ebx,ss:[history_pointer+PM] + mov eax,[esp+iret_eip+2*4] + mov ss:[ebx],eax + + add ebx,4 + IFAE ebx, + mov ebx,offset history+PM + FI + mov ss:[history_pointer+PM],ebx + sub eax,eax + mov ss:[ebx],eax + + pop ebx + pop eax + FI + + + call check_monitored_data + IFNZ + iretd + FI + + + + IFZ cs:[debug_exception_ko_flag+PM],true + pushad + kd____disp <13,10,'#DB:'> + lno___thread eax,esp + kd____outhex16 + popad + bts [esp+iret_eflags],r_flag + iretd + FI + jmp cs:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFAE esp,,long + CANDB esp,,long + CANDNZ ss:[bx_size+PM],0,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELSE_ + mov eax,ss:[ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + lea ebx,[esi+myself] + call show_thread_id + + kd____disp <' Chief: '> + mov eax,[esi+chief] + lno___thread eax,eax + kd____outhex16 + + + IFNZ [esi+resources],0 + kd____disp <6,0,53,'resrc: '> + mov al,[esi+resources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + + mov ebx,[esi+thread_state] + IFZ ebx,ready + kd____disp <'ready'> + ELIFZ ebx,dead + kd____disp <'dead'> + ELIFZ ebx,locked + kd____disp <'lock'> + ELIFZ ebx,polling + kd____disp <'poll'> + ELSE_ + kd____disp <'wait '> + IFZ ebx,waiting_inner + kd____disp <'inner'> + ELIFZ ebx,waiting_outer + kd____disp <'outer'> + ELIFZ ebx,waiting_none + kd____disp <'none'> + ELIFZ ebx,waiting_any + kd____disp <'any'> + ELSE_ + lea ebx,[esi+thread_state] + call show_thread_id + FI + FI + + show <6,1,53,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' ipc contr: '>,ipc_control + + show <6,3,60,' partner: '>,com_partner + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + kd____outhex32 + + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + + show <6,7,28, 'pdir: '>,task_pdir + mov eax,[esi+task_pdir] + IFNZ eax,[esi+thread_proot] + show <6,8,28, 'proot: '>,thread_proot + FI + IFNZ [esi+small_as],0 + show <6,9,28, 'small: '>,small_as + FI + + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,50, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,50, 'ready link: '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,50, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,50, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,50, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + push eax + kd____outhex16 + mov al,' ' + kd____outchar + pop eax + + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + mov al,'-' + kd____outchar + + push ebx + mov eax,[ebx] + mov ebx,eax + and eax,mask ver0 + shr ebx,ver1 + shl ebx,ver0 + add eax,ebx + kd____outhex16 + pop ebx + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + IFZ esi,ebp + call $+5 + pop eax + and eax,PM + mov eax,cs:[eax+kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + cmp al,20h + EXITAE + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + call $+5 + pop eax + and eax,PM + IFZ ebp,cs:[eax+kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-additional_kd_save_area_size].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-additional_kd_save_area_size].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ + mov eax,ss + CANDZ eax,linear_kernel_space + kd____disp <' Gdt/Idt/Task/Linktab/Pnodes? '> + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + ELIFZ al,'l' + mov eax,ss:[linktab_base] + ELIFZ al,'p' + mov eax,ss:[free_pnode_root] + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + +display_ptabs: + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + shl eax,task_no + add eax,offset tcb_space + test__page_present eax + pop ds + CANDNC + mov eax,ss:[eax+task_pdir] + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + mov eax,esi + shr eax,log2_pagesize + imul eax,linksize + add eax,ss:[linktab_base] + mov eax,ss:[eax].pmap_link + test eax,eax + IFZ + mov al,'-' + kd____outchar + REPEAT + FI + push esi + push edi + push ebp + mov ebp,offset dump_page + add esi,eax + mov edi,esi + and edi,-pagesize + mov eax,edi + xchg [dump_area_base],eax + push eax + mov al,'d' + call dump + pop [dump_area_base] + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'L4KD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + mov eax,ss + IFZ eax,linear_kernel_space + kd____disp <6,lines-1,24> + push edi + shr edi,log2_pagesize + imul edi,linksize + add edi,ss:[linktab_base] + mov eax,ss:[edi].pdir_link + shr eax,log2_pagesize + IFNZ + kd____disp <'pdir:'> + sub eax,PM SHR log2_pagesize + kd____outhex20 + FI + mov eax,ss:[edi].pmap_link + pop edi + test eax,eax + IFNZ + kd____disp <' pmap:'> + add eax,edi + shr eax,log2_pagesize + kd____outhex20 + FI + FI + FI + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test edx,0F0000000h + CORNZ + test dl,page_present + IFZ + mov eax,edx + kd____outhex32 + mov al,' ' + kd____outchar + ret + FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + IFZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + IF kernel_type NE i486 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ELSE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + IF kernel_type EQ i486 + + IFA eax,GB1 + + mov ebx,M4_pnode_base + DO + mov ecx,[ebx].pte_ptr + test ecx,ecx + IFNZ + mov edi,[ecx] + and edi,-pagesize + mov edi,dword ptr [edi+PM] + sub edi,GB1 + xor edi,eax + test edi,-1 SHL 22 + EXITZ + FI + + add ebx,sizeof pnode + cmp ebx,M4_pnode_base + high4M_pages * sizeof pnode + REPEATB + + pop es + pop ds + ret + OD + + mov eax,ecx + FI + + ENDIF + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + EXIT + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF scheduled_tcb + kd____disp <6,6,1,'scheduled tcb : '> + mov eax,ds:[scheduled_tcb] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + +page_fault_prot: + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + mov [page_fault_prot_state],al + + CORZ al,'+' + IFZ al,'*' + kd____outchar + IFZ [page_fault_handler],0 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + sub eax,eax + xchg eax,[page_fault_handler] + test eax,eax + IFNZ + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFAE eax,[page_fault_low+PM],long + CANDBE eax,[page_fault_high+PM],long + + kd____disp <13,10,'#PF: '> + mov eax,cr2 + kd____outhex32 + kd____disp <', eip='> + mov eax,[esp+ip_eip] + kd____outhex32 + kd____disp <', thread='> + mov eax,esp + and eax,-sizeof tcb + mov eax,[eax+myself] + lno___thread eax,eax + kd____outhex16 + + + IFNZ [page_fault_prot_state+PM],'*' + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'page_fault' + FI + call close_debug_keyboard + FI + FI + + IF kernel_type NE i486 + pop ds + ENDIF + + popad + jmp ds:[page_fault_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + mov [ipc_prot_state],al + + CORZ al,'+' + IFZ al,'*' + kd____outchar + IFZ [ipc_handler],0 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + kd____outchar + sub eax,eax + xchg eax,[ipc_handler] + test eax,eax + IFNZ + mov bl,ipc + call set_exception_handler + FI + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ebp,esp + + kd____disp <13,10> + + mov ebx,esp + and ebx,-sizeof tcb + add ebx,offset myself + call show_thread_id + + DO + mov edx,virtual_space_size + IFAE [ebp+ip_eax],edx + test byte ptr [ebp+ip_ebp],1 + IFZ + kd____disp <' <--- '> + ELSE_ + kd____disp <' <<-- '> + EXIT + FI + + ELIFB [ebp+ip_ebp],edx + test byte ptr [ebp+ip_ebp],1 + IFZ + kd____disp <' <--> '> + ELSE_ + kd____disp <' <<-> '> + FI + ELSE_ + kd____disp <' ---> '> + FI + + mov eax,[ebp+ip_esi] + mov ebx,eax + and ebx,mask thread_no + add ebx,offset tcb_space+offset myself + + test__page_present ebx + IFNC + call show_thread_id + ELSE_ + kd____outhex32 + FI + OD + + IFB_ [ebp+ip_eax],edx + + test byte ptr [ebp+ip_eax],2 + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,[ebp+ip_edx] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[ebp+ip_ebx] + kd____outhex32 + mov al,')' + kd____outchar + FI + + + + IFNZ [ipc_prot_state+PM],'*' + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'ipc' + FI + call close_debug_keyboard + FI + + IF kernel_type NE i486 + pop ds + ENDIF + + popad + add esp,4 + jmp ds:[ipc_handler+PM] + + + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + + kd____inchar + kd____outchar + + push eax + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + call $+5 + pop edi + and edi,PM + mov al,cs:[edi+monitored_exception] + mov ebp,esp + DO + IF kernel_type NE i486 + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + ENDIF + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,cs:[edi+monitored_ec_min] + movzx ecx,cs:[edi+monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + sub eax,eax + CORB cs:[edi+monitored_exception],8 + IFA cs:[edi+monitored_exception],14 + IFNZ cs:[edi+monitored_exception],17 + dec eax + FI + FI + + test edi,edi + bt eax,0 + + IF kernel_type NE i486 + pop ds + ENDIF + popad + IFC + lea esp,[esp+4] + FI + + IFZ + jmp cs:[monitored_exception_handler] + FI + jmp cs:[monitored_exception_handler+PM] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + IF kernel_type NE i486 + pop ds + ENDIF + + popad + add esp,4 + jmp cs:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; tracing on/off +; +;---------------------------------------------------------------------------- + + + +tracing_on_off: + + kd____inchar + mov edi,[kdebug_esp] + IFA edi, + push ds + push linear_kernel_space + pop ds + FI + + IFZ al,'+' + bts [edi+ip_eflags],t_flag + else_ + btr [edi+ip_eflags],t_flag + mov al,'-' + FI + + IFA edi, + pop ds + FI + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +port_io: + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IF kernel_type EQ i486 + kd____disp <'-byte port '> + ELSE + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELSE_ + kd____disp <'-byte port '> + FI + ENDIF + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + IF kernel_type NE i486 + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + ENDIF + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + shl ebx,task_no + add ebx,offset tcb_space + sub edx,edx + test__page_present ebx + IFNC + mov edx,[ebx+task_pdir] + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + IF kernel_type EQ i486 + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + ENDIF + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + IFA esp, + add eax,PM + FI + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + +;-------------------------------------------------------------------------- +; +; special PCI -> 21140 Throughput test +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'MSR: '> + kd____inhex32 + mov ecx,eax + + kd____disp <' r/w? '> + kd____inchar + + IFZ al,'w' + kd____inhex32 + IFNZ ecx,0 + mov edx,eax + kd____disp <':'> + kd____inhex32 + wrmsr + ELSE_ + mov cr4,eax + FI + ELSE_ + IFNZ ecx,0 + rdmsr + xchg eax,edx + kd____outhex32 + kd____disp <':'> + mov eax,edx + kd____outhex32 + ELSE_ + mov eax,cr4 + kd____outhex32 + FI + FI + ret + + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + + + +;--------------------------------------------------------------------------- + + + + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/kdiopc.asm b/l4-x86/l4-4test/kernel/kdiopc.asm new file mode 100644 index 0000000..d9efa8b --- /dev/null +++ b/l4-x86/l4-4test/kernel/kdiopc.asm @@ -0,0 +1,1251 @@ +include l4pre.inc + + dcode + + Copyright GMD, L4.KDIO.PC, 21,06,96, 24 + + +;********************************************************************* +;****** ****** +;****** L4 KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** created: 28.02.91 ****** +;****** modified: 21.06.96 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public init_debug_screen + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +.list + + +ok_for i486,pentium,ppro,k6 + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + + +init_kdio: + + pushad + push ds + + IFAE esp, + mov ebx,phys_mem + mov ds,ebx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov edi,cga_base + ELIFZ al,'m' + mov edi,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov edi,hercules_base + ELSE_ + mov edi,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov edi,cga_base + FI + FI + + mov [deb_screen_base],edi + mov [deb_crtc_base],dx + + pop ds + popad + ret + + + + + +remote_io_open db false + + + + + + + + + +kd_incharety: + + call local_soft_incharety + IFZ eax,-1 + call remote_incharety + IFZ [remote_io_open],false + IFZ al,'+' + mov [remote_io_open],true + FI + stc + sbb eax,eax + FI + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call local_incharety + test eax,eax + EXITNS + call remote_incharety + test eax,eax + REPEATS + + cmp al,'~' + REPEATZ + + IFZ [remote_io_open],false + IFZ al,'+' + mov [remote_io_open],true + FI + REPEAT + FI + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','ü' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','&' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'z','Z' ; 15 Z + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,215 ; 27 ™ + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'y','Y' ; 2C Y + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + test al,00000010b + IFZ + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX -1 iff (remote info mode = off OR no input char available) +; +; EAX char else +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + in al,kb_status + test al,1 + + IFZ + stc + sbb eax,eax + ret + FI + + sub eax,eax + in al,kb_data + + + IFZ al,num_lock + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al + IFNZ + ret + FI + FI + + stc + sbb eax,eax + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + push eax + push edx + mov dx,3D8h + mov al,9 + out dx,al + pop edx + pop eax + ret + + + +init_debug_screen: + + push eax + push edx + + mov dx,[deb_crtc_base] + mov al,screen_start_low + out dx,al + inc edx + mov al,0 + out dx,al + dec edx + mov al,screen_start_high + out dx,al + inc edx + shr eax,16 + mov al,0 + out dx,al + + pop edx + pop eax + ret + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + push ebx + push ecx + + mov ebx,[deb_screen_base] ;;;;; 0b0000h + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + push eax + mov al,27 + call remote_outchar + mov al,'[' + call remote_outchar + mov al,[cursor_y] + inc al + call remote_outdec8 + mov al,';' + call remote_outchar + mov al,[cursor_x] + inc al + call remote_outdec8 + mov al,'H' + call remote_outchar + pop eax + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov eax,07200720h + cld + rep stosd + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outchar + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outchar + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELSE_ + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outchar + ret + FI + + push ecx + push edx + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outchar + + ret + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + +rate_divisor dw 192 ; 600 + dw 96 ; 1200 + dw 48 ; 2400 + dw 24 ; 4800 + dw 12 ; 9600 + dw 6 ; 19200 + dw 3 ; 38400 + dw 1 ;115200 + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 12..23 = 0 : remote info off +; +; EAX BIT 12..23 > 0 : 8250 port base address +; EAX BIT 8..10 : baud rate index +; EAX BIT 0..5 : line control register +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,12 + and dx,0FFFh + mov [remote_info_port],dx + + mov ebx,eax ; set LCR and baud rate divisor + and al,3Fh ; + or al,80h ; + outdx sio_lcr,al ; + mov eax,ebx ; + shr eax,8 ; + and eax,07h ; + mov ax,[(eax*2)+rate_divisor] ; + outdx sio_dllow,al ; + mov al,ah ; + outdx sio_dlhigh,al ; + mov al,bl ; + and al,3Fh ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + +;---------------------------------------------------------------------------- +; +; remote outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outchar: + + push eax + push edx + + mov ah,al + mov dx,[remote_info_port] + IFNZ dx,0 + DO + indx al,sio_lsr + test al,lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outchar + mov al,'[' + call remote_outchar + pop eax + call remote_outchar + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outchar + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX -1 iff (remote info mode = off OR no input char available) +; +; EAX char else +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + mov dx,[remote_info_port] + IFNZ dx,0 + indx al,sio_lsr + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + movzx eax,al + FI + FI + IFZ + mov eax,-1 + FI + + pop edx + ret + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/kernel4.asm b/l4-x86/l4-4test/kernel/kernel4.asm new file mode 100644 index 0000000..f19f7d1 --- /dev/null +++ b/l4-x86/l4-4test/kernel/kernel4.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 20007 +kerneltxt EQU '18.08.96' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4/486 ',0E6h,'-Kernel, Copyright (C) GMD 1995,1996 Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/kernel5.as5 b/l4-x86/l4-4test/kernel/kernel5.as5 new file mode 100644 index 0000000..a580732 --- /dev/null +++ b/l4-x86/l4-4test/kernel/kernel5.as5 @@ -0,0 +1,81 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 30007 +kerneltxt EQU '25.07.97' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4/Pentium ',0E6h,'-Kernel, Copyright (C) IBM 1997 Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + + +dcod segment para public use32 'code' +dcod_start: +dcod ends + + +scod segment para public use32 'code' +scod_start: +scod ends + + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/kernelk6.as5 b/l4-x86/l4-4test/kernel/kernelk6.as5 new file mode 100644 index 0000000..2a8c4a6 --- /dev/null +++ b/l4-x86/l4-4test/kernel/kernelk6.as5 @@ -0,0 +1,81 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 20007 +kerneltxt EQU '18.08.96' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4/AMD-K6 ',0E6h,'-Kernel, Copyright (C) GMD 1995,1996 Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + + +dcod segment para public use32 'code' +dcod_start: +dcod ends + + +scod segment para public use32 'code' +scod_start: +scod ends + + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/ktest4.asm b/l4-x86/l4-4test/kernel/ktest4.asm new file mode 100644 index 0000000..a5fdef9 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ktest4.asm @@ -0,0 +1,716 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.4, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 02.06.96 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list + + + + +ok_for i486 + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 63 dup (0) +ktest0_stack dd 0 + dd 63 dup (0) +ktest1_stack dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + +counter dd 0 + + + + + + align 16 + +test_idt dw 0, linear_space_exec, 0EE00h, 0 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +ncache_refs equ 011110b +locked_bus equ 011100b + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event equ 011b SHL 6 + + +select equ 11h +cnt0 equ 12h +cnt1 equ 13h + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + +;include msg.mac +;include gdp3 +; +;disk_driver dd sigma0_disk_driver,0 +; +; +;order: sr_msg 4,,4 +; dd 0,0,0,0 +; + + assume ds:codseg + + +ktest0_start: + + mov ecx,100 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + +; mov eax,1 +; mov ecx,offset ktest1_stack +; mov edx,offset ktest1_start +; sub ebx,ebx +; mov ebp,ebx +; mov esi,ebx +; mov edi,ebx +; int lthread_ex_regs +; + + +; DO +; int thread_switch +; +; ipc___call [disk_driver],gdp_index+open_order,ebx +; +; ke 'dopen' +; +; test al,ipc_error_mask +; REPEATNZ +; OD +; +; mov eax,offset order +; mov [eax].msg_w2,10*512 +; mov [eax].msg_w3,3*MB1 +; +; ipc___call [disk_driver],gdp_index+block_data_seq_ptr+exec_in,0,, +; +; ke 'dread' +; + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + mov edi,root_chief + int ipc + + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + DO + + mov [ping_dest_vec],pong_thread + mov [ping_dest_vec+4],root_chief + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + ke 'done' + + sti + jmp $ + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; mov edi,root_chief +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma2_task +; mov edi,root_chief +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + ;; mov esi,[ping_dest_vec] + ;; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + mov edi,root_chief + int ipc + test al,al + EXITNZ + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + ;; mov esi,[ping_dest_vec] + ;; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + mov edi,root_chief + int ipc + test al,al + EXITNZ + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + ;; mov esi,[ping_dest_vec] + ;; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + mov edi,root_chief + int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + mov eax,ecx + mov edx,ecx + mov ebp,ecx + ;; mov esi,[ping_dest_vec] + ;; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + mov edi,root_chief + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + mov eax,1 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,ebx + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + mov eax,-1 + + clign 16 + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + ke '-pong_err' + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + +memptr dd 2*MB1 + + + +pf_1024: + + mov ebx,[memptr] + lea ecx,[ebx+128*pagesize] + mov [memptr],ecx + + mov eax,[ebx] + add ebx,pagesize + + timer_start + clign 16 + DO + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + timer_stop + + mov ebx,127*1000 + call microseconds + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/ktest5-30.as5 b/l4-x86/l4-4test/kernel/ktest5-30.as5 new file mode 100644 index 0000000..0e8e96d --- /dev/null +++ b/l4-x86/l4-4test/kernel/ktest5-30.as5 @@ -0,0 +1,1098 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.5, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 02.06.96 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pentium + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+1*sizeof tcb) +pong_thread equ (sigma2_thread+3*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + +;include msg.mac +;include gdp3 +; +;disk_driver dd sigma0_disk_driver,0 +; +; +;order: sr_msg 4,,4 +; dd 0,0,0,0 +; + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + mov eax,(ping_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest0_stack + mov edx,offset kktest0_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest0_start: + + + + +; mov eax,1 +; mov ecx,offset ktest1_stack +; mov edx,offset ktest1_start +; sub ebx,ebx +; mov ebp,ebx +; mov esi,ebx +; mov edi,ebx +; int lthread_ex_regs +; + + +; DO +; int thread_switch +; +; ipc___call [disk_driver],gdp_index+open_order,ebx +; +; ke 'dopen' +; +; test al,ipc_error_mask +; REPEATNZ +; OD +; +; mov eax,offset order +; mov [eax].msg_w2,10*512 +; mov [eax].msg_w3,3*MB1 +; +; ipc___call [disk_driver],gdp_index+block_data_seq_ptr+exec_in,0,, +; +; ke 'dread' +; + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + mov edi,root_chief + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' + + + +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + DO + call enter_ktest + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + mov [ping_dest_vec+4],root_chief + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + jmp xxxx + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + xxxx: + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; mov edi,root_chief +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma2_task +; mov edi,root_chief +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + sub eax,eax + mov esi,[ping_dest_vec] + mov edi,esi + int ipc3 + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + mov ebx,[counter] + + clign 16 + DO + ; rdtsc + ; push eax + ; push esi + ; mov esi,MB2+KB4+KB4 + ; mov ecx,2*KB4 + ; push offset xxxret + ; push esi + ; push ecx + ; mov edi,esi + ; cld + ; mov eax,90h + ; rep stosb + ; pop ecx + ; pop esi + ; rep lodsb + ; mov byte ptr [esi],0C3h + ; ret + ; xxxret: + ; pop esi + ; pop ecx + ; add dword ptr [esp],0 + ; rdtsc + ; sub eax,ecx + ; add [esp],eax + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + + ; dec ebx + ; REPEATNZ + ; EXIT + + test al,al + EXITNZ + + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + sub ebx,4 + REPEATA + OD + test al,al + IFNZ + ke 'ping_err' + FI + +; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + kd____disp <', events: ca='> +; P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> +; P_read P_event_counter1 + div ebx + kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + mov eax,(pong_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,ebx + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + mov eax,-1 + or byte ptr [pong_snd_msg],0 + + mov esi,waiting_any + sub edi,edi + + clign 16 + DO +ps0: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps1: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps2: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps3: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + REPEATZ + OD + ke '-pong_err' + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov dword ptr [ebx],0 + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count rd_miss,cnt_event,d_wback,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count locked_bus,cnt_event,r_stall,cnt_event +; P_count r_stall,cnt_event_PL0,r_stall,cnt_event_PL3 +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + mov [ebx],eax + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + kd____disp <', events: ca='> + ; P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> + ; P_read P_event_counter1 + div ebx + kd____outdec + + + sub eax,eax + lea ecx,[eax-1] + mov edx,ecx + mov ebx,ecx + mov ebp,ecx + mov esi,ecx + mov edi,ecx + int lthread_ex_regs + + lno___prc eax + test al,al + IFZ + mov edx,2*MB1 + ELSE_ + mov edx,MB16 + FI + mov ecx,128 + DO + push edx + push ecx + push esi + + sub eax,eax + sub ecx,ecx + or edx,1 + mov bl,2 + mov edi,esi + int ipc3 + + pop esi + pop ecx + pop edx + + add edx,pagesize + dec ecx + REPEATNZ + OD + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/ktest5-rtas.as5 b/l4-x86/l4-4test/kernel/ktest5-rtas.as5 new file mode 100644 index 0000000..d62aa23 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ktest5-rtas.as5 @@ -0,0 +1,838 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.5, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Special Version for Author: J.Liedtke ****** +;****** Cache Partitioning Tests ****** +;****** ****** +;****** Attention: requires recomp of sigma0+memctr ****** +;****** ****** +;********************************************************************* + +include rtcache.inc + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pentium + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+0*sizeof tcb) +pong_thread equ (sigma2_thread+0*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + + +ktest0_ready db false +ktest1_ready db false + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + assume ds:codseg + + +ktest0_start: + + + + + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + +columns equ matrix_columns + +.errnz (pagesize/(columns*8)) * (columns / (pagesize/(columns*8))) - columns + +IF L2_cache_ways EQ 1 + + matrix_a equ (MB1) + matrix_b equ (matrix_a+MB16) + + code_area equ (2*MB16) + +ELSE + + matrix_a equ (MB1) + matrix_b equ (matrix_a+MB4) + + code_area equ (2*MB4) + +ENDIF + + + + + + mov edx,1 + mov ebx,edx + mov esi,sigma0_task + mov edi,esi + sub eax,eax + mov ecx,1000h+12*4+map_msg + int ipc3 + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + + + mov ds:[ktest0_ready],true + + DO + sub esi,esi + int thread_switch + cmp ds:[ktest1_ready],true + REPEATNZ + OD + + + kd____disp <13,10,'matrix: '> + mov eax,columns + mov ecx,eax + kd____disp <' '> + kd____outdec + kd____disp <'x'> + kd____outdec + kd____disp <13,10> + + DO + mov eax,ds:[1000h].cpu_clock_freq + add eax,500000 + sub edx,edx + mov ebx,1000000 + div ebx + mov ds:[cycles_per_microsecond],eax + mov ebx,eax + + mov eax,ds:[intr_interval] + add eax,25 + mov ds:[intr_interval],eax + IFA eax,500 + CANDNZ eax,10000000 + kd____disp <13,10,'intr interval: '> + kd____inhex32 + IFZ eax,1 + ke 'MM' + FI + IFBE eax,1 + mov eax,25 + mov ds:[intr_interval],eax + FI + FI + + kd____disp <13,10,'int: '> + kd____outdec + kd____disp <'us'> + + imul eax,ebx + mov ebp,eax + + finit + + mov ecx,columns + mov edi,matrix_a + call gen_matrix + mov edi,matrix_b + call gen_matrix + + cli + + mov ds:[ktest1_ready],false + + pushad + DO + mov esi,pong_thread + int thread_switch + cmp ds:[ktest1_ready],true + REPEATNZ + OD + popad + + mov esi,matrix_a + mov edi,matrix_b + ; call mul_matrix + + pushad + mov esi,offset mul_matrix + mov edi,code_area + mov ecx,offset mul_matrix_end - offset mul_matrix + cld + rep movsb + popad + + rdtsc + mov ds:[cycles],eax + + pushfd + cli + mov eax,code_area + call eax + popfd + + + + sub eax,12 + sub eax,ds:[cycles] + mov ds:[cycles],eax + IFZ ds:[best_cycles],0 + mov ds:[best_cycles],eax + FI + kd____disp <' t='> + ; rdtsc + + push eax + sub edx,edx + mov ebx,ds:[cycles_per_microsecond] + imul ebx,1000 + call outdec2 + kd____disp <'ms ('> + pop eax + mov ebx,eax + mov eax,columns*columns*columns + xchg eax,ebx + call outdec2 + kd____disp <'cy/x, '> + mov eax,ds:[vec_mults_sum] + add eax,ds:[vec_mults] + mov ebx,ds:[intrs] + inc ebx + call outdec2 + kd____disp <'vm/ts) q='> + + mov eax,ds:[cycles] + sub edx,edx + mov ebx,ds:[best_cycles] + sub eax,ebx + call outdec2 + + + + REPEAT + OD + + + align 16 + +std_value dq 1.0 +fzero dq 0.0 +result dq 0.0 + +cycles dd 0 + +intr_clock dd 0 +vec_mults dd 0 +vec_mults_sum dd 0 +intrs dd 0 +intr_interval dd 10000000-25 +best_cycles dd 0 +filter_t dd 0 + +cycles_per_microsecond dd 0 + + + +gen_matrix: + + push ecx + push edi + + mov eax,ecx + imul ecx + DO + mov ebx,dword ptr ds:[std_value] + mov ecx,dword ptr ds:[std_value+4] + mov [edi],ebx + mov [edi+4],ecx + add edi,8 + dec eax + REPEATNZ + OD + + pop edi + pop ecx + ret + + + +mul_matrix: + + mov ecx,columns / (pagesize/(columns*8)) + + push esi + push edi + + sub eax,eax + mov ds:[vec_mults],eax + mov ds:[vec_mults_sum],eax + mov ds:[intrs],eax + + rdtsc + mov ds:[intr_clock],eax + DO + push ecx + push esi + push edi + + mov ecx,columns + DO + push ecx + push esi + push edi + + sub ebx,ebx + cli + fninit + mov ecx,pagesize/(columns*8) + DO + push ecx + mov ecx,columns + fld qword ptr ds:[fzero] + jmp short xx + + DO + faddp st(1),st + xx: + fld dword ptr [ecx*8+esi-8] + fmul qword ptr [ecx*8+edi-8] + fld qword ptr [ecx*8+esi-16] + fmul qword ptr [ecx*8+edi-16] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-24] + fmul qword ptr [ecx*8+edi-24] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-32] + fmul qword ptr [ecx*8+edi-32] + fxch st(1) + faddp st(2),st + + sub ecx,4 + REPEATNZ + OD + faddp st(1),st + fstp qword ptr ds:[result] + + pop ecx + inc ebx + cmp ebx,10 + REPEATB + IFZ + rdtsc + mov ecx,eax + REPEAT + FI + cmp ebx,110 + REPEATB + rdtsc + sub eax,ecx + ke 'vector' + sub ebx,ebx + REPEAT + + + rdtsc + sub eax,12 + sub ds:[cycles],eax + + inc ds:[vec_mults] + + rdtsc + sub eax,ds:[intr_clock] + sub eax,ebp + IFAE + inc ds:[intrs] + sub ebx,ebx + xchg ds:[vec_mults],ebx + add ds:[vec_mults_sum],ebx + + IF interfering_with EQ filter + mov ebx,eax + rdtsc + sub eax,ebx + mov ds:[intr_clock],eax + + rdtsc + add ds:[cycles],eax + ENDIF + + pushad + mov esi,pong_thread + int thread_switch + popad + + IF interfering_with EQ filter + jmp xxxx + ENDIF + + IF interfering_with EQ flooder + mov ebx,eax + rdtsc + sub eax,ebx + mov ds:[intr_clock],eax + ENDIF + FI + + rdtsc + add ds:[cycles],eax + + + xxxx: + pop ecx + add edi,columns*8 + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + + add esi,columns*8 + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + + add edi,(pagesize/(columns*8)) * (columns*8) + dec ecx + REPEATNZ + + OD + + pop edi + pop esi + ret + + +mul_matrix_end equ $ + + + + +outdec2: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + + popad + ret + + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +filter_area equ 8*MB1 + L2_cache_colors/2*pagesize + +ktest1_start: + + DO + sub esi,esi + int thread_switch + cmp ds:[ktest0_ready],true + REPEATNZ + OD + + + + + IF interfering_with EQ none + + jmp ktest1_start + + ENDIF + + + + + IF interfering_with EQ flooder + + mov edi,8*MB1+KB256+KB256-2*KB4 + mov ecx,2*KB4-1 + mov al,90h + cld + rep stosb + mov byte ptr [edi],0C3h + + + cli + DO + mov edi,8*MB1 + mov ecx,KB256/4 ; 2*KB4/4; KB256/4 + ; lea edi,[edi+(ecx*4)-32] + DO + IF (cache_strategy EQ write_through) OR (partitioning_strategy EQ single_writer_partitioned) + mov eax,[edi] + ELSE + add dword ptr ds:[edi],0 + ENDIF + mov eax,[edi] + ; sub edi,32 + add edi,32 + sub ecx,32/4 + REPEATA + OD + IF partitioning_strategy EQ single_writer_partitioned + mov edi,8*MB1 + mov ecx,2*KB4/4 + DO + add dword ptr [edi],0 + add edi,32 + sub ecx,32/4 + REPEATA + OD + ENDIF + + + mov edi,8*MB1+KB256+KB256-2*KB4 + call edi + + mov ds:[ktest1_ready],true + + mov esi,ping_thread + int thread_switch + + REPEAT + OD + ENDIF + + + + IF interfering_with EQ filter + + + mov edi,8*MB1+3*pagesize + mov esi,offset filter_loop + mov ecx,offset filter_end - offset filter_loop + cld + rep movsb + + + mov edi,filter_area + mov eax,filtersize*2 + DO + mov ebx,dword ptr ds:[std_value] + mov ecx,dword ptr ds:[std_value+4] + mov [edi],ebx + mov [edi+4],ecx + add edi,8 + dec eax + REPEATNZ + OD + + sub eax,eax + mov ds:[filter_t],eax + + cli + + mov edi,8*MB1+3*pagesize + jmp edi + + + filter_loop: + + DO + mov eax,ds:[filter_t] + inc eax + IFAE eax,filtersize + sub eax,eax + FI + mov ds:[filter_t],eax + + mov edi,filter_area + lea esi,[eax*8+edi+filtersize*8] + mov ecx,filtersize + + fld qword ptr ds:[fzero] + jmp short xx1 + + DO + faddp st(1),st + xx1: + fld qword ptr [esi] + fmul qword ptr [edi] + fld qword ptr [esi+8] + fmul qword ptr [edi+8] + fxch st(1) + faddp st(2),st + fld qword ptr [esi+16] + fmul qword ptr [edi+16] + fxch st(1) + faddp st(2),st + fld qword ptr [esi+24] + fmul qword ptr [edi+24] + fxch st(1) + faddp st(2),st + + add esi,4*8 + add edi,4*8 + IFB_ esi,filter_area+2*(filtersize*8) + sub ecx,4 + REPEATNZ + ELSE_ + sub esi,filtersize*8 + sub ecx,4 + REPEATNZ + FI + OD + faddp st(1),st + fstp qword ptr [result] + add dword ptr [esi],0 + + mov ds:[ktest1_ready],true + + mov esi,ping_thread + int thread_switch + + REPEAT + OD + + + filter_end equ $ + + + ENDIF + + + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/ktest5.as5 b/l4-x86/l4-4test/kernel/ktest5.as5 new file mode 100644 index 0000000..1848dc2 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ktest5.as5 @@ -0,0 +1,1109 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.5, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 02.06.96 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pentium + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+1*sizeof tcb) +pong_thread equ (sigma2_thread+3*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + +;include msg.mac +;include gdp3 +; +;disk_driver dd sigma0_disk_driver,0 +; +; +;order: sr_msg 4,,4 +; dd 0,0,0,0 +; + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + mov eax,(ping_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest0_stack + mov edx,offset kktest0_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest0_start: + + + + +; mov eax,1 +; mov ecx,offset ktest1_stack +; mov edx,offset ktest1_start +; sub ebx,ebx +; mov ebp,ebx +; mov esi,ebx +; mov edi,ebx +; int lthread_ex_regs +; + + +; DO +; int thread_switch +; +; ipc___call [disk_driver],gdp_index+open_order,ebx +; +; ke 'dopen' +; +; test al,ipc_error_mask +; REPEATNZ +; OD +; +; mov eax,offset order +; mov [eax].msg_w2,10*512 +; mov [eax].msg_w3,3*MB1 +; +; ipc___call [disk_driver],gdp_index+block_data_seq_ptr+exec_in,0,, +; +; ke 'dread' +; + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + mov edi,root_chief + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' + + + +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + DO + call enter_ktest + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + + inc [large_space] + + + ; kd____disp <13,10,10,'PageFault: '> + ; call pf_1024 + + mov [ping_dest_vec],pong_thread + mov [ping_dest_vec+4],root_chief + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + jmp xxxx + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + xxxx: + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; mov edi,root_chief +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma2_task +; mov edi,root_chief +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + sub eax,eax + mov esi,[ping_dest_vec] + mov edi,esi + int ipc3 + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +;; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + mov edx,offset ktest0_stack + mov eax,dword ptr ds:[edx] + + mov ebx,[counter] + + clign 16 + DO + ; rdtsc + ; push eax + ; push esi + ; mov esi,MB2+KB4+KB4 + ; mov ecx,2*KB4 + ; push offset xxxret + ; push esi + ; push ecx + ; mov edi,esi + ; cld + ; mov eax,90h + ; rep stosb + ; pop ecx + ; pop esi + ; rep lodsb + ; mov byte ptr [esi],0C3h + ; ret + ; xxxret: + ; pop esi + ; pop ecx + ; add dword ptr [esp],0 + ; rdtsc + ; sub eax,ecx + ; add [esp],eax + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + + ; dec ebx + ; REPEATNZ + ; EXIT + + test al,al + EXITNZ + + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + int ipc3 + sub ebx,4 + REPEATA + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ;; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ret + + + + kd____disp <', events: ca='> + P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> + P_read P_event_counter1 + div ebx + kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + mov eax,(pong_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,ebx + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + mov edx,offset ktest0_stack + mov eax,dword ptr ds:[edx] + + + mov eax,-1 + or byte ptr [pong_snd_msg],0 + + mov esi,waiting_any + sub edi,edi + + clign 16 + DO +ps0: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps1: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps2: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + EXITNZ +ps3: mov eax,0 + mov ecx,offset pong_rcv_msg + int ipc3 + mov edi,esi + test al,al + REPEATZ + OD + ke '-pong_err' + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov dword ptr [ebx],0 + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count rd_miss,cnt_event,d_wback,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count locked_bus,cnt_event,r_stall,cnt_event +; P_count r_stall,cnt_event_PL0,r_stall,cnt_event_PL3 +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + mov [ebx],eax + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + kd____disp <', events: ca='> + ; P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> + ; P_read P_event_counter1 + div ebx + kd____outdec + + + sub eax,eax + lea ecx,[eax-1] + mov edx,ecx + mov ebx,ecx + mov ebp,ecx + mov esi,ecx + mov edi,ecx + int lthread_ex_regs + + lno___prc eax + test al,al + IFZ + mov edx,2*MB1 + ELSE_ + mov edx,MB16 + FI + mov ecx,128 + DO + push edx + push ecx + push esi + + sub eax,eax + sub ecx,ecx + or edx,1 + mov bl,2 + mov edi,esi + int ipc3 + + pop esi + pop ecx + pop edx + + add edx,pagesize + dec ecx + REPEATNZ + OD + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/ktestk6.as5 b/l4-x86/l4-4test/kernel/ktestk6.as5 new file mode 100644 index 0000000..451af57 --- /dev/null +++ b/l4-x86/l4-4test/kernel/ktestk6.as5 @@ -0,0 +1,1118 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.K6, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 02.06.96 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for k6 + + +syscall_ textequ + + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+1*sizeof tcb) +pong_thread equ (sigma2_thread+3*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + +;include msg.mac +;include gdp3 +; +;disk_driver dd sigma0_disk_driver,0 +; +; +;order: sr_msg 4,,4 +; dd 0,0,0,0 +; + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + mov eax,(ping_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest0_stack + mov edx,offset kktest0_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest0_start: + + + + +; mov eax,1 +; mov ecx,offset ktest1_stack +; mov edx,offset ktest1_start +; sub ebx,ebx +; mov ebp,ebx +; mov esi,ebx +; mov edi,ebx +; int lthread_ex_regs +; + + +; DO +; int thread_switch +; +; ipc___call [disk_driver],gdp_index+open_order,ebx +; +; ke 'dopen' +; +; test al,ipc_error_mask +; REPEATNZ +; OD +; +; mov eax,offset order +; mov [eax].msg_w2,10*512 +; mov [eax].msg_w3,3*MB1 +; +; ipc___call [disk_driver],gdp_index+block_data_seq_ptr+exec_in,0,, +; +; ke 'dread' +; + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + mov edi,root_chief + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' + + + +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + DO + call enter_ktest + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + ; call pf_1024 + + mov [ping_dest_vec],pong_thread + mov [ping_dest_vec+4],root_chief + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + jmp xxxx + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + xxxx: + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; mov edi,root_chief +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma2_task +; mov edi,root_chief +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + sub eax,eax + mov esi,[ping_dest_vec] + mov edi,esi + int ipc3 + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + mov ebx,[counter] + + sub ecx,ecx + push ecx + push ebp + + clign 16 + DO + ; rdtsc + ; push eax + ; push esi + ; mov esi,MB2+KB4+KB4 + ; mov ecx,2*KB4 + ; push offset xxxret + ; push esi + ; push ecx + ; mov edi,esi + ; cld + ; mov eax,90h + ; rep stosb + ; pop ecx + ; pop esi + ; rep lodsb + ; mov byte ptr [esi],0C3h + ; ret + ; xxxret: + ; pop esi + ; pop ecx + ; add dword ptr [esp],0 + ; rdtsc + ; sub eax,ecx + ; add [esp],eax + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + syscall_ ; int ipc3 + + ; dec ebx + ; REPEATNZ + ; EXIT + + test al,al + EXITNZ + + + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + syscall_ ; int ipc3 + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + syscall_ ; int ipc3 +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + mov esi,pong_thread + sub eax,eax + mov edi,esi + syscall_ ; int ipc3 + sub ebx,4 + REPEATA + OD + + pop ebp + pop ecx + + test al,al + IFNZ + ke 'ping_err' + FI + +; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + kd____disp <', events: ca='> +; P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> +; P_read P_event_counter1 + div ebx + kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + mov eax,(pong_thread AND mask lthread_no) SHR lthread_no + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,ebx + mov edi,ebx + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + mov eax,-1 + or byte ptr [pong_snd_msg],0 + + mov esi,waiting_any + sub edi,edi + + mov ecx,offset pong_rcv_msg + push ecx + push ebp + + clign 16 + DO +ps0: mov eax,0 + mov ecx,offset pong_rcv_msg + syscall_ ; int ipc3 + mov edi,esi + test al,al + EXITNZ +ps1: mov eax,0 + mov ecx,offset pong_rcv_msg + syscall_ ; int ipc3 + mov edi,esi + test al,al + EXITNZ +ps2: mov eax,0 + mov ecx,offset pong_rcv_msg + syscall_ ; int ipc3 + mov edi,esi + test al,al + EXITNZ +ps3: mov eax,0 + mov ecx,offset pong_rcv_msg + syscall_ ; int ipc3 + mov edi,esi + test al,al + REPEATZ + OD + + pop ebp + pop ecx + + ke '-pong_err' + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov dword ptr [ebx],0 + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count rd_miss,cnt_event,d_wback,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count locked_bus,cnt_event,r_stall,cnt_event +; P_count r_stall,cnt_event_PL0,r_stall,cnt_event_PL3 +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + mov [ebx],eax + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + kd____disp <', events: ca='> + ; P_read P_event_counter0 + div ebx + kd____outdec + + kd____disp <', cb='> + ; P_read P_event_counter1 + div ebx + kd____outdec + + + sub eax,eax + lea ecx,[eax-1] + mov edx,ecx + mov ebx,ecx + mov ebp,ecx + mov esi,ecx + mov edi,ecx + int lthread_ex_regs + + lno___prc eax + test al,al + IFZ + mov edx,2*MB1 + ELSE_ + mov edx,MB16 + FI + mov ecx,128 + DO + push edx + push ecx + push esi + + sub eax,eax + sub ecx,ecx + or edx,1 + mov bl,2 + mov edi,esi + int ipc3 + + pop esi + pop ecx + pop edx + + add edx,pagesize + dec ecx + REPEATNZ + OD + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/memctr.asm b/l4-x86/l4-4test/kernel/memctr.asm new file mode 100644 index 0000000..4d0fa68 --- /dev/null +++ b/l4-x86/l4-4test/kernel/memctr.asm @@ -0,0 +1,523 @@ +include l4pre.inc + + Copyright GMD, L4.MEMCTR, 30,05,96, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 05.03.91 ****** +;****** modified: 30.05.96 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public initial_grab_mem + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include intrifc.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + pushad + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + and edx,-pagesize + + mov [esp+7*4],edx + popad + ret + + + + icode + +;include rtcache.inc +; +; + + +initial_grab_frame: + + popad + mov eax,pagesize + + +; DO +; mov eax,pagesize +; call initial_grab_mem +; test eax,L2_cache_colors/2*pagesize +; REPEATNZ +; OD +; ret + + + +initial_grab_mem: + + pushad + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc ecx + lea edx,[ecx*4+edx] + ENDIF + mov ecx,[edx+lowest_allocated_frame] + + add eax,pagesize-1 + and eax,-pagesize + + sub ecx,eax + CORC + IFB_ ecx,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],ecx + + mov [esp+7*4],ecx + popad + + + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + mov ebx,ds:[((sigma0_task AND mask task_no) + offset tcb_space)].task_pdir + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test al,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + IFNZ eax,edi + call map_ur_pages + FI + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + mov eax,[ebx+reserved_mem0].mem_end + ;;;;;;;;;;;;; mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + IF kernel_type NE i486 + test esi,MB4-1 + IFZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + ENDIF + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/pagctr4.asm b/l4-x86/l4-4test/kernel/pagctr4.asm new file mode 100644 index 0000000..65f8aae --- /dev/null +++ b/l4-x86/l4-4test/kernel/pagctr4.asm @@ -0,0 +1,1104 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGCTR.4, 19,07,96, 117 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + public gen_4M_page + + + extrn alloc_initial_pagmap_pages:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + + +.nolist +include l4const.inc +.list +include adrspace.inc +.nolist +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + + +ok_for i486 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + mov cl,page_present+page_write_permit + add esi,PM + call map_page_initially + add eax,pagesize + add esi,pagesize-PM + dec edi + REPEATNZ + OD + mov edi,[phys_frames] + shl edi,log2_pagesize + add esi,PM + add edi,PM + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + cmp esi,edi + REPEATNZ + OD + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + mov cl,page_present+page_write_permit + call alloc_kernel_pages + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + mov cl,page_present+page_write_permit + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + + mov edi,offset task_proot + mov ecx,sizeof task_proot/4 + lea eax,[ebx+(root_chief SHR task_no)] + cld + rep stosd + + mov ds:[kernel_proot],edx + mov ds:[empty_proot],ebx + + popad + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; CL page attributes +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov dword ptr ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + mov edi,root_chief + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + mov edi,root_chief + int ipc + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + +;---------------------------------------------------------------------------- +; +; gen 4M page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; superpage bit in EAX set: EAX physical address + superpage +; +; superpage bit in EAX reset: EAX physical address of spec ptab +; pointing to original 4 M frame +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- + + + + +gen_4M_page: + + push ebx + push ecx + + lea ebx,[eax+page_user_permit+page_write_permit+page_present] + + call request_fresh_ptab + + IFNC + mov ecx,eax + DO + mov dword ptr [ecx+PM],ebx + add ebx,pagesize + add ecx,4 + test ecx,pagesize-1 + REPEATNZ ; NC ! + OD + FI + + pop ecx + pop ebx + ret + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + + icode + + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/pagctr5.as5 b/l4-x86/l4-4test/kernel/pagctr5.as5 new file mode 100644 index 0000000..e4bba84 --- /dev/null +++ b/l4-x86/l4-4test/kernel/pagctr5.as5 @@ -0,0 +1,1130 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGCTR.5, 16,07,96, 114 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 16.07.96 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + extrn grab_frame:near + extrn update_proot:near + extrn remove_from_sigma0_and_pmap:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + + +.nolist +include l4const.inc +.list +include adrspace.inc +.nolist +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for pentium,k6 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + +cr4_enable_superpages equ 4 + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + mov eax,0B8000h ; + mov esi,eax ; to enable kdebug output during startup phase + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially ; + + mov eax,cr4 + bts eax,cr4_enable_superpages + mov cr4,eax + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit+page_write_through + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + mov cl,page_present+page_write_permit + call alloc_kernel_pages + + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + mov cl,page_present+page_write_permit + call alloc_kernel_pages + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + + mov ds:[kernel_proot],edx + mov ds:[kernel_proot+4],edx + mov ds:[empty_proot],ebx + mov ds:[empty_proot+4],ebx + + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; CL page attributes +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32+16 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + and eax,-pagesize ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push eax + push ebx + push ecx + push esi + + call init_pdir + + mov esi,edx + mov ebx,eax + mov ecx,eax + mov al,[edx+small_as] + call update_proot + + pop esi + pop ecx + pop ebx + pop eax + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + mov edi,root_chief + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + mov edi,root_chief + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call remove_from_sigma0_and_pmap + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + mov edx,ecx + shr edx,log2_pagesize + imul edx,linksize + add edx,ds:[linktab_base] + + mov [edx].pdir_link,edi + + push eax + call request_fresh_frame + and ecx,-pagesize + sub eax,ecx + mov [edx].pmap_link,eax + pop eax + + pop edi + pop esi + pop edx + pop ecx + ret + + + icod ends + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/pagfault.asm b/l4-x86/l4-4test/kernel/pagfault.asm new file mode 100644 index 0000000..3aa3ab6 --- /dev/null +++ b/l4-x86/l4-4test/kernel/pagfault.asm @@ -0,0 +1,686 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGFAULT, 04,07,96, 160, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 04.07.96 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn tcb_fault:near + extrn flush_tcb:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list + + IF kernel_type NE i486 + extrn set_small_pde_block_in_pdir:near + ENDIF + +.nolist +include intrifc.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for i486,pentium,ppro,k6 + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler+PM + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + +page_fault_handler: + + + cmp ss:[esp+iret_cs+4],linear_kernel_space_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + IF kernel_type NE i486 + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + ENDIF + + IFB_ edx,,long + + mov edi,[ebp+pager] + mov esi,edi + + IFNZ [ebp+thread_state],locked + + sub eax,eax + mov ecx,32*4+map_msg + + push 0 + push linear_kernel_space_exec + push offset ipcret+PM + jmp ipc_sc + ipcret: + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + call push_ipc_state + + IFNZ + sub eax,eax + + push edx + push ebp + mov ecx,32*4+map_msg + int ipc3 + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + test__page_present edx + CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + + + IF kernel_type NE i486 + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov esi,[ebp+task_pdir] + add esi,PM + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + ENDIF + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + mov ebx,[esi+task_pdir] + add ebx,PM + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + push ebp + mov edi,[ebp+com_partner] + push eax + push edi + + call tunnel_to + + pop ebp + pop eax + mov edi,ss:[esp] + + add byte ptr [eax],0 + + call tunnel_to + + pop ebp + pop esi + REPEAT + OD + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-256) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 256' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/pagmap4.asm b/l4-x86/l4-4test/kernel/pagmap4.asm new file mode 100644 index 0000000..1971247 --- /dev/null +++ b/l4-x86/l4-4test/kernel/pagmap4.asm @@ -0,0 +1,1690 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGMAP.4, 17,07,96, 40, K + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 17.07.96 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn gen_4M_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + + + +ok_for i486,ppro + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + mov cl,page_present+page_write_permit + call alloc_kernel_pages + mov ecx,eax + mov edi,esi + mov al,0 + cld + rep stosb + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,high4M_pages + shl eax,log2_size_pnode + mov cl,page_present+page_write_permit + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + imul eax,pnodes_per_frame-1 + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov ebx,M4_pnode_base + DO + mov [ebx].pte_ptr,0 + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + add ebx,sizeof pnode-1 + cmp ebx,M4_pnode_base + high4M_pages * sizeof pnode + REPEATB + OD + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+PM + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + klign 32 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + push offset grant_page_+PM + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+PM + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+PM + jmp short do_fpage + FI + push offset unmap_write_page+PM + jmp short do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page+PM + jmp short do_fpage + FI + push offset flush_write_page+PM + jmp short do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page+PM + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IF kernel_type NE i486 + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + ENDIF + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + and ch,NOT (ur_page SHR 8) + or ecx,NOT (page_write_permit + (1 SHL no_autoflush_bit) + ur_page) + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + cmp ebx,ptes_per_chapter + jae do_large_fpage + + mov esi,eax + shr eax,22 + and esi,003FF000h + + cmp eax,virtual_space_size SHR 22 + jae do_fpage_ret + + shr esi,log2_pagesize-2 + mov eax,[eax*4+ebp] + add esi,ecx + + + test eax,M4_page+page_present + IFPO ; note: NOT present => NOT M4 page + and eax,-pagesize + add esi,eax + + test edx,edx + IFNZ + lno___task ecx,edx + + cmp edi,virtual_space_size + jae short do_fpage_ret + + load__proot ecx,ecx + mov ebp,edi + shr ebp,22 + + and edi,003FF000h + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,dword ptr [ebp*4+ecx+PM] + + test eax,(M4_page SHL 8)+page_present + xc pe,do_fpage_map_fresh_ptab + and eax,-pagesize + add edi,eax + FI + + + mov ebp,esp + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + FI + + + + +do_fpage_ret: + + cmp [esp+tlb_flush_indicator],1 + + lea esp,[esp+sizeof do_source_dest_data] + ret + + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz do_fpage_ret + + lea ecx,[ebp*4+ecx+PM] + call map_fresh_ptab + xret nc + + jmp do_fpage_ret + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +do_large_fpage: + + DO + + cmp eax,virtual_space_size + jae do_large_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + shr eax,22-2 + mov edx,[ebp+source_pdir] + add edx,eax + and esi,003FF000h + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + cmp ebx,MB4/pagesize + xc ae,perhaps_high4M_page,long + + test eax,M4_page+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_large_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test eax,M4_page+page_present + xc pe,do_large_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_large_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_large_fpage_ret: + + cmp [esp+tlb_flush_indicator],1 + + lea esp,[esp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_large_fpage_map_fresh_ptab + + jnz short do_large_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_large_fpage_pop_ret: + + pop edi + pop eax + jmp do_large_fpage_ret + + + + + + + +XHEAD permit_intr_in_do_large_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_large_fpage + + + + + + + + + + + +XHEAD perhaps_high4M_page + + test ah,M4_page SHR 8 + IFZ + test eax,eax + xret nz,long + + mov ecx,[ebp+source_pdir] + sub ecx,PM + cmp ecx,ds:[sigma0_proot] + xret nz,long + + call gen_high4M_ur_page + xret z,long + FI + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_large_fpage_pop_ret + + load__proot ecx,ecx + shr edi,22 + lea edi,[edi*4+ecx+PM] + FI + + push ebx + call [ebp+operation] + pop ebx + + sub eax,eax + + xret ,long + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + IFNZ [eax].pte_ptr,esi + mov eax,[ebx+cache1] + CANDNZ [eax].pte_ptr,esi + call search_pnode + FI + + endm + + + + align 16 + + +search_pnode: + + push ecx + mov ecx,100 + mov eax,ebx + DO + dec ecx + IFZ + ke 's00' + FI + + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + dec ecx + IFZ + ke 's01' + FI + + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ecx + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + shr eax,12-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + + align 16 + + +grant_page_: + + + mov ebx,[edi] + test ebx,ebx + jnz short void_or_access_attribute_widening + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + ret + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,cr3 + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,ebx + mov dword ptr [ebx],0 + + shr ebx,log2_pagesize + shr edi,log2_chaptersize + + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + xor ebx,ebp + test ebx,-pagesize + xc z,unmap_in_own_address_space + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + +XHEAD unmap_in_own_address_space + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + mov ebx,[eax].pte_ptr + cmp ebx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp ebx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,cr3 + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + xor ebx,ebp + test ebx,-pagesize + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + ret + + + + + + +flush_write_page: + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [edi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + ret + + + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+PM + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+PM + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + push edx + + mov edx,sigma0_task + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + call map_fresh_ptab + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + pop edx + + mov bl,dl + bts ebx,ur_page_bit + mov [ecx],ebx + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + add ebx,offset pnode_base + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; gen high 4M page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX PDE address +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ succeeded +; +; Z failed +; +; +;---------------------------------------------------------------------------- + + +gen_high4M_ur_page: + + push ebx + + ke '4M' + mov ebx,M4_pnode_base + DO + cmp [ebx].pte_ptr,0 + IFNZ + add ebx,sizeof pnode + cmp ebx,M4_pnode_base + high4M_pages * sizeof pnode + REPEATB + + EXIT + FI + + mov eax,edx + and eax,pagesize-1 + shl eax,22-2 + add eax,GB1 + EXITNS + + call gen_4M_page + EXITC + + mov [ebx].pte_ptr,edx + + test al,superpage + IFZ + mov ebx,eax + shr ebx,log2_pagesize-log2_size_pnode + add ebx,pnode_base + + mov [ebx].pte_ptr,edx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + FI + or eax,M4_page+ur_page+page_user_permit+page_write_permit+page_present + mov [edx],eax + ; NZ ! + pop ebx + ret + OD + + pop ebx + sub eax,eax ; Z + ret + + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/pagmap5.as5 b/l4-x86/l4-4test/kernel/pagmap5.as5 new file mode 100644 index 0000000..bb3c829 --- /dev/null +++ b/l4-x86/l4-4test/kernel/pagmap5.as5 @@ -0,0 +1,1345 @@ +include l4pre.inc + + + Copyright GMD, L4.PAGMAP.5, 24,03,97,210 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 17.07.96 ****** +;****** ****** +;********************************************************************* + + + public init_pagmap + public map_ur_page_initially + public map_or_grant_fpage + public flush_address_space + public remove_from_sigma0_and_pmap + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn initial_grab_mem:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + + + +ok_for pentium,k6 + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov ecx,[phys_frames+PM] + lea eax,[ecx*linksize] + call initial_grab_mem + add eax,PM + mov ds:[linktab_base],eax + push eax + sub eax,(PM SHR log2_pagesize)*linksize + mov ds:[linktab_base_PM],eax + pop eax + + push ecx + DO + mov dword ptr [eax],0 + add eax,4 + dec ecx + REPEATNZ + OD + pop ecx + + + + imul ecx,pnodes_per_frame + lea eax,[ecx*sizeof pnode] + call initial_grab_mem + add eax,PM + mov ds:[free_pnode_root],eax + + DO + mov [eax].pte_ptr,0 + add eax,sizeof pnode + mov [eax-sizeof pnode].succ_pnode,eax + dec ecx + REPEATNZ + OD + mov [eax-sizeof pnode].succ_pnode,-1 + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+PM + call define_idt_gate + + ret + + + + + icod ends + + + + + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+PM + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+PM + jmp do_fpage + FI + push offset unmap_write_page+PM + jmp do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page+PM + jmp do_fpage + FI + push offset flush_write_page+PM + jmp do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map or grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX centerpoint +; EBX source fpage addr + operation +; EBP dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_or_grant_fpage: + + mov ch,bl ; CH: opn + mov eax,ebx + + mov ebx,edi + mov esi,-1 SHL log2_pagesize + + shr al,2 + mov cl,bl + + shr cl,2 + mov edi,esi + + sub al,log2_pagesize + IFNC + + sub cl,log2_pagesize + CANDNC + + shl edi,cl + mov cl,al + + shl esi,cl + + and eax,esi + xor esi,edi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + + and edx,esi + and edi,ebx + + add edi,edx + mov ebx,esp + + test ecx,(fpage_grant SHL 8)+0FFh + xc z,map_one_page + + push edi + + mov edx,ebp + push ebp + + push eax + push offset map_page+PM + + test ch,fpage_grant + jz do_fpage + + + mov ch,0FFh ; map mask: all + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + mov [esp],offset grant_page_+PM + jmp do_fpage + + FI + + ret + + + + + + + + +XHEAD shrink_snd_fpage + + and edx,esi + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD map_one_page + + + + and ebx,-sizeof tcb + mov esi,edi + + shr esi,22 + mov edx,[ebp+task_pdir] + + + cmp edi,virtual_space_size + IFB_ + + mov edx,dword ptr ds:[esi*4+edx+PM] + mov esi,eax + + shr esi,22 + mov ebx,[ebx+task_pdir] + + test dl,superpage+page_present + xret pe + + mov ebx,dword ptr ds:[esi*4+ebx+PM] + and edx,-pagesize + + test bl,superpage+page_present + xret pe + + shr edi,12 + and eax,3FF000h + + shr eax,12 + and ebx,-pagesize + + and edi,3FFh + cmp esi,virtual_space_size SHR 22 + + lea esi,[eax*4+ebx+PM] + CANDB + + or ch,NOT page_write_permit + lea edi,[edi*4+edx+PM] + + mov eax,[esi] + + test eax,eax + jnz map_page + + FI + ret + + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,esp + and ebp,-sizeof tcb + mov ebp,[ebp+task_pdir] + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + or ch,NOT page_write_permit + and ebp,-pagesize + + push ecx + add ebp,PM + + inc ds:[do_fpage_counter] + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + cmp edi,virtual_space_size + jae do_fpage_ret + + mov ecx,[edx+task_pdir] + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + mov ecx,[ebp+map_mask] + DO + mov eax,[esi] + test eax,eax + IFNZ + push ebx + call [ebp+operation] + pop ebx + FI + + dec ebx + jz short do_fpage_ret + + add esi,4 + add edi,4 + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + jnz short intr_in_do_fpage + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz do_fpage_ret + + call map_fresh_ptab + xret nc,long + jmp do_fpage_ret + + + + + + + +intr_in_do_fpage: + + pop edi + pop eax + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + + + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + cmp edi,virtual_space_size + jae do_fpage_ret + + mov edx,[edx+task_pdir] + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,pagesize-1 + mov ecx,esi + shr ecx,log2_pagesize + mov eax,ds:[linktab_base] + mov ds:[ecx*linksize+eax].pdir_link,0 + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + push edi + + mov edi,ds:[linktab_base] + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*linksize+edi].pdir_link,0 + + IFZ [ebp+operation], + push ecx + ;; shl ecx,log2_size_pnode-2 + ;; cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*linksize+edi].pdir_link,edx + FI + + ELSE_ + sub eax,eax + FI + + pop edi + pop ebx + xret ,long + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; map / grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CH map mask +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + + +grant_page_: + + + mov byte ptr [esi],0 + pushad + call unmap_page + popad + + + + + + +map_page: + + and al,ch + mov ecx,[edi] + + mov edx,ds:[linktab_base_PM] + mov [edi],eax + + test ecx,ecx + xc nz,flush_dest_pte + + mov eax,esi + mov ecx,esi + + shr eax,log2_pagesize + + mov eax,[eax*linksize+edx] + xor ecx,512 + + test eax,eax + xc z,gen_new_maptab,long + + mov edx,[eax+ecx] + add eax,ecx + + test edx,edx + IFZ + mov [eax],edi + ret + FI + + + mov ecx,ds:[free_pnode_root] + test edx,1 + IFZ + mov [ecx].pte_ptr,edx + mov edx,ecx + + mov ecx,[ecx].succ_pnode + FI + + and edx,NOT 1 + inc ecx + + mov [eax],ecx + jz short free_pnode_unavailable + + mov eax,[ecx-1].succ_pnode + mov [ecx-1].pte_ptr,edi + + mov ds:[free_pnode_root],eax + mov [ecx-1].succ_pnode,edx + + ret + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +XHEAD flush_dest_pte + + and al,page_present+page_write_permit + not cl + and al,cl + IFNZ + + xor eax,ecx + and eax,-pagesize + CANDZ + + mov eax,esi + shr eax,log2_pagesize + mov eax,[eax*linksize+edx] + test eax,eax + CANDNZ + + mov eax,[eax+esi] + cmp eax,edi + jz trivial_remap + + dec eax + test eax,1 + IFZ + DO + cmp [eax].pte_ptr,edi + jz trivial_remap + mov eax,[eax].succ_pnode + test eax,eax + REPEATNZ + OD + FI + FI + + IFNZ cl,NOT 0 + pushad + mov esi,edi + call unmap_page + popad + FI + + shr ecx,log2_pagesize + push edx + push esi + push ebp + + mov esi,[ecx*linksize+edx].ptab_link + mov ebp,esp + call clear_ + ke 'grrr' + +cleared: + mov [eax],edx + + mov esp,ebp + pop edx + pop ebp + pop esi + xret ,long + + + +trivial_remap: + + ret + + + + +clear_: + mov eax,esi + sub edx,edx + + shr eax,log2_pagesize + mov eax,[eax*linksize+edx] + test eax,eax + IFNZ + + mov ecx,[eax+esi] + add eax,esi + + test ecx,ecx + CANDNZ + + cmp esi,edi + jz cleared + + mov esi,ecx + test ecx,1 + jz clear_ + + mov esi,[ecx-1].pte_ptr + mov edx,[ecx-1].succ_pnode + + cmp esi,edi + jz clear_head_pnode + + DO + push ecx + push edx + call clear_ + pop ecx + pop eax + + test ecx,ecx + EXITZ + + mov esi,[ecx].pte_ptr + mov edx,[ecx].succ_pnode + + cmp esi,edi + REPEATNZ + + IF offset succ_pnode NE 0 + add eax,offset succ_pnode + ENDIF + jmp cleared + OD + FI + + ret + + + +clear_head_pnode: + + inc edx + jmp cleared + + + + + +XHEAD gen_new_maptab + + ke 'gen_new_maptab' + xret ,long + + + + + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; unmap / flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + mov byte ptr [esi],0 + + + + +unmap_page: + + mov edx,esi + mov edi,ds:[linktab_base_PM] + + shr edx,log2_pagesize + mov ecx,ds:[cpu_cr3] + + mov eax,[edx*linksize+edi].pmap_link + sub edx,edx + + test eax,eax + IFNZ + xor esi,512 + xchg edx,[eax+esi] + xor esi,512 + test edx,edx + CANDNZ + + call unmap_tree + + FI + ret + + + +unmap_tree: + + test edx,1 + IFZ + mov dword ptr [edx],0 + mov esi,edx + + shr edx,log2_pagesize + + mov eax,[edx*linksize+edi].pmap_link + mov edx,[edx*linksize+edi].pdir_link + + xor edx,ecx + + shr edx,1 + xc be,unmap_in_own_address_space + + test eax,eax + IFNZ + sub edx,edx + xchg edx,[eax+esi] + test edx,edx + jnz unmap_tree + FI + ret + FI + + dec edx + DO + push edx + mov edx,[edx].pte_ptr + call unmap_tree + pop edx + + mov eax,edx + mov edx,[edx].succ_pnode + + test edx,edx + REPEATNZ + OD + + mov edx,ds:[free_pnode_root] + mov [eax].succ_pnode,edx + mov ds:[free_pnode_root],eax + + ret + + + +XHEAD unmap_in_own_address_space + + mov [ebp+tlb_flush_indicator],2 + xret + + + +unmap_write_page: + +flush_write_page: + + ke 'u/f_write_page' + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+PM + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+PM + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + +;---------------------------------------------------------------------------- +; +; remove_from_sigma0_and_pmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frame completely erased in ur ptab (avoids delayed clear) +; ptab_link of frame in linktab reset to 0 +; +;---------------------------------------------------------------------------- + + +remove_from_sigma0_and_pmap: + + push eax + push ecx + + shr eax,log2_pagesize + imul eax,linksize + add eax,ds:[linktab_base] + sub ecx,ecx + xchg ecx,[eax] + sub eax,eax + mov [ecx],eax + + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov edi,ds:[linktab_base] + + mov ebx,eax + + mov ecx,ds:[((sigma0_task AND mask task_no) + offset tcb_space)].task_pdir + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + or dl,page_accessed+page_dirty + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + + mov edx,eax + shr edx,log2_pagesize + + mov [edx*linksize+edi].pdir_link,ecx + + push eax + mov ecx,eax + and ecx,-pagesize + call request_fresh_frame + sub eax,ecx + mov [edx*linksize+edi].pmap_link,eax + pop eax + + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov eax,ebx + shr eax,log2_pagesize + mov [eax*linksize+edi].ptab_link,ecx + + + ELIFB ebx,max_physical_memory_size + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*linksize+edi].pdir_link,ecx + popad + + FI + + mov bl,dl + mov [ecx],ebx + + + popad + ret + + + + + icod ends + + + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernel/proj.err b/l4-x86/l4-4test/kernel/proj.err new file mode 100644 index 0000000..c0e3337 --- /dev/null +++ b/l4-x86/l4-4test/kernel/proj.err @@ -0,0 +1,52 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd d:\l4-31\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +D:\l4-31\src\kernel> + + cd d:\l4-31\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +D:\l4-31\src\kernel> + + cd d:\l4-31\bin-pent + link @ln4.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-4test/kernel/sgmctr.asm b/l4-x86/l4-4test/kernel/sgmctr.asm new file mode 100644 index 0000000..2b594d6 --- /dev/null +++ b/l4-x86/l4-4test/kernel/sgmctr.asm @@ -0,0 +1,277 @@ +include l4pre.inc + + Copyright GMD, L4.SGMCTR, 24,12,97, 300 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.02.90 ****** +;****** modified: 24.12.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + extrn physical_kernel_info_page:dword + + + + + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include kpage.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + (highword ((dsize SHR 12)-1)) SHL 8) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS linear_kernel_space_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + add ds:[physical_kernel_info_page].kdebug_exception,PM + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6+PM,linear_kernel_space_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + pop eax + add eax,PM + jmp eax + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type EQ i486 + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 08 : cpu0_tss + descriptor rw32, dpl2, PM, ; 10 : phys_mem + + descriptor xr32, dpl0, 0, ; 18 : phys_exec + ; dw lowword (KB64-1) ; 18 : phys_exec + ; dw lowword PM + ; db low highword PM + ; db low (xr32+dpl0+80h) + ; db high xr32 + ; db high highword 0 ; PM + descriptor rw32, dpl0, 0, ; 20 : linear_kernel_space + + descriptor rw32, dpl3, 0, user_space_size ; 28 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 30 : linear space + + + + + +end_of_initial_gdt equ $ + + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-4test/kernel/sigma0-rtas.asm b/l4-x86/l4-4test/kernel/sigma0-rtas.asm new file mode 100644 index 0000000..3337436 --- /dev/null +++ b/l4-x86/l4-4test/kernel/sigma0-rtas.asm @@ -0,0 +1,768 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.sigma0 , 20,04,97, 200 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** special RT version Author: J.Liedtke ****** +;****** ****** +;****** created: 24.09.95 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + +include rtcache.inc + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include msgmac.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dd 4 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + + + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop eax + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],eax + + mov eax,[eax+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + sub eax,eax + dec eax + + + + sub esi,esi + sub eax,eax + + DO + push ebp + sub ecx,ecx + mov edi,esi + mov esi,waiting_any + int ipc3 + pop ebp + + cmp eax,ipc_control_mask + mov eax,esi + REPEATA + + and eax,mask task_no + and edx,NOT 10b + + ror eax,task_no-8 + + cmp eax,dedicated_mem SHL 8 + REPEATAE + + test edx,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + REPEAT + + ELIFZ ah,kernel_task_no + + call grab_free_default_page + add ebx,fpage_grant - fpage_map_read_write + REPEAT + + ELSE_ + call grab_free_default_page + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + mov eax,map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + REPEAT + FI + + IFZ bl,2 + call unmap_4K_page + REPEAT + FI + + call reply_nak + REPEAT + OD + + + +reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_page: + + cmp edx,GB1 + xc ae,perhaps_special_device_4M_frame,long + + and edx,-pagesize + + push edx + + IFAE esi,booter_task + CANDB esi, + CANDA edx,KB64 + + IF partitioning_strategy EQ unpartitioned + + mov edi,edx + and edi,-MB16 + and edx,(KB128-1) AND -pagesize + shr edi,24-17 + lea edx,[edi+edx+MB1] + + ELSE + + mov edi,edx + shr edi,24 + and edi,L2_cache_colors/2-1 + add edi,L2_cache_colors/2 + IFAE esi,sigma2_task + add edi,L2_cache_colors/4 + FI + and edx,(KB128-1) AND -pagesize + imul edx,L2_cache_colors + shl edi,log2_pagesize + lea edx,[edi+edx+MB1] + + ENDIF + + ELIFAE esi,sigma2_task + CANDB esi, + CANDA edx,KB64 + + IF partitioning_strategy EQ partitioned + test edx,(L2_cache_colors/2)*pagesize + IFNZ + add edx,KB512-(L2_cache_colors/2)*pagesize + FI + ENDIF + FI + + + + + + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + mov al,[edi+ebx] + + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + + mov [edi+ebx],ah + + lea ebx,[edx+log2_pagesize*4 + fpage_map_read_write] + pop edx + + mov eax,map_msg + ret + FI + FI + + pop edx + call reply_nak + ret + + + + +XHEAD perhaps_special_device_4M_frame + + cmp edx,3*GB1 + xret ae ,long + + mov ebx,edx + and ebx,-1 SHL 22 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + +grab_specific_4M_or_4K_page: + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + cmp ecx,MB4/pagesize + jb grab_specific_page + + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + jnz grab_specific_page + + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + DO + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + lea edx,[edi+1] + sub edx,[ebp+memmap_descriptor].mem_begin + and edx,L2_cache_colors-1 + cmp edx,L2_cache_colors/2 + REPEATAE + + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + add ebx,log2_pagesize*4 + fpage_map_read_write + + mov eax,map_msg + ret + FI + OD + + call reply_nak + ret + + + + +;---------------------------------------------------------------------------- +; +; unmap 4K page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX 0 +; +;---------------------------------------------------------------------------- + + +unmap_4K_page: + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + and edx,-pagesize + mov al,[edi+ebx] + + IFZ al,ah + + ; mov byte ptr [edi+ebx],free_mem + + pushad + mov eax,edx + and eax,-pagesize + add eax,12*4+2 + mov cl,0FFh + int fpage_unmap + popad + FI + FI + + sub eax,eax + ret + + + + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad ;Ž90-09-15 + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad ;...Ž + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-4test/kernel/sigma0.asm b/l4-x86/l4-4test/kernel/sigma0.asm new file mode 100644 index 0000000..99c3237 --- /dev/null +++ b/l4-x86/l4-4test/kernel/sigma0.asm @@ -0,0 +1,708 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.sigma0 , 20,04,97, 200 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 24.09.95 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include msgmac.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dd 4 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + + + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop eax + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],eax + + mov eax,[eax+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + sub eax,eax + dec eax + + + + sub esi,esi + sub eax,eax + + DO + push ebp + sub ecx,ecx + mov edi,esi + mov esi,waiting_any + int ipc3 + pop ebp + + cmp eax,ipc_control_mask + mov eax,esi + REPEATA + + and eax,mask task_no + and edx,NOT 10b + + ror eax,task_no-8 + + cmp eax,dedicated_mem SHL 8 + REPEATAE + + test edx,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + REPEAT + + ELIFZ ah,kernel_task_no + + call grab_free_default_page + add ebx,fpage_grant - fpage_map_read_write + REPEAT + + ELSE_ + call grab_free_default_page + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + mov eax,map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + REPEAT + FI + + IFZ bl,2 + call unmap_4K_page + REPEAT + FI + + call reply_nak + REPEAT + OD + + + +reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_page: + + cmp edx,GB1 + xc ae,perhaps_special_device_4M_frame + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + and edx,-pagesize + mov al,[edi+ebx] + + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + + mov [edi+ebx],ah + lea ebx,[edx+log2_pagesize*4 + fpage_map_read_write] + + mov eax,map_msg + ret + FI + FI + + call reply_nak + ret + + + + +XHEAD perhaps_special_device_4M_frame + + cmp edx,3*GB1 + xret ae + + mov ebx,edx + and ebx,-1 SHL 22 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + +grab_specific_4M_or_4K_page: + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + cmp ecx,MB4/pagesize + jb grab_specific_page + + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + jnz grab_specific_page + + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + add ebx,log2_pagesize*4 + fpage_map_read_write + + mov eax,map_msg + ret + FI + + call reply_nak + ret + + + + +;---------------------------------------------------------------------------- +; +; unmap 4K page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX 0 +; +;---------------------------------------------------------------------------- + + +unmap_4K_page: + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + and edx,-pagesize + mov al,[edi+ebx] + + IFZ al,ah + + ; mov byte ptr [edi+ebx],free_mem + + pushad + mov eax,edx + and eax,-pagesize + add eax,12*4+2 + mov cl,0FFh + int fpage_unmap + popad + FI + FI + + sub eax,eax + ret + + + + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad ;Ž90-09-15 + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad ;...Ž + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-4test/kernel/start.asm b/l4-x86/l4-4test/kernel/start.asm new file mode 100644 index 0000000..fc91bee --- /dev/null +++ b/l4-x86/l4-4test/kernel/start.asm @@ -0,0 +1,395 @@ +include l4pre.inc + + + + Copyright GMD, L4.START, 19,07,96, 28 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 04.03.91 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for i486,pentium,ppro,k6 + + IF kernel_type NE i486 + extrn init_apic:near + ENDIF + + IF kernel_type NE i486 + extrn init_small_address_spaces:near + ENDIF + + IF kernel_x2 + extrn prepare_dual_processor_init:near + extrn init_dual_processor:near + extrn dual_link_table:dword + ENDIF + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + dd 0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd 0,0 ; 1030 ; sigma1 ESP, EIP + dd 0,0 + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + dd ktest1_stack,ktest1_start ; 1050 ; sigma2 ESP, EIP + dd ktest_begin,ktest_end + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+L4_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+L4_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+L4_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + + + +kernel_start_x2: + + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + + call init_memctr + call enable_paging_mode + call init_sgmctr + call init_intctr + + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + IF kernel_type NE i486 + call init_small_address_spaces + ENDIF + + call init_emuctr + call init_basic_hw_interrupts + + IF kernel_type EQ i486 + call init_rtc_timer + ELSE + bt ds:[cpu_feature_flags],on_chip_apic_bit + IFC + call init_apic + ELSE_ + call init_rtc_timer + FI + ENDIF + + IF kernel_x2 + call init_dual_processor + ENDIF + + ke 'debug' + + cli + + include pagmac.inc + + mov ebx,offset gdt+(linear_kernel_space AND -8) + mov eax,cr3 + and eax,-pagesize + xpdir ecx,ebx + mov eax,dword ptr [eax+ecx*4+PM] + and eax,-pagesize + xptab ecx,ebx + mov eax,dword ptr [eax+ecx*4+PM] + and eax,-pagesize + and ebx,pagesize-1 + lea ebp,[eax+ebx+PM] + +; DO +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov ebx,eax +; mov edi,linear_kernel_space +; mov ebp,linear_space +; rdtsc +; mov ecx,eax +; mov ds,edi +; rdtsc +; sub eax,ecx +; sub eax,ebx +; mov ecx,eax +; ;; add ds:[ldt+(linear_space AND -8)],0 +; ;; add dword ptr ss:[ebp-(linear_kernel_space AND -3)],0 +; +; rdtsc +; mov esi,eax +; mov ds,ebp +; mov ds,edi +; mov eax,phys_mem +; mov ds,eax +; rdtsc +; sub eax,esi +; sub eax,ebx +; mov esi,eax +; ke 'xx' +; ;; REPEAT +; OD + + + push linear_kernel_space + pop ds + + call init_sigma0_1 + call ptabman_init + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma2_task + mov ebx,offset sigma2_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/startpc.asm b/l4-x86/l4-4test/kernel/startpc.asm new file mode 100644 index 0000000..4d63272 --- /dev/null +++ b/l4-x86/l4-4test/kernel/startpc.asm @@ -0,0 +1,1285 @@ +include l4pre.inc + + + + Copyright GMD, L4.START.PC, 30,05,96, 46 + +;********************************************************************* +;****** ****** +;****** L4 START.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** created: 03.12.87 ****** +;****** modified: 30.05.96 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + +.nolist +include l4const.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; L4-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop ecx ; + sub ecx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [ecx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [ecx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [ecx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [ecx+main_mem+physical_kernel_info_page].mem_end,eax + + + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If L3 kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + +reloc1: + + mov edi,start_offset + lea esi,[edi+ecx] + mov ecx,offset continue_after_relocation-start_offset + shr ecx,2 + cld + rep movsd + + mov eax,offset reloc2 + jmp eax + +reloc2: + + mov ecx,offset max_kernel_end + sub ecx,offset continue_after_relocation-start_offset + shr ecx,2 + cld + rep movsd + + jmp $+2 ; flush prefetch que, because next code parts just moved + ; to position 'continue_after_relocation' + align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + +;---------------------------------------------------------------------------- +; +; start L4 +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; L3 BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; L3 kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + inrtc 0 + + in al,sys_port_b ;Ž90-10-21... + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure ;...Ž + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure+PM + call define_idt_gate + + ret + + + icod ends + + + + + +memory_failure_text db ' : MEMORY_FAILURE' ;Ž90-10-21 + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + mov eax,phys_mem + mov ds,eax + + mov al,00001001b ; alpha, 80*25 + mov dx,3D8h ; + out dx,al ; + + mov esi,offset memory_failure_text + in al,sys_port_b ;Ž90-10-21... + shr al,iochk_signal_bit + add al,'0' + mov [esi],al ;...Ž + mov ecx,sizeof memory_failure_text + mov ah,0F0h + call direct_console_out + + jmp $ + + + + + + ;Ž90-09-15... +;---------------------------------------------------------------------------- +; +; direct console out +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AH attribute +; ESI +; ECX string length > 0 +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +direct_console_out: + + pushad + + sub edi,edi + DO + mov al,[esi] + mov [edi+0B8000h],ax + mov [edi+0B0000h],ax + mov [edi+0A0000h],ax + add edi,2 + inc esi + RLOOP + OD + + popad + ret + ;Ž90-09-15 + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + out pic1_icw4,al ; special fully nested mode !! + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher+PM + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int+PM + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line ;Ž90-06-01 + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + inrtc rtc_seconds + mov ah,al + DO + inrtc rtc_seconds + cmp ah,al + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + + mov ss:[esp+iret_code],3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start diff --git a/l4-x86/l4-4test/kernel/tables.asm b/l4-x86/l4-4test/kernel/tables.asm new file mode 100644 index 0000000..7027133 --- /dev/null +++ b/l4-x86/l4-4test/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include adrspace.inc +page +include uid.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/tcbman.asm b/l4-x86/l4-4test/kernel/tcbman.asm new file mode 100644 index 0000000..c796da3 --- /dev/null +++ b/l4-x86/l4-4test/kernel/tcbman.asm @@ -0,0 +1,841 @@ +include l4pre.inc + + + Copyright GMD, L4.TCBMAN, 31,12,96, 200 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 07.03.90 ****** +;****** modified: 03.07.96 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_kernel_thread + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn refresh_reallocate:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include intrifc.inc +include tcb.inc +.nolist +include cpucb.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for i486,pentium,ppro,k6 + + + assume ds:codseg + + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc+PM + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + call rerun_thread + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +; EAX,EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + mov edx,ebp ; be mult inserted into sndq + and edx,-(lthreads*sizeof tcb) + test__page_writable edx + IFNC + mov ebx,[edx+task_pdir] + test ebx,ebx + CANDNZ + mov ecx,[edx+thread_proot] + mov al,[edx+small_as] + ELSE_ + mov ebx,ds:[empty_proot] + mov ecx,ebx + mov al,0 + FI + mov [ebp+task_pdir],ebx + mov [ebp+thread_proot],ecx + mov [ebp+small_as],al + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter.low +; EBP preempter.high / FFFFFFFF +; ESI pager.low +; EDI pager.high / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter.low +; EBP preempter.high +; ESI pager.low +; EDI pager.high +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + push ebp + + mov ebp,esp + and ebp,-sizeof tcb + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ eax,ready + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_eip + FI + + pop eax + + cmp___eax -1 + IFNZ + xchg ebx,[ebp+int_preempter] + xchg eax,[ebp+int_preempter+4] + ELSE_ + mov ebx,[ebp+int_preempter] + mov eax,[ebp+int_preempter+4] + FI + + IFNZ edi,-1 + xchg esi,[ebp+pager] + xchg edi,[ebp+pager+4] + ELSE_ + mov esi,[ebp+pager] + mov edi,[ebp+pager+4] + FI + + mov ebp,[ebp+kernel_stack_bottom-sizeof int_pm_stack].ip_eflags + + xchg eax,ebp + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + + pop ecx + + lea esi,[ebp+kernel_stack_bottom-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret+PM + + IF kernel_type NE i486 + + mov dword ptr [esi+4],linear_space + + ENDIF + + movi eax,ready + mov [ebp+thread_state],eax + mark__ready ebp + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + xc z,reset_own_thread + + push ecx + test [ebp+resources],NOT is_polled + jnz refresh_reallocate + ret + + + + +XHEAD reset_own_thread + + xor esp,esi + xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager (low) +; EDI pager (high) +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id (low) +; EDI new thread id (high) +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; mov edi,[eax+pager+4] +; FI + mov [ebp+pager],esi + mov [ebp+pager+4],edi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov esi,[eax+myself] + and esi,mask ver1 + mask ver0 + mov edi,[eax+chief] + ELSE_ + movi esi,initial_version + movi edi,root_chief + FI + mov ebx,ebp + and ebx,mask task_no+mask lthread_no + add esi,ebx + mov [ebp+myself],esi + mov [ebp+chief],edi + + pop eax + + lea ebx,[ebp+kernel_stack_bottom-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret+PM + IF kernel_type NE i486 + mov [ebx+ip_ds+4],linear_space + ENDIF + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+thread_state],ready + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + mov [ebp+chief],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; rerun thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread restarted +; +;---------------------------------------------------------------------------- +; +; align 4 +; +; +; +rerun_thread: + + ret + +; +; pushad +; +; mov eax,[ebp+thread_esp] +; test al,11b +; CORNZ +; sub eax,edx +; CORB eax, +; IFA eax, +; ke 'inv_tcb_rerun' +; FI +; +; lea___ip_bottom ebx,ebp +; +; mov eax,[ebx+ip_error_code] +; +; IFB_ eax, +; lea ecx,[ebx+ip_error_code] +; call ipcman_rerun_thread +; ELSE_ +; mov ecx,ebx +; IFZ eax,trap1 +; sub [ebx+ip_eip],1 +; ELIFZ eax,trap2 +; sub [ebx+ip_eip],2 +; ELIFZ eax,trap6 +; sub [ebx+ip_eip],6 +; ELIFZ eax,trap8 +; sub [ebx+ip_eip],8 +; FI +; lea ecx,[ebx-4] +; mov dword ptr [ebx-4],offset rerun_iret +; FI +; mov eax,ecx +; and eax,sizeof tcb-1 +; add eax,edx +; mov [ebp+thread_esp],eax +; +; call cpuctr_rerun_thread +; +; mov [esp+2*4],ebp +; popad +; ret +; +; +; +; +;rerun_iret: +; +; ipost +; + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/x.asm b/l4-x86/l4-4test/kernel/x.asm new file mode 100644 index 0000000..b7970ee --- /dev/null +++ b/l4-x86/l4-4test/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +include pagmac.inc +page +include syscalls.inc +page +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernel/x2ctr.as5 b/l4-x86/l4-4test/kernel/x2ctr.as5 new file mode 100644 index 0000000..38310ce --- /dev/null +++ b/l4-x86/l4-4test/kernel/x2ctr.as5 @@ -0,0 +1,650 @@ +include l4pre.inc + + + + Copyright GMD, L4.X2CTR.5, 19,01,97, 1 + +;********************************************************************* +;****** ****** +;****** Kernel x2 Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 19.01.97 ****** +;****** modified: 19.01.97 ****** +;****** ****** +;********************************************************************* + + + public init_dual_processor + public prepare_dual_processor_init + public dual_link_table + public generate_x2_info_page + public enter_single_processor_mode + public exit_single_processor_mode + + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack2:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack2:dword,ktest0_start:near + extrn ktest1_stack2:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + + extrn kernel_start_x2:near + + + + +.nolist +include l4const.inc +include l4kd.inc +include adrspace.inc +include intrifc.inc +include uid.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for pentium,ppro + + + +;********************************************************************* +;****** ****** +;****** Dual Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + +;; icode + + + assume ds:codseg + + +;---------------------------------------------------------------------------- +; +; dual link table +; +;---------------------------------------------------------------------------- + + +dual_link_table: + + db 'L4',0E6h,'K' + db current_kpage_version + db 0,0,0 + dd 0,0 + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack2,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd 0,0 ; 1030 ; sigma1 ESP, EIP + dd 0,0 + + dd ktest0_stack2,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + dd ktest1_stack2,ktest1_start ; 1050 ; sigma2 ESP, EIP + dd ktest_begin,ktest_end + + dd 0,0 ; main_mem ; 1060 +;; dd 0,0 ; reserved_mem0 + dd 0,MB16 ; reserved_mem0 + + dd 0,0 ; reserved_mem1 ; 1070 + dd 0,0 ; dedicated_mem0 + + dd 0,0 ; dedicated_mem1 ; 1080 + + dd 0A0000h,MB1 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 + ;; dd MB32,GB1 + + dd 0,0,0,0 ; 10A0 ; user clock + + + + +;--------------------------------------------------------------------- +; +; single processor mutex +; +;--------------------------------------------------------------------- + +single_processor_mutex db 0FFh + +single_processor_depth db 0 + + + + +;--------------------------------------------------------------------- +; +; init second processor +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + + +prepare_dual_processor_init: + + lea eax,[esp-32*4] + mov [initial_esp],eax + + sgdt [initial_gdt_vec] + sidt [initial_idt_vec] + mov [initial_cs],cs + mov [initial_ds],ds + str [initial_tss] + + ret + + + + + +init_dual_processor: + + bt ds:[cpu_feature_flags],on_chip_apic_bit + IFC + lno___prc eax + test eax,eax + CANDZ + + sub eax,eax + mov byte ptr ds:[eax],0E9h ; jmp + mov ebx,offset dual_processor_start-3 + mov word ptr ds:[eax+1],bx + + mov ds:[local_apic+apic_icr],apic_startup_msg + 0 + + mov eax,1000000 + DO + dec eax + REPEATNZ + OD + + FI + ret + + + + +;--------------------------------------------------------------------- +; +; dual processor start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; real mode +; +; CS 0 +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + + +dual_processor_start: + + asp + osp + mov esp,cs:[initial_esp] + + asp + lgdt cs:[initial_gdt_vec] + asp + lidt cs:[initial_idt_vec] + + mov eax,cr0 + or al,1 + mov cr0,eax + + osp + db 0EAh ; jmp far + dd offset protected_mode +initial_cs dw 0 + + +protected_mode: + + movzx eax,cs:[initial_ds] + mov ds,eax + mov ss,eax + mov es,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + mov bl,1 + lock xadd [processor_no],bl + + IFA bl,1 + DO + hlt + REPEAT + OD + FI + + movzx eax,[initial_tss] + mov ecx,dword ptr [initial_gdt_vec+2] + and byte ptr [eax+ecx+5],NOT (1 SHL (9-8)) ; reset busy bit in tss descriptor + + add al,bl + ltr ax + + jmp kernel_start_x2 + + + + + +initial_ds dw 0 + +initial_esp dd 0 + +initial_gdt_vec df 0 +initial_idt_vec df 0 + +initial_tss dw 0 + +processor_no db 1 + + + +;--------------------------------------------------------------------- +; +; generate x2 info page +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; EDX processor number +; EDI old kernel info page (physical address) +; +; DS,ES phys mem +; +; interrupts disabled +; +;--------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI new kernel info page (physical address} +; +; EAX,EBX,ECX,EBP,ESI scratch +; +;--------------------------------------------------------------------- + + + +generate_x2_info_page: + + mov esi,offset dual_link_table + + mov eax,ds:[edi+main_mem].mem_begin + mov ds:[esi+main_mem].mem_begin,eax + mov eax,ds:[edi+main_mem].mem_end + mov ds:[esi+main_mem].mem_end,eax + + mov ch,kpage_mem_regions + DO + lea ebx,[esi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [ebx].mem_end,eax + CANDB [ebx].mem_begin,eax + mov eax,[ebx].mem_begin + FI + add ebx,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ebx,edi + lea edi,[eax-KB4] + + + mov ds:[esi+reserved_mem1].mem_begin,edi + IFB_ ds:[esi+reserved_mem1].mem_end,eax + mov ds:[esi+reserved_mem1].mem_end,eax + FI + + + lno___prc eax + test eax,eax + IFNZ + DO + mov eax,[ebx+cpu_clock_freq] ; wait until first processor + test eax,eax ; has determined cpu clock + REPEATZ ; frequency + OD + FI + + + push edi + + mov ecx,offset user_clock + cld + rep movsb + lea esi,[ebx+user_clock] + mov ecx,pagesize-offset user_clock + rep movsb + + pop edi + + mov ds:[ebx+next_kpage_link],edi + + ret + + + + +;--------------------------------------------------------------------- +; +; enter/exit single processor mode +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + + +enter_single_processor_mode: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[single_processor_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[single_processor_depth] + + pop ecx + pop eax + ret + + +exit_single_processor_mode: + + dec ds:[single_processor_depth] + IFZ + mov ds:[single_processor_mutex],0FFh + FI + + ret + + + + +;; icod ends + + + +;------------------------------------ +; +; IRQ10 on P6 dual workaround +; +;------------------------------------ + + public p6_workaround_init + public p6_workaround_open_irq + + + extrn define_idt_gate:near + + + + +p6_workaround_init: + + pushad + + lno___prc eax + test eax,eax + IFZ + mov eax,offset x9_handler+PM + mov bl,20h+9 + mov bh,0 SHL 5 + call define_idt_gate + + mov eax,offset x10_handler+PM + mov bl,20h+10 + mov bh,0 SHL 5 + call define_idt_gate + + mov eax,offset x11_handler+PM + mov bl,20h+11 + mov bh,0 SHL 5 + call define_idt_gate + + mov eax,offset x15_handler+PM + mov bl,20h+15 + mov bh,0 SHL 5 + call define_idt_gate + FI + + popad + ret + + + +p6_workaround_open_irq: + + push eax + push ecx + + mov al,0FEh + IFAE ecx,8 + sub ecx,8 + in al,0A1h + btr eax,ecx + out 0A1h,al + ELSE_ + in al,21h + btr eax,ecx + out 21h,al + FI + + pop eax + pop edx + ret + + + + + + + +wait_for_apic_ready: + + pushad + mov edi,100000 + DO + sub eax,eax + + cpuid + mov eax,ss:[local_apic+apic_icr] + test eax,1 SHL 12 + EXITZ + dec edi + REPEATNZ + ke 'sa100000' + OD + popad + ret + + +x9_handler: + + push eax + + mov eax,ss:[local_apic+apic_id] + xor eax,01000000h + mov ss:[local_apic+apic_icr+10h],eax + mov dword ptr ss:[local_apic+apic_icr],4029h + + call wait_for_apic_ready + + pop eax + iretd + + mov al,0Bh ; read isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,NOT (1 SHL (9-8)) + IFZ + mov al,60h+2 + out 20h,al + FI + mov al,60h+9-8 + out 0A0h,al + + pop eax + iretd + + + +x10_handler: + + push eax + + mov eax,ss:[local_apic+apic_id] + xor eax,01000000h + mov ss:[local_apic+apic_icr+10h],eax + mov dword ptr ss:[local_apic+apic_icr],402Ah + + call wait_for_apic_ready + + pop eax + iretd + + + mov al,0Bh ; read isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,NOT (1 SHL (10-8)) + IFZ + mov al,60h+2 + out 20h,al + FI + mov al,60h+10-8 + out 0A0h,al + + pop eax + iretd + + + +x11_handler: + + push eax + + mov eax,ss:[local_apic+apic_id] + xor eax,01000000h + mov ss:[local_apic+apic_icr+10h],eax + mov dword ptr ss:[local_apic+apic_icr],402Bh + + call wait_for_apic_ready + + pop eax + iretd + + + mov al,0Bh ; read isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,NOT (1 SHL (11-8)) + IFZ + mov al,60h+2 + out 20h,al + FI + mov al,60h+11-8 + out 0A0h,al + + pop eax + iretd + + + + +x15_handler: + + push eax + + mov eax,ss:[local_apic+apic_id] + xor eax,01000000h + mov ss:[local_apic+apic_icr+10h],eax + mov dword ptr ss:[local_apic+apic_icr],402Fh + + call wait_for_apic_ready + + pop eax + iretd + + + mov al,0Bh ; read isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,NOT (1 SHL (15-8)) + IFZ + mov al,60h+2 + out 20h,al + FI + mov al,60h+15-8 + out 0A0h,al + + pop eax + iretd + + + + + + code ends + end diff --git a/l4-x86/l4-4test/kernifc/adrspac4.inc b/l4-x86/l4-4test/kernifc/adrspac4.inc new file mode 100644 index 0000000..60d2d9b --- /dev/null +++ b/l4-x86/l4-4test/kernifc/adrspac4.inc @@ -0,0 +1,172 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB+512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ( 64*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ( 88*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2*32 is ok , since only used for segment descriptor construction. + + + +kernel_firewall_size equ KB4 + +auxiliary_address_space struc + + db offset tcb_space dup (?) + + kernel_firewall db kernel_firewall_size dup (?) + + db offset ptab_space-offset tcb_space-KB4 dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset tcb_space +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 1 + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00B65000h-KB4 dup (?) + + logical_info_page db KB4 dup (?) + + db 280h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd 2048*dwords_per_task_proot dup (?) ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset task_proot+sizeof task_proot) ; masm611 bug + +.erre kernel_r_tables_size LE (offset kernel_resident_tables+kernel_resident_tab_size) + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd 0 + kernel_proot dd 0 + sigma0_proot dd 0 + +special_proots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) diff --git a/l4-x86/l4-4test/kernifc/adrspac5.inc b/l4-x86/l4-4test/kernifc/adrspac5.inc new file mode 100644 index 0000000..b01f648 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/adrspac5.inc @@ -0,0 +1,177 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ (128*MB) + + reserved_space_1_size equ ( 92*MB) + + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + + reserved_space_2_size equ (4*MB-(8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + + reserved_space_3 db 00BF3000h-4*KB4 dup (?) + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h dup (?) + gdt dd 8*2*4/4 dup (?) + dd 2*2*4/4 dup (?) + db 8 dup (?) + idt dd (40h-1)*8/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + ; | + empty_proot dd 2 dup (?) + kernel_proot dd 2 dup (?) + sigma0_proot dd 2 dup (?) + highest_task dd 1 dup (?) + dd 1 dup (?) + + small_associated_task dd max_small_spaces dup (?) ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + +.erre kernel_r_tables_size LE (offset kernel_resident_tables+kernel_resident_tab_size) + + + + diff --git a/l4-x86/l4-4test/kernifc/adrspace.inc b/l4-x86/l4-4test/kernifc/adrspace.inc new file mode 100644 index 0000000..00e3d1f --- /dev/null +++ b/l4-x86/l4-4test/kernifc/adrspace.inc @@ -0,0 +1,76 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + IF target EQ 486 + +subtitle L4/486 + +kernel_type = i486 + +gver = 3 + +kernel_x2 = 0 + + +include adrspac4.inc + + + ENDIF + + + + IF target EQ pentium + +subtitle L4/Pentium + +kernel_type = pentium + +kernel_char = '5' + +gver = 3 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + IF target EQ pentium_x2 + +subtitle L4/Pentium/x2 + +kernel_type = pentium + +gver = 3 + +kernel_x2 = 2 + + +include adrspac5.inc + + + ENDIF + + + + IF target EQ amd_k6 + +subtitle L4/K6 + +kernel_type = amd_k6 + +gver = 3 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + diff --git a/l4-x86/l4-4test/kernifc/apic.inc b/l4-x86/l4-4test/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-4test/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/cpucb.inc b/l4-x86/l4-4test/kernifc/cpucb.inc new file mode 100644 index 0000000..24d1787 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/cpucb.inc @@ -0,0 +1,21 @@ + + IF kernel_type EQ i486 + +include cpucb4.inc + + ENDIF + + + IF kernel_type EQ pentium + +include cpucb5.inc + + ENDIF + + + IF kernel_type EQ k6 + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/l4-4test/kernifc/cpucb4.inc b/l4-x86/l4-4test/kernifc/cpucb4.inc new file mode 100644 index 0000000..6e8dc86 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/cpucb4.inc @@ -0,0 +1,294 @@ + +uniprocessor equ off + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + actual_co1_tcb dd 0 ; tss_ss1 + + dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.erre (offset cpu_iopbm+2+4) LE (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + +;---------------------------------------------------------------------------- + + + IF uniprocessor + extrn fast_switch:near + ENDIF + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'resources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+resources],0 + jnz deallocate_resources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + +switch_thread_fast macro src_tcb + + IF uniprocessor + + IFDIF , + mov edi,src_tcb + ENDIF + + public fast_switch + fast_switch: + call deallocate_resources + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [edi+thread_esp],esp + mov esp,[ebp+thread_esp] + + ELSE + switch_thread + ENDIF + + endm + + +.errnz sizeof pl0_stack AND 0FFh + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*4)+task_proot-(offset tcb_space SHR (task_no-2))] + mov cr3,ebp + + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+resources],mask rscr + IF uniprocessor + mov byte ptr ss:[fast_switch+PM],call_opc + ENDIF + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+resources],NOT mask rscr + IF uniprocessor + IFZ + mov byte ptr ss:[fast_switch+PM],cmp_opc + FI + ENDIF + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND resources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+resources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg,mode + + sub reg,reg + endm + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/cpucb5.inc b/l4-x86/l4-4test/kernifc/cpucb5.inc new file mode 100644 index 0000000..ca0d32f --- /dev/null +++ b/l4-x86/l4-4test/kernifc/cpucb5.inc @@ -0,0 +1,158 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink == IDT 3B (upper 4 bytes) + + cpu_esp0 dd 0 ; tss_esp0 == IDT 3C + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 == IDT 3D + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 == IDT 3E + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 == IDT 3F ipc3 ! + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + amd_feature_flags dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + +mark__ressource macro reg,rscr + + or [reg+resources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+resources],NOT mask rscr + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND resources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + + + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg,mode + + sub reg,reg + endm + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 + + + +amd_syscall_ret_bit equ 10 +amd_int_cmov_bit equ 15 +amd_fp_cmov_bit equ 16 diff --git a/l4-x86/l4-4test/kernifc/intrifc.inc b/l4-x86/l4-4test/kernifc/intrifc.inc new file mode 100644 index 0000000..1e697fd --- /dev/null +++ b/l4-x86/l4-4test/kernifc/intrifc.inc @@ -0,0 +1,382 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0 + iret_code db 0 + db 0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0 + db 0 + iret_aux_state db 0 + +iret_vec ends + + + + IF kernel_type EQ i486 ;----------------------------------------------- + + +int_pm_stack struc + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0 + ip_code db 0 + db 0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + + ELSE ;------------------------------------------------------------------- + + +int_pm_stack struc + + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0 + ip_code db 0 + db 0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0 + db 0 + ip_aux_state db 0 + +int_pm_stack ends + + + ENDIF ;------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + IF kernel_type NE i486 + push ds + IFDIF , + push linear_kernel_space + pop ds + ENDIF + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + lea eax,[esp+sizeof int_pm_stack] + mov ss:[cpu_esp0],eax + IF kernel_type NE i486 + pop ds + ENDIF + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IF kernel_type NE i486 + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + IF kernel_type EQ i486 + + + +tpost macro reg,sg1,sg2 + + IFNB + lea reg,[esp+sizeof iret_vec+4] + mov ds:[cpu_esp0],reg + pop reg + ELSE + mov ss:[esp],eax + lea eax,[esp+sizeof iret_vec+4] + mov ds:[cpu_esp0],reg + pop eax + ENDIF + iretd + + endm + + + ENDIF + + + + + IF kernel_type NE i486 + + + +tpost macro reg,sg1,sg2 + + IFNB + lea reg,[esp+sizeof iret_vec+4] + IFNB + mov ds:[cpu_esp0],reg + ELSE + mov ss:[cpu_esp0],reg + ENDIF + pop reg + ELSE + mov ss:[esp],eax + lea eax,[esp+sizeof iret_vec+4] + IFNB + mov ds:[cpu_esp0],eax + ELSE + mov ss:[cpu_esp0],eax + ENDIF + pop eax + ENDIF + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + iretd + + endm + + + ENDIF + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/kpage.inc b/l4-x86/l4-4test/kernifc/kpage.inc new file mode 100644 index 0000000..31c75d3 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/kpage.inc @@ -0,0 +1,65 @@ +current_kpage_version equ 1 + + +kpage struc + + L4_magic_word dd 0 + L4_version_word dd 0 + L4_label_link db 0 + kpage_version db current_kpage_version + db ?,? + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + sigma2_ktask dd ?,?,?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + diff --git a/l4-x86/l4-4test/kernifc/l3-ktest.asm b/l4-x86/l4-4test/kernifc/l3-ktest.asm new file mode 100644 index 0000000..7c1328f --- /dev/null +++ b/l4-x86/l4-4test/kernifc/l3-ktest.asm @@ -0,0 +1,687 @@ + +include ctrpre + + GMD L3.KTEST, 04.11.94, 30007 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 04.11.94 ****** +;****** ****** +;********************************************************************* + + + + public kernel_test + + + extrn create_pl3_kernel_thread:near + extrn thread_to_v3:near + extrn page_phys_address:near + extrn grab_frame:near + extrn kdebug_outstring:near + extrn kdebug_outchar:near + extrn kdebug_outdec:near + extrn ipc_sc:near + extrn kernel_proot:dword + extrn hw_config_descriptor:byte + + +include ctrconst +include adrspace +include mcb +include tcb +include msg +include intrifc +include cpucb +include schedcb +include lbmac +include pagmac1 +include syscalls + + + + +disp macro string + local xx + + mov eax,offset $+5+5+1 + call kdebug_outstring + jmp short xx + db string +xx: + endm + + + + + + + assume ds:codseg + + + +kernel_test: + + call put_hw_data + + mov al,ds:[cpu_type] + mov [processor],al + + call grab_frame + mov ebx,offset ping_snd_msg+size ping_snd_msg + mov [ebx].str_addr,eax + mov [ebx].buf_addr,eax + mov ebx,offset ping_rcv_msg+size ping_rcv_msg + mov [ebx].str_addr,eax + mov [ebx].buf_addr,eax + call grab_frame + mov ebx,offset pong_snd_msg+size pong_snd_msg + mov [ebx].str_addr,eax + mov [ebx].buf_addr,eax + mov ebx,offset pong_rcv_msg+size pong_rcv_msg + mov [ebx].str_addr,eax + mov [ebx].buf_addr,eax + + mov edx,'gnip' + mov esi,offset ping_stack + mov edi,offset ping + call create_pl3_kernel_thread + + push eax + mov eax,offset task_proot ; by this trick both threads point in fact + mov ebx,kernel_task_no ; to the same (kernel) proot, but address + call page_phys_address ; space switch (CR3 load) will be done + sub eax,PM + mov ebx,[eax+2*4] + mov [eax],ebx + pop eax + mov ebx,kernel_task_no + call page_phys_address + sub eax,PM + mov [eax+proot_ptr],offset task_proot + + mov [ping_tcb],eax + + mov edx,'gnop' + mov esi,offset pong_stack + mov edi,offset pong + call create_pl3_kernel_thread + + + DO + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,-1 + sub edx,edx + sub esi,esi + mov edi,-1 + int ipc + REPEAT + OD + + + + align 16 + + dd 63 dup (0) +ping_stack dd 0 + dd 63 dup (0) +pong_stack dd 0 + + + align 16 +ping_dest_vec dd 0,0,never,never,0,0 + align 16 +ping_snd_msg dd 00007E00h,0,128 dup (0) + dd 0,0,KB4,0 + align 16 +ping_rcv_msg dd 00017E00h,0,128 dup (0) + dd 0,0,KB4,0 + + align 16 +pong_dest_vec dd 0,0,never,never,0,0 + align 16 +pong_snd_msg dd 00007E00h,0,128 dup (0) + dd 0,0,KB4,0 + align 16 +pong_rcv_msg dd 00017E00h,0,128 dup (0) + dd 0,0,KB4,0 + +counter dd 0 + +ping_tcb dd 0 + +processor db 0 + + + align 16 + +test_idt dw 0, linear_space_exec, 0EE00h, 0 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +ncache_refs equ 011110b +locked_bus equ 011100b + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event equ 011b SHL 6 + + +select equ 11h +cnt0 equ 12h +cnt1 equ 13h + + + + + +ping: + + mov al,sys_prc_id_v2 + mov ebx,'gnop' + int 7 + mov ecx,ebx + mov ebx,eax + call thread_to_v3 + mov [ping_dest_vec],ebx + mov [ping_dest_vec+4],ecx + + mov [ping_snd_msg+msg_dope].msg_dwords,0 + mov [ping_snd_msg+msg_dope].msg_strings,0 + mov [pong_snd_msg+msg_dope].msg_dwords,0 + mov [pong_snd_msg+msg_dope].msg_strings,0 + + + disp <13,10,10,'ipc_8 : '> + call ping_100000 + + + disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope].msg_dwords,1 + mov [pong_snd_msg+msg_dope].msg_dwords,1 + call ping_100000 + + + disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope].msg_dwords,32-2 + mov [pong_snd_msg+msg_dope].msg_dwords,32-2 + call ping_100000 + + disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope].msg_dwords,128-2 + mov [pong_snd_msg+msg_dope].msg_dwords,128-2 + call ping_100000 + + mov [ping_snd_msg+msg_dope].msg_dwords,0 + mov [ping_snd_msg+msg_dope].msg_strings,1 + mov [pong_snd_msg+msg_dope].msg_dwords,0 + mov [pong_snd_msg+msg_dope].msg_strings,1 + + disp <13,10,'ipc_1024 : '> + mov [ping_snd_msg+size ping_snd_msg].str_len,1024 + mov [pong_snd_msg+size ping_snd_msg].str_len,1024 + call ping_100000 + + disp <13,10,'ipc_2048 : '> + mov [ping_snd_msg+size ping_snd_msg].str_len,2048 + mov [pong_snd_msg+size ping_snd_msg].str_len,2048 + call ping_100000 + + disp <13,10,'ipc_4096 : '> + mov [ping_snd_msg+size ping_snd_msg].str_len,4096 + mov [pong_snd_msg+size ping_snd_msg].str_len,4096 + call ping_100000 + + DO + ke 'xxx' + REPEAT + OD + + mov ax,080Fh ; invd + IFNZ ,ax + mov word ptr [f0],ax + mov word ptr [f1],ax + mov word ptr [f2],ax + mov word ptr [f3],ax + mov word ptr [f4],ax + mov word ptr [f5],ax + mov word ptr [f6],ax + mov word ptr [f7],ax + disp <13,10,10,'----- mit cache flush ----'> + jmp ping + FI + + + + disp <13,10,'cache used: '> + + mov [ping_snd_msg+msg_dope].msg_dwords,1 + mov [ping_snd_msg+msg_dope].msg_strings,0 + + mov eax,[ping_dest_vec] + leaw__tcb eax,eax + mov ebx,[kernel_proot] + and ebx,-KB4 + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and ebx,-KB4 + xptab ecx,eax + mov ecx,[(ecx*4)+ebx] + and ecx,-KB4 + and eax,(-size tcb AND KB4-1) + or eax,ecx + mov [eax+size pl0_stack-size int_pm_stack + ip_eip],offset cache_count_pl3 + + mov eax,offset ping_rcv_msg + sub ebx,ebx + mov ecx,offset ping_snd_msg + mov edx,[ping_dest_vec] + mov esi,[ping_dest_vec+4] + lea edi,[ebx-1] + + db 0Fh,08h + int ipc + + jmp $ + + + + +cache_count_pl3: + + mov byte ptr ds:[ipc_sc],0E9h ; jmp + mov eax,offset cache_count + sub eax,offset ipc_sc+5 + mov dword ptr ds:[ipc_sc+1],eax + jmp $+2 + int ipc + + +cache_count: + + mov eax,cr0 + bts eax,30 + mov cr0,eax + +cache_is_off: + + mov ebx,02h + sub ecx,ecx + DO + db 0fh,26h,0ebh ; mov tr5,ebx + db 0fh,24h,0e0h ; mov eax,tr4 + bt eax,10 + adc ecx,0 + add ebx,4 + cmp ebx,2048 + REPEATB + OD + + mov eax,ecx + shl eax,4 + sub eax,(offset cache_is_off+15 - offset cache_count_pl3) AND -16 + call kdebug_outdec + disp <' bytes'> + + + DO + ke 'done' + REPEAT + OD + +; disp <13,10,'user_exc : '> +; +; mov eax,offset test_intr +; mov [test_idt],ax +; shr eax,16 +; mov [test_idt+6],ax +; +; sub ebx,ebx +; mov ecx,offset test_idt +; mov edx,size test_idt +; mov al,specop_v2 +; int 7 +; +; mov eax,[ping_tcb] +; inc [eax+mytask] ; preventing kdebug at test intr0 10000 times +; +; mov [counter],100000 +; mov al,get_system_time +; int 7 +; mov edi,eax +; +; sub ebx,ebx +; clign 16 +; div ebx +; ; intr 0 forever + + + +ping_100000: + + mov [counter],100000 + + mov al,get_system_time + int 7 + push eax + + + IFZ [processor],pentium + + mov ecx,select + sub edx,edx + mov eax,r_stall + cnt_event + ((rw_miss + cnt_event) SHL 16) + wrmsr + + sub eax,eax + mov ecx,cnt0 + wrmsr + mov ecx,cnt1 + wrmsr + + rdtsc + FI + push eax + push edx + + + clign 16 + DO + +; db 0Fh,08h + mov eax,offset ping_rcv_msg + sub ebx,ebx + mov ecx,offset ping_snd_msg + mov edx,[ping_dest_vec] + mov esi,[ping_dest_vec+4] + lea edi,[ebx-1] + int ipc +f0: test al,al + EXITNZ +; db 0Fh,08h + mov eax,offset ping_rcv_msg + sub ebx,ebx + mov ecx,offset ping_snd_msg + mov edx,[ping_dest_vec] + mov esi,[ping_dest_vec+4] + lea edi,[ebx-1] + int ipc +f1: test al,al + EXITNZ +; db 0Fh,08h + mov eax,offset ping_rcv_msg + sub ebx,ebx + mov ecx,offset ping_snd_msg + mov edx,[ping_dest_vec] + mov esi,[ping_dest_vec+4] + lea edi,[ebx-1] + int ipc + test al,al +f2: EXITNZ +; db 0Fh,08h + mov eax,offset ping_rcv_msg + sub ebx,ebx + mov ecx,offset ping_snd_msg + mov edx,[ping_dest_vec] + mov esi,[ping_dest_vec+4] + lea edi,[ebx-1] + int ipc +f3: test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop edi + pop esi + pop ebx + + IFZ [processor],pentium + + rdtsc + sub eax,esi + sbb edx,edi + mov edi,200000 + div edi + mov esi,eax + + mov ecx,select + sub eax,eax + sub edx,edx + wrmsr + FI + + pushad + + push ebx + mov al,get_system_time + int 7 + pop ebx + sub eax,ebx + inc eax + shr eax,1 + call microseconds + + popad + + IFZ ds:[processor],pentium + + disp <' cycles/ipc: '> + mov eax,esi + call kdebug_outdec + disp <', events/ipc: cnt0='> + mov ecx,cnt1 + rdmsr + mov esi,eax + mov ecx,cnt0 + rdmsr + div edi + call kdebug_outdec + disp <' cnt1='> + mov eax,esi + sub edx,edx + div edi + call kdebug_outdec + FI + + ret + + + + +pong: + + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,-1 + sub edx,edx + sub esi,esi + mov edi,-1 + int ipc + test al,al + IFNZ + ke 'pong_wait_err' + FI + mov [pong_dest_vec],edx + mov [pong_dest_vec+4],esi + + clign 16 + DO + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,offset pong_snd_msg + lea edi,[ebx-1] + int ipc +f4: test al,al + EXITNZ + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,offset pong_snd_msg + lea edi,[ebx-1] + int ipc +f5: test al,al + EXITNZ + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,offset pong_snd_msg + lea edi,[ebx-1] + int ipc +f6: test al,al + EXITNZ + mov eax,offset pong_rcv_msg+2 + sub ebx,ebx + mov ecx,offset pong_snd_msg + lea edi,[ebx-1] + int ipc +f7: test al,al + REPEATZ + OD + DO + ke 'pong_err' + REPEAT + OD + + + + align 16 + + +;test_intr: +; +; dec [counter] +; IFNZ +; iretd +; FI +; mov al,get_system_time +; int 7 +; sub eax,edi +; call microseconds +; disp <13,10,10,10> +; +; mov ebx,[ping_tcb] +; dec [ebx+mytask] ; reenable kdebug +; DO +; ke 'test' +; REPEAT +; OD + + + + + align 4 + + +microseconds: + + pushad + + sub edx,edx + mov ebx,100 + div ebx + call kdebug_outdec + mov al,'.' + call kdebug_outchar + IFB_ edx,10 + mov al,'0' + call kdebug_outchar + FI + mov eax,edx + call kdebug_outdec + disp <' us'> + + popad + ret + + + +hw_config_descr struc +hw_cpu db ' ' +hw_clock_rate dw 0 ;cpu_speed + dw 0 + dw 0 ;cpu_bus_width + dw 0 + db ' ' ;cache_type +hw_cache_acc_time dw 0 ;cache_speed + dw 0 ; + dd 0 ;cache_size + db ' ' ;ram_type +hw_ram_min_acc_time dw 0 ;ram_speed +hw_ram_max_acc_time dw 0 ; +hw_ram_size dd 0 ;ram_size +hw_co1 db ' ' ;co1_type + dd 0 ;co1_speed + dd 0 ; + db ' ' ;co2_type + dd 0 ;co2_speed + dd 0 ; + db ' ' ;co3_type + dd 0 ;co3_speed + dd 0 ; + db ' ' ; + dd 0 ; + dd 0 ; + db ' ' ; +L2_cache_x dd 0 ; +L2_cache_y dd 0 ; +hw_config_descr ends + + +put_hw_data: + + mov ebx,offset hw_config_descriptor + + disp <13,10,10,'cpu clock: '> + movzx eax,[ebx+hw_clock_rate] + call kdebug_outdec + + disp <'ns',13,10,'L2 cache acc: '> + movzx eax,[ebx+hw_cache_acc_time] + call kdebug_outdec + + disp <'ns, RAM acc: '> + movzx eax,[ebx+hw_ram_min_acc_time] + call kdebug_outdec + disp <'-'> + movzx eax,[ebx+hw_ram_max_acc_time] + call kdebug_outdec + + disp <'ns , L2 Rd256K x:'> + mov eax,[ebx+L2_cache_x] + call kdebug_outdec + disp <', y:'> + mov eax,[ebx+L2_cache_y] + call kdebug_outdec + disp <13,10,10> + + ret + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/l4const.inc b/l4-x86/l4-4test/kernifc/l4const.inc new file mode 100644 index 0000000..f52e3af --- /dev/null +++ b/l4-x86/l4-4test/kernifc/l4const.inc @@ -0,0 +1,100 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants (91-02-23) ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +cpu0_tss equ 0008h +phys_mem equ 0010h + +linear_kernel_space_exec equ 0018h +linear_kernel_space equ 0020h + +linear_space equ (0028h+3) +linear_space_exec equ (0030h+3) + + + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h ;Ž89-11-08 +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 3 +i486 equ 4 +pentium equ 5 +ppro equ 6 +amd_k6 equ 16 +p4 equ i486 +p5 equ pentium +p6 equ ppro +k6 equ amd_k6 + +pentium_x2 equ 200+pentium \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/l4kd.inc b/l4-x86/l4-4test/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-4test/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-4test/kernifc/l4pre.inc b/l4-x86/l4-4test/kernifc/l4pre.inc new file mode 100644 index 0000000..0c401ab --- /dev/null +++ b/l4-x86/l4-4test/kernifc/l4pre.inc @@ -0,0 +1,872 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +scod segment para public use32 'code' +scod ends + +dcod segment para public use32 'code' +dcod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm +EXITPE macro lg +jX jpe,odl,%doNST,lg +endm +EXITPO macro lg +jX jpo,odl,%doNST,lg +endm + + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab+PM +endm + +pret macro lab +push offset xr&lab+PM +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxhl equ ax +ebxhl equ bx +ecxhl equ cx +edxhl equ dx +esihl equ si +edihl equ di +ebphl equ bp +eaxl equ al +ebxl equ bl +ecxl equ cl +edxl equ dl +eaxh equ ah +ebxh equ bh +ecxh equ ch +edxh equ dh +axl equ al +bxl equ bl +cxl equ cl +dxl equ dl +axh equ ah +bxh equ bh +cxh equ ch +dxh equ dh + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + +clign macro alignment,off + +ifb +aax=($-modstart) AND (alignment-1) +else +aax=($-modstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +klign macro alignment,off + +ifb +aax=($-kmodstart) AND (alignment-1) +else +aax=($-kmodstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + + + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +dw ver+gver*1024 +db '(C)' +db '&who&',0 +db '&name&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3,k4 +xok %kernel_type,k1,k2,k3,k4 +endm + +xok macro k,k1,k2,k3,k4 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3,k4 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-4test/kernifc/lbmac.inc b/l4-x86/l4-4test/kernifc/lbmac.inc new file mode 100644 index 0000000..e31803b --- /dev/null +++ b/l4-x86/l4-4test/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-4test/kernifc/pagcb.inc b/l4-x86/l4-4test/kernifc/pagcb.inc new file mode 100644 index 0000000..2c98aca --- /dev/null +++ b/l4-x86/l4-4test/kernifc/pagcb.inc @@ -0,0 +1,23 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + linktab_base dd 0 + linktab_base_PM dd 0 + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + IF kernel_type NE i486 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + ENDIF + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/pagconst.inc b/l4-x86/l4-4test/kernifc/pagconst.inc new file mode 100644 index 0000000..c2162e3 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/pagconst.inc @@ -0,0 +1,86 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + +IF kernel_type EQ i486 +M4_page_bit equ 11 +ENDIF + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + +IF kernel_type EQ i486 +M4_page equ (1 SHL M4_page_bit) +ENDIF + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-4test/kernifc/pagmac.inc b/l4-x86/l4-4test/kernifc/pagmac.inc new file mode 100644 index 0000000..19de909 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/pagmac.inc @@ -0,0 +1,121 @@ +;---------------------------------------------------------------------------- +; +; linktab +; +;---------------------------------------------------------------------------- + + +linktab_entry_for_ptab struc + + pmap_link dd 0 + pdir_link dd 0 + +linktab_entry_for_ptab ends + + +linktab_entry_for_data_page struc + + ptab_link dd 0 + dd 0 + +linktab_entry_for_data_page ends + + + +linksize equ (sizeof linktab_entry_for_ptab) + + + + + +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + + IF kernel_type NE i486 + + + +store_inactive_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot],reg + mov ds:[(task_no*8)+task_proot+4],0 + endm + + +chnge_proot macro reg,task_no + + test byte ptr ds:[(task_no*8)+task_proot+3],80h + IFZ + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot].proot_ptr,reg + mov edi,task_no + call update_thread_proot + pop edi + endm + + + + + + + ENDIF + diff --git a/l4-x86/l4-4test/kernifc/perfmon.inc b/l4-x86/l4-4test/kernifc/perfmon.inc new file mode 100644 index 0000000..9d0b008 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/perfmon.inc @@ -0,0 +1,130 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + + + + externdef cycles:dword + +sstart macro + push eax + push edx + rdtsc + sub ss:[cycles+PM],eax + pop edx + pop eax + endm + +sstop macro + push eax + push edx + rdtsc + add ss:[cycles+PM],eax + pop edx + pop eax + endm diff --git a/l4-x86/l4-4test/kernifc/pnodes.inc b/l4-x86/l4-4test/kernifc/pnodes.inc new file mode 100644 index 0000000..dbf9d9f --- /dev/null +++ b/l4-x86/l4-4test/kernifc/pnodes.inc @@ -0,0 +1,40 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame equ 16 + + +pnode struc + + pte_ptr dd 0 + succ_pnode dd 0 + +pnode ends + + + + IF kernel_type EQ i486 + + +high4M_pages equ 8 + + +M4_pnode_base equ offset pnode_space + + + ELSE + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + + ENDIF \ No newline at end of file diff --git a/l4-x86/l4-4test/kernifc/rtcache-x.inc b/l4-x86/l4-4test/kernifc/rtcache-x.inc new file mode 100644 index 0000000..03f1be1 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/rtcache-x.inc @@ -0,0 +1,40 @@ +;************************************************ +; +; included in special rt versions of +; ktest5, sigma0, memctr +; +; all these have to be recompiled +; +;************************************************ + + +L2_cache_size equ KB256 +L2_cache_ways equ 1 + +L2_cache_colors equ (L2_cache_size / (L2_cache_ways*pagesize)) + + + + +unpartitioned equ 0 +partitioned equ 1 +single_writer_partitioned equ 2 + +write_through equ 0 +write_back equ 1 + + +none equ 0 +flooder equ 1 +filter equ 2 + + +partitioning_strategy equ unpartitioned +cache_strategy equ write_back + +interfering_with equ flooder + +matrix_columns equ 64 +filtersize equ 512 + + diff --git a/l4-x86/l4-4test/kernifc/schedcb.inc b/l4-x86/l4-4test/kernifc/schedcb.inc new file mode 100644 index 0000000..c8227ed --- /dev/null +++ b/l4-x86/l4-4test/kernifc/schedcb.inc @@ -0,0 +1,392 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + +llins_ss macro entry,root,temp,list + + or ss:[entry+list_state],is_&list& + mov ss:[entry+list&_llink].pred,root + mov temp,ss:[root+list&_llink].succ + mov ss:[root+list&_llink].succ,entry + mov ss:[entry+list&_llink].succ,temp + mov ss:[temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + +lldel_ss macro entry,temp_succ,temp_pred,list + + and ss:[entry+list_state],NOT is_&list& + mov temp_succ,ss:[entry+list&_llink].succ + mov temp_pred,ss:[entry+list&_llink].pred + mov ss:[temp_succ+list&_llink].pred,temp_pred + mov ss:[temp_pred+list&_llink].succ,temp_succ + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + +lins__ss macro tcb,temp,list + + or ss:[tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ss:[dispatcher_tcb+&list&_link] + mov ss:[tcb+&list&_link],temp + endm + + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + +linsr_ss macro tcb,temp,list,listmask + + or ss:[tcb+list_state],listmask + mov temp,tcb + xchg temp,ss:[dispatcher_tcb+list] + mov ss:[tcb+list],temp + endm + + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +; tcb <> ebp : DS linear_kernel_space +; +; tcb = ebp : SS linear_kernel_space is sufficient +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebp + mov ebp,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebp + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + diff --git a/l4-x86/l4-4test/kernifc/schedcb2.inc b/l4-x86/l4-4test/kernifc/schedcb2.inc new file mode 100644 index 0000000..2bf4865 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + scheduled_tcb dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-4test/kernifc/small-as.inc b/l4-x86/l4-4test/kernifc/small-as.inc new file mode 100644 index 0000000..4582b2f --- /dev/null +++ b/l4-x86/l4-4test/kernifc/small-as.inc @@ -0,0 +1,186 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + shl ebx,cl + xchg cl,ch + shl eax,cl + xchg cl,ch + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-4test/kernifc/tcb.inc b/l4-x86/l4-4test/kernifc/tcb.inc new file mode 100644 index 0000000..ae323a9 --- /dev/null +++ b/l4-x86/l4-4test/kernifc/tcb.inc @@ -0,0 +1,274 @@ +new_tcb_version equ 043h ; 30.12.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender + + + ready_llink dd 0,0 + dd 0 + task_pdir dd 0 + + com_partner dd 0 + waddr dd 0 + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + + + myself dd 0 + chief dd 0 + thread_state dd 0 + thread_proot dd 0 + + db 0 + coarse_state db 0 + list_state db 0 + resources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + ipc_control dd 0 + + + pager dd 0 + ext_preempter dd 0 + int_preempter dd 0 + ext_preempter_prio db 0 + int_preempter_prio db 0 + db 0 + small_as db 0 + + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink + + + +tcb struc + + pl0_stack dd 512/4 dup (0) + +tcb ends + + + +kernel_stack_bottom equ (sizeof tcb-4) + + + +auxiliary_thread_control_block struc + + db kernel_stack_bottom-sizeof int_pm_stack+offset ip_aux_state dup (0) + aux_state db 0 + dd 0 + +auxiliary_thread_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:4,xis_polled:1,com_used:1,dr_used:1,x87_used:1 + + + +is_polled equ mask xis_polled + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:4,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yfree:5,yiopl3:1 + +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; thread_states (special contents of 'waiting_for') +; +;---------------------------------------------------------------------------- + + +ready equ 0 +dead equ 1 +locked equ 2 +polling equ 3 +waiting_inner equ 4 +waiting_outer equ 5 +waiting_none equ 7 +waiting_any equ -1 + +;waiting_tid 100h <= tid < 80000000h +;waiting_int 40h <= int < 100h + + +;---------------------------------------------------------------------------- +; +; auxilary thread_states (only valid during in kernel) +; +;---------------------------------------------------------------------------- + + +aux_state_bits record xfree:6,xipcmem:1,xwake:1 + + +wakeup_active equ mask xwake +ipc_mem_active equ mask xipcmem + + + + + +.errnz tcb_space_size - (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + + +root_chief equ (booter_task AND mask task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + +;;max_kdebug_tcb equ ((sigma2_thread AND mask thread_no)+offset tcb_space) +max_kdebug_tcb equ (((threads-1) SHL thread_no)+offset tcb_space) + + + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb reg containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-4test/make/l4.rsp b/l4-x86/l4-4test/make/l4.rsp new file mode 100644 index 0000000..8408c97 --- /dev/null +++ b/l4-x86/l4-4test/make/l4.rsp @@ -0,0 +1,2 @@ +kernel5 startpc start cpuctr5 ipcman5 dispatch intctr tcbman memctr sgmctr+ +pagctr5 pagfault pagmap5 adrsman5 emuctr kdiopc kdebug sigma0 ktest5 ,l4.exe,l4.map; diff --git a/l4-x86/l4-4test/make/make-l4 b/l4-x86/l4-4test/make/make-l4 new file mode 100644 index 0000000..edd6d63 --- /dev/null +++ b/l4-x86/l4-4test/make/make-l4 @@ -0,0 +1,109 @@ + +p={\liedtke\l4-4test\kernel\;\liedtke\l4-4test\kernifc\;\liedtke\l4-4test\userifc\} +a=d:\liedtke\l4-4test\x86^\ +all_includes_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)apic.inc + + + + +$(a)adrsman5.obj : $(all_includes_x86) $(p)adrsman5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 adrsman5 as5 + +$(a)cpuctr5.obj : $(all_includes_x86) $(p)cpuctr5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 cpuctr5 as5 + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman5.obj : $(all_includes_x86) $(p)ipcman5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 ipcman5 as5 + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel5.obj : $(p)kernel5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 kernel5 as5 + +$(a)ktest5.obj : $(all_includes_x86) $(p)ktest5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 ktest5 as5 + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr5.obj : $(all_includes_x86) $(p)pagctr5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 pagctr5 as5 + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap5.obj : $(all_includes_x86) $(p)pagmap5.as5 + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 pagmap5 as5 + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 tcbman asm + + +$(a)l4.exe : $(a)adrsman5.obj $(a)cpuctr5.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman5.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel5.obj $(a)ktest5.obj $(a)memctr.obj $(a)pagctr5.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap5.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj + @cd \liedtke\l4-4test\x86 + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \liedtke\l4-4test\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-4test\x86 + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-4test/make/make-l4-old b/l4-x86/l4-4test/make/make-l4-old new file mode 100644 index 0000000..26dd873 --- /dev/null +++ b/l4-x86/l4-4test/make/make-l4-old @@ -0,0 +1,371 @@ + +p={\l4-30\src\kernel\;\l4-30\src\kernifc\;\l4-30\src\userifc\} +b=\l4-30\bin-486^\ +c=\l4-30\bin-pent^\ +d=\l4-30\bin-pex2^\ +e=\l4-30\bin-k6^\ +all_includes_486= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac4.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb4.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)msgmac.inc +all_includes_pent= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)msgmac.inc $(p)small-as.inc $(p)apic.inc +all_includes_k6= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)msgmac.inc $(p)small-as.inc $(p)apic.inc + +$(b)adrsman4.obj : $(all_includes_486) $(p)adrsman4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 adrsman4 asm + +$(b)cpuctr4.obj : $(all_includes_486) $(p)cpuctr4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 cpuctr4 asm + +$(b)dispatch.obj : $(all_includes_486) $(p)dispatch.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 dispatch asm + +$(b)emuctr.obj : $(all_includes_486) $(p)emuctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 emuctr asm + +$(b)intctr.obj : $(all_includes_486) $(p)intctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 intctr asm + +$(b)ipcman4.obj : $(all_includes_486) $(p)ipcman4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 ipcman4 asm + +$(b)kdebug.obj : $(all_includes_486) $(p)kdebug.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 kdebug asm + +$(b)kdiopc.obj : $(all_includes_486) $(p)kdiopc.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 kdiopc asm + +$(b)kernel4.obj : $(p)kernel4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 kernel4 asm + +$(b)ktest4.obj : $(all_includes_486) $(p)ktest4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 ktest4 asm + +$(b)memctr.obj : $(all_includes_486) $(p)memctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 memctr asm + +$(b)pagctr4.obj : $(all_includes_486) $(p)pagctr4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 pagctr4 asm + +$(b)pagfault.obj : $(all_includes_486) $(p)pagfault.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 pagfault asm + +$(b)pagmap4.obj : $(all_includes_486) $(p)pagmap4.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 pagmap4 asm + +$(b)sgmctr.obj : $(all_includes_486) $(p)sgmctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 sgmctr asm + +$(b)sigma0.obj : $(all_includes_486) $(p)sigma0.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 sigma0 asm + +$(b)start.obj : $(all_includes_486) $(p)start.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 start asm + +$(b)startpc.obj : $(all_includes_486) $(p)startpc.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 startpc asm + +$(b)tcbman.obj : $(all_includes_486) $(p)tcbman.asm + cd \l4-30\src\kernel + ..\..\make\xml-486 tcbman asm + + +$(b)l4.exe : $(b)adrsman4.obj $(b)cpuctr4.obj $(b)dispatch.obj $(b)emuctr.obj +$(b)l4.exe : $(b)intctr.obj $(b)ipcman4.obj $(b)kdebug.obj $(b)kdiopc.obj +$(b)l4.exe : $(b)kernel4.obj $(b)ktest4.obj $(b)memctr.obj $(b)pagctr4.obj +$(b)l4.exe : $(b)pagfault.obj $(b)pagmap4.obj $(b)sgmctr.obj $(b)sigma0.obj +$(b)l4.exe : $(b)start.obj $(b)startpc.obj $(b)tcbman.obj + cd \l4-30\bin-486 + link @ln4.rsp + pause + + + +$(c)adrsman5.obj : $(all_includes_pent) $(p)adrsman5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent adrsman5 as5 + +$(c)cpuctr5.obj : $(all_includes_pent) $(p)cpuctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent cpuctr5 as5 + +$(c)dispatch.obj : $(all_includes_pent) $(p)dispatch.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent dispatch asm + +$(c)emuctr.obj : $(all_includes_pent) $(p)emuctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent emuctr asm + +$(c)intctr.obj : $(all_includes_pent) $(p)intctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent intctr asm + +$(c)ipcman5.obj : $(all_includes_pent) $(p)ipcman5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent ipcman5 as5 + +$(c)kdebug.obj : $(all_includes_pent) $(p)kdebug.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent kdebug asm + +$(c)kdiopc.obj : $(all_includes_pent) $(p)kdiopc.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent kdiopc asm + +$(c)kernel5.obj : $(p)kernel5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent kernel5 as5 + +$(c)ktest5.obj : $(all_includes_pent) $(p)ktest5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent ktest5 as5 + +$(c)memctr.obj : $(all_includes_pent) $(p)memctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent memctr asm + +$(c)pagctr5.obj : $(all_includes_pent) $(p)pagctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent pagctr5 as5 + +$(c)pagfault.obj : $(all_includes_pent) $(p)pagfault.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent pagfault asm + +$(c)pagmap5.obj : $(all_includes_pent) $(p)pagmap5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pent pagmap5 as5 + +$(c)sgmctr.obj : $(all_includes_pent) $(p)sgmctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent sgmctr asm + +$(c)sigma0.obj : $(all_includes_pent) $(p)sigma0.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent sigma0 asm + +$(c)start.obj : $(all_includes_pent) $(p)start.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent start asm + +$(c)startpc.obj : $(all_includes_pent) $(p)startpc.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent startpc asm + +$(c)tcbman.obj : $(all_includes_pent) $(p)tcbman.asm + cd \l4-30\src\kernel + ..\..\make\xml-pent tcbman asm + + +$(c)l4.exe : $(c)adrsman5.obj $(c)cpuctr5.obj $(c)dispatch.obj $(c)emuctr.obj +$(c)l4.exe : $(c)intctr.obj $(c)ipcman5.obj $(c)kdebug.obj $(c)kdiopc.obj +$(c)l4.exe : $(c)kernel5.obj $(c)ktest5.obj $(c)memctr.obj $(c)pagctr5.obj +$(c)l4.exe : $(c)pagfault.obj $(c)pagmap5.obj $(c)sgmctr.obj $(c)sigma0.obj +$(c)l4.exe : $(c)start.obj $(c)startpc.obj $(c)tcbman.obj + cd \l4-30\bin-pent + link @ln4.rsp + pause + + + + + +$(d)adrsman5.obj : $(all_includes_pent) $(p)adrsman5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 adrsman5 as5 + +$(d)cpuctr5.obj : $(all_includes_pent) $(p)cpuctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 cpuctr5 as5 + +$(d)dispatch.obj : $(all_includes_pent) $(p)dispatch.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 dispatch asm + +$(d)emuctr.obj : $(all_includes_pent) $(p)emuctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 emuctr asm + +$(d)intctr.obj : $(all_includes_pent) $(p)intctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 intctr asm + +$(d)ipcman5.obj : $(all_includes_pent) $(p)ipcman5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 ipcman5 as5 + +$(d)kdebug.obj : $(all_includes_pent) $(p)kdebug.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 kdebug asm + +$(d)kdiopc.obj : $(all_includes_pent) $(p)kdiopc.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 kdiopc asm + +$(d)kernel5.obj : $(p)kernel5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 kernel5 as5 + +$(d)ktest5.obj : $(all_includes_pent) $(p)ktest5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 ktest5 as5 + +$(d)memctr.obj : $(all_includes_pent) $(p)memctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 memctr asm + +$(d)pagctr5.obj : $(all_includes_pent) $(p)pagctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 pagctr5 as5 + +$(d)pagfault.obj : $(all_includes_pent) $(p)pagfault.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 pagfault asm + +$(d)pagmap5.obj : $(all_includes_pent) $(p)pagmap5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 pagmap5 as5 + +$(d)sgmctr.obj : $(all_includes_pent) $(p)sgmctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 sgmctr asm + +$(d)sigma0.obj : $(all_includes_pent) $(p)sigma0.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 sigma0 asm + +$(d)start.obj : $(all_includes_pent) $(p)start.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 start asm + +$(d)x2ctr.obj : $(all_includes_pent) $(p)x2ctr.as5 + cd \l4-30\src\kernel + ..\..\make\xml-pex2 x2ctr as5 + + +$(d)startpc.obj : $(all_includes_pent) $(p)startpc.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 startpc asm + +$(d)tcbman.obj : $(all_includes_pent) $(p)tcbman.asm + cd \l4-30\src\kernel + ..\..\make\xml-pex2 tcbman asm + + +$(d)l4.exe : $(d)adrsman5.obj $(d)cpuctr5.obj $(d)dispatch.obj $(d)emuctr.obj +$(d)l4.exe : $(d)intctr.obj $(d)ipcman5.obj $(d)kdebug.obj $(d)kdiopc.obj +$(d)l4.exe : $(d)kernel5.obj $(d)ktest5.obj $(d)memctr.obj $(d)pagctr5.obj +$(d)l4.exe : $(d)pagfault.obj $(d)pagmap5.obj $(d)sgmctr.obj $(d)sigma0.obj +$(d)l4.exe : $(d)start.obj $(d)startpc.obj $(d)tcbman.obj +$(d)l4.exe : $(d)x2ctr.obj + cd \l4-30\bin-pex2 + link @ln4.rsp + pause + + + + +$(e)adrsman5.obj : $(all_includes_k6) $(p)adrsman5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 adrsman5 as5 + +$(e)cpuctr5.obj : $(all_includes_k6) $(p)cpuctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 cpuctr5 as5 + +$(e)dispatch.obj : $(all_includes_k6) $(p)dispatch.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 dispatch asm + +$(e)emuctr.obj : $(all_includes_k6) $(p)emuctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 emuctr asm + +$(e)intctr.obj : $(all_includes_k6) $(p)intctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 intctr asm + +$(e)ipcmank6.obj : $(all_includes_k6) $(p)ipcmank6.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 ipcmank6 as5 + +$(e)kdebug.obj : $(all_includes_k6) $(p)kdebug.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 kdebug asm + +$(e)kdiopc.obj : $(all_includes_k6) $(p)kdiopc.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 kdiopc asm + +$(e)kernelk6.obj : $(p)kernelk6.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 kernelk6 as5 + +$(e)ktestk6.obj : $(all_includes_k6) $(p)ktestk6.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 ktestk6 as5 + +$(e)memctr.obj : $(all_includes_k6) $(p)memctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 memctr asm + +$(e)pagctr5.obj : $(all_includes_k6) $(p)pagctr5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 pagctr5 as5 + +$(e)pagfault.obj : $(all_includes_k6) $(p)pagfault.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 pagfault asm + +$(e)pagmap5.obj : $(all_includes_k6) $(p)pagmap5.as5 + cd \l4-30\src\kernel + ..\..\make\xml-k6 pagmap5 as5 + +$(e)sgmctr.obj : $(all_includes_k6) $(p)sgmctr.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 sgmctr asm + +$(e)sigma0.obj : $(all_includes_k6) $(p)sigma0.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 sigma0 asm + +$(e)start.obj : $(all_includes_k6) $(p)start.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 start asm + +$(e)startpc.obj : $(all_includes_k6) $(p)startpc.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 startpc asm + +$(e)tcbman.obj : $(all_includes_k6) $(p)tcbman.asm + cd \l4-30\src\kernel + ..\..\make\xml-k6 tcbman asm + + +$(e)l4.exe : $(e)adrsman5.obj $(e)cpuctr5.obj $(e)dispatch.obj $(e)emuctr.obj +$(e)l4.exe : $(e)intctr.obj $(e)ipcmank6.obj $(e)kdebug.obj $(e)kdiopc.obj +$(e)l4.exe : $(e)kernelk6.obj $(e)ktestk6.obj $(e)memctr.obj $(e)pagctr5.obj +$(e)l4.exe : $(e)pagfault.obj $(e)pagmap5.obj $(e)sgmctr.obj $(e)sigma0.obj +$(e)l4.exe : $(e)start.obj $(e)startpc.obj $(e)tcbman.obj + cd \l4-30\bin-k6 + link @ln4.rsp + pause + + + diff --git a/l4-x86/l4-4test/make/ml-x86.bat b/l4-x86/l4-4test/make/ml-x86.bat new file mode 100755 index 0000000..dbb59c0 --- /dev/null +++ b/l4-x86/l4-4test/make/ml-x86.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=pentium /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-4test/make/proj.err b/l4-x86/l4-4test/make/proj.err new file mode 100644 index 0000000..e69de29 diff --git a/l4-x86/l4-4test/rtas-specials/ktest5-rt.as5 b/l4-x86/l4-4test/rtas-specials/ktest5-rt.as5 new file mode 100644 index 0000000..d323450 --- /dev/null +++ b/l4-x86/l4-4test/rtas-specials/ktest5-rt.as5 @@ -0,0 +1,805 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.5, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Special Version for Author: J.Liedtke ****** +;****** Cache Partitioning Tests ****** +;****** ****** +;****** Attention: requires recomp of sigma0+memctr ****** +;****** ****** +;********************************************************************* + +include rtcache.inc + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pentium + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+0*sizeof tcb) +pong_thread equ (sigma2_thread+0*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + + +ktest0_ready db false +ktest1_ready db false + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + assume ds:codseg + + +ktest0_start: + + + + + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + +columns equ matrix_columns + +.errnz (pagesize/(columns*8)) * (columns / (pagesize/(columns*8))) - columns + +IF L2_cache_ways EQ 1 + + matrix_a equ (MB1) + matrix_b equ (matrix_a+MB16) + + code_area equ (2*MB16) + +ELSE + + matrix_a equ (MB1) + matrix_b equ (matrix_a+MB4) + + code_area equ (2*MB4) + +ENDIF + + + + + + mov edx,1 + mov ebx,edx + mov esi,sigma0_task + mov edi,esi + sub eax,eax + mov ecx,1000h+12*4+map_msg + int ipc3 + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + + + mov ds:[ktest0_ready],true + + DO + sub esi,esi + int thread_switch + cmp ds:[ktest1_ready],true + REPEATNZ + OD + + + kd____disp <13,10,'matrix: '> + mov eax,columns + mov ecx,eax + kd____disp <' '> + kd____outdec + kd____disp <'x'> + kd____outdec + kd____disp <13,10> + + DO + mov eax,ds:[1000h].cpu_clock_freq + add eax,500000 + sub edx,edx + mov ebx,1000000 + div ebx + mov ds:[cycles_per_microsecond],eax + mov ebx,eax + + mov eax,ds:[intr_interval] + add eax,25 + mov ds:[intr_interval],eax + IFA eax,500 + CANDNZ eax,10000000 + kd____disp <13,10,'intr interval: '> + kd____inhex32 + IFZ eax,0 + mov eax,25 + mov ds:[intr_interval],eax + FI + FI + + kd____disp <13,10,'interval: '> + kd____outdec + kd____disp <' us'> + + imul eax,ebx + mov ebp,eax + + finit + + mov ecx,columns + mov edi,matrix_a + call gen_matrix + mov edi,matrix_b + call gen_matrix + + cli + + mov ds:[ktest1_ready],false + + pushad + DO + mov esi,pong_thread + int thread_switch + cmp ds:[ktest1_ready],true + REPEATNZ + OD + popad + + mov esi,matrix_a + mov edi,matrix_b + ; call mul_matrix + + pushad + mov esi,offset mul_matrix + mov edi,code_area + mov ecx,offset mul_matrix_end - offset mul_matrix + cld + rep movsb + popad + + rdtsc + mov ds:[cycles],eax + + mov eax,code_area + call eax + + + + + kd____disp <' time: '> + rdtsc + sub eax,13 + sub eax,ds:[cycles] + mov ds:[cycles],eax + IFZ ds:[best_cycles],0 + mov ds:[best_cycles],eax + FI + push eax + sub edx,edx + mov ebx,ds:[cycles_per_microsecond] + imul ebx,1000 + call outdec2 + kd____disp <' ms ('> + pop eax + mov ebx,eax + mov eax,columns*columns*columns + xchg eax,ebx + call outdec2 + kd____disp <' cy/it, '> + mov eax,ds:[vec_mults_sum] + add eax,ds:[vec_mults] + mov ebx,ds:[intrs] + IFZ ebx,0 + inc ebx + FI + call outdec2 + kd____disp <' vm/int) unpred: '> + + mov eax,ds:[cycles] + sub edx,edx + mov ebx,ds:[best_cycles] + sub eax,ebx + call outdec2 + + + + + REPEAT + OD + + + align 16 + +std_value dq 1.0 +fzero dq 0.0 +result dq 0.0 + +cycles dd 0 + +intr_clock dd 0 +vec_mults dd 0 +vec_mults_sum dd 0 +intrs dd 0 +intr_interval dd 10000000-25 +best_cycles dd 0 +filter_t dd 0 + +cycles_per_microsecond dd 0 + + + +gen_matrix: + + push ecx + push edi + + mov eax,ecx + imul ecx + DO + mov ebx,dword ptr ds:[std_value] + mov ecx,dword ptr ds:[std_value+4] + mov [edi],ebx + mov [edi+4],ecx + add edi,8 + dec eax + REPEATNZ + OD + + pop edi + pop ecx + ret + + + +mul_matrix: + + mov ecx,columns / (pagesize/(columns*8)) + + push esi + push edi + + sub eax,eax + mov ds:[vec_mults],eax + mov ds:[vec_mults_sum],eax + mov ds:[intrs],eax + + rdtsc + mov ds:[intr_clock],eax + DO + push ecx + push esi + push edi + + mov ecx,columns + DO + push ecx + push esi + push edi + + mov ecx,pagesize/(columns*8) + DO + push ecx + mov ecx,columns + fld qword ptr ds:[fzero] + jmp short xx + + DO + faddp st(1),st + xx: + fld qword ptr [ecx*8+esi-8] + fmul qword ptr [ecx*8+edi-8] + fld qword ptr [ecx*8+esi-16] + fmul qword ptr [ecx*8+edi-16] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-24] + fmul qword ptr [ecx*8+edi-24] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-32] + fmul qword ptr [ecx*8+edi-32] + fxch st(1) + faddp st(2),st + + sub ecx,4 + REPEATNZ + OD + faddp st(1),st + fstp qword ptr ds:[result] + + rdtsc + sub eax,13 + sub ds:[cycles],eax + + inc ds:[vec_mults] + + rdtsc + sub eax,ds:[intr_clock] + sub eax,ebp + IFAE + inc ds:[intrs] + sub ebx,ebx + xchg ds:[vec_mults],ebx + add ds:[vec_mults_sum],ebx + + IF interfering_with EQ filter + mov ebx,eax + rdtsc + sub eax,ebx + mov ds:[intr_clock],eax + + rdtsc + add ds:[cycles],eax + ENDIF + + pushad + mov esi,pong_thread + int thread_switch + popad + + IF interfering_with EQ filter + jmp xxxx + ENDIF + + IF interfering_with EQ flooder + mov ebx,eax + rdtsc + sub eax,ebx + mov ds:[intr_clock],eax + ENDIF + FI + + rdtsc + add ds:[cycles],eax + xxxx: + pop ecx + add edi,columns*8 + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + + add esi,columns*8 + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + + add edi,(pagesize/(columns*8)) * (columns*8) + dec ecx + REPEATNZ + + OD + + pop edi + pop esi + ret + + +mul_matrix_end equ $ + + + + +outdec2: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + + popad + ret + + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +filter_area equ 12*MB1 + L2_cache_colors/2*pagesize + +ktest1_start: + + DO + sub esi,esi + int thread_switch + cmp ds:[ktest0_ready],true + REPEATNZ + OD + + + IF interfering_with EQ none + + jmp ktest1_start + + ENDIF + + + + + IF interfering_with EQ flooder + + mov edi,12*MB1 + mov ecx,2*KB4-1 + mov al,90h + cld + rep stosb + mov byte ptr [edi],0C3h + + + cli + DO + mov edi,12*MB1 + call edi + mov ecx,2*KB4/4; KB256/4 + DO + IF (cache_strategy EQ write_through) OR (partitioning_strategy EQ single_writer_partitioned) + mov eax,[edi] + ELSE + add dword ptr ds:[edi],0 + ENDIF + mov eax,[edi] + add edi,32 + sub ecx,32/4 + REPEATA + OD + IF partitioning_strategy EQ single_writer_partitioned + mov edi,12*MB1 + mov ecx,2*KB4/4 + DO + add dword ptr [edi],0 + add edi,32 + sub ecx,32/4 + REPEATA + OD + ENDIF + + mov ds:[ktest1_ready],true + + mov esi,ping_thread + int thread_switch + + REPEAT + OD + ENDIF + + + + IF interfering_with EQ filter + + + mov edi,12*MB1+3*pagesize + mov esi,offset filter_loop + mov ecx,offset filter_end - offset filter_loop + cld + rep movsb + + + mov edi,filter_area + mov eax,filtersize*2 + DO + mov ebx,dword ptr ds:[std_value] + mov ecx,dword ptr ds:[std_value+4] + mov [edi],ebx + mov [edi+4],ecx + add edi,8 + dec eax + REPEATNZ + OD + + sub eax,eax + mov ds:[filter_t],eax + + cli + + mov edi,12*MB1+3*pagesize + jmp edi + + + filter_loop: + + DO + mov eax,ds:[filter_t] + inc eax + IFAE eax,filtersize + sub eax,eax + FI + mov ds:[filter_t],eax + + mov edi,filter_area + lea esi,[eax*8+edi+filtersize*8] + mov ecx,filtersize + + fld qword ptr ds:[fzero] + jmp short xx1 + + DO + faddp st(1),st + xx1: + fld qword ptr [esi] + fmul qword ptr [edi] + fld qword ptr [esi+8] + fmul qword ptr [edi+8] + fxch st(1) + faddp st(2),st + fld qword ptr [esi+16] + fmul qword ptr [edi+16] + fxch st(1) + faddp st(2),st + fld qword ptr [esi+24] + fmul qword ptr [edi+24] + fxch st(1) + faddp st(2),st + + add esi,4*8 + add edi,4*8 + IFB_ esi,filter_area+2*(filtersize*8) + sub ecx,4 + REPEATNZ + ELSE_ + sub esi,filtersize*8 + sub ecx,4 + REPEATNZ + FI + OD + faddp st(1),st + fstp qword ptr [result] + add dword ptr [esi],0 + + mov ds:[ktest1_ready],true + + mov esi,ping_thread + int thread_switch + + REPEAT + OD + + + filter_end equ $ + + + ENDIF + + + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/rtas-specials/ktest5-rt1.as5 b/l4-x86/l4-4test/rtas-specials/ktest5-rt1.as5 new file mode 100644 index 0000000..1ab6097 --- /dev/null +++ b/l4-x86/l4-4test/rtas-specials/ktest5-rt1.as5 @@ -0,0 +1,532 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.KTEST.5, 02,06,96, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 14.06.91 ****** +;****** modified: 02.06.96 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pentium + + +open_receive equ 1 + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ (booter_thread+0*sizeof tcb) +pong_thread equ (sigma2_thread+0*sizeof tcb) +;ping_thread equ booter_thread +;pong_thread equ (sigma2_thread+3*sizeof tcb) +;pong_thread equ (sigma2_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + + +ktest0_ready db false +ktest1_ready db false + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + assume ds:codseg + + +ktest0_start: + + + + + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + mov ds:[ktest0_ready],true + + + + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + mov edi,root_chief + int thread_schedule + + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,pong_thread + mov edi,root_chief + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,ping_thread + mov edi,root_chief + int thread_schedule + +matrix_a equ (MB1) +matrix_b equ (matrix_a+MB16) + + DO + + ke 'xx' + + finit + + kd____disp <13,10,'matrix: '> + ; kd____inhex16 + + mov eax,64 + + mov ecx,eax + kd____disp <' '> + kd____outdec + kd____disp <'x'> + kd____outdec + + mov edi,matrix_a + call gen_matrix + + mov edi,matrix_b + call gen_matrix + + cli + + mov ds:[ktest1_ready],false + + pushad + DO + mov esi,pong_thread + int thread_switch + cmp ds:[ktest1_ready],true + REPEATNZ + OD + popad + + rdtsc + mov ds:[cycles],eax + + mov esi,matrix_a + mov edi,matrix_b + call mul_matrix + + kd____disp <' cycles: '> + rdtsc + sub eax,13 + sub eax,ds:[cycles] + mov ebx,eax + kd____outdec + kd____disp <' ('> + mov eax,ecx + imul ecx + imul ecx + xchg eax,ebx + call outdec2 + kd____disp <' cycles/iteration)'> + + + + REPEAT + OD + + + align 16 + +std_value dq 1.0 +fzero dq 0.0 +result dq 0.0 + +cycles dd 0 + + + +gen_matrix: + + push ecx + push edi + + mov eax,ecx + imul ecx + DO + mov ebx,dword ptr ds:[std_value] + mov ecx,dword ptr ds:[std_value+4] + mov [edi],ebx + mov [edi+4],ecx + add edi,8 + dec eax + REPEATNZ + OD + + pop edi + pop ecx + ret + + + +mul_matrix: + + mov ebp,ecx + + push ecx + push esi + push edi + + DO + push ecx + push esi + push edi + + mov ecx,ebp + DO + push ecx + mov ecx,ebp + fld qword ptr ds:[fzero] + jmp short xx + + DO + faddp st(1),st + xx: + fld qword ptr [ecx*8+esi-8] + fmul qword ptr [ecx*8+edi-8] + fld qword ptr [ecx*8+esi-16] + fmul qword ptr [ecx*8+edi-16] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-24] + fmul qword ptr [ecx*8+edi-24] + fxch st(1) + faddp st(2),st + fld qword ptr [ecx*8+esi-32] + fmul qword ptr [ecx*8+edi-32] + fxch st(1) + faddp st(2),st + + sub ecx,4 + REPEATNZ + OD + faddp st(1),st + fstp qword ptr ds:[result] + + rdtsc + sub eax,13 + sub ds:[cycles],eax + + pushad + mov esi,pong_thread + int thread_switch + popad + + rdtsc + add ds:[cycles],eax + + pop ecx + lea edi,[ebp*8+edi] + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + + lea esi,[ebp*8+esi] + dec ecx + REPEATNZ + OD + + pop edi + pop esi + pop ecx + ret + + + + + +outdec2: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + + popad + ret + + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + DO + sub esi,esi + int thread_switch + cmp ds:[ktest0_ready],true + REPEATNZ + OD + + mov edi,MB1 + mov ecx,KB16/4 + DO + mov eax,[edi] + add edi,32 + sub ecx,32/4 + REPEATA + OD + mov edi,MB1+MB16 + mov ecx,KB16/4 + DO + mov eax,[edi] + add edi,32 + sub ecx,32/4 + REPEATA + OD + + + cli + DO + mov edi,MB1 + mov ecx,KB16/4 + DO + mov eax,[edi] + add edi,32 + sub ecx,32/4 + REPEATA + OD + mov edi,MB1+MB16 + mov ecx,KB16/4 + DO + mov eax,[edi] + add edi,32 + sub ecx,32/4 + REPEATA + OD + + mov ds:[ktest1_ready],true + + mov esi,ping_thread + int thread_switch + REPEAT + OD + + + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-4test/rtas-specials/sigma0-rt.asm b/l4-x86/l4-4test/rtas-specials/sigma0-rt.asm new file mode 100644 index 0000000..0fccf41 --- /dev/null +++ b/l4-x86/l4-4test/rtas-specials/sigma0-rt.asm @@ -0,0 +1,755 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.sigma0 , 20,04,97, 200 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** special RT version Author: J.Liedtke ****** +;****** ****** +;****** created: 24.09.95 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + +include rtcache.inc + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include msgmac.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dd 4 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + + + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop eax + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],eax + + mov eax,[eax+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + sub eax,eax + dec eax + + + + sub esi,esi + sub eax,eax + + DO + push ebp + sub ecx,ecx + mov edi,esi + mov esi,waiting_any + int ipc3 + pop ebp + + cmp eax,ipc_control_mask + mov eax,esi + REPEATA + + and eax,mask task_no + and edx,NOT 10b + + ror eax,task_no-8 + + cmp eax,dedicated_mem SHL 8 + REPEATAE + + test edx,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + REPEAT + + ELIFZ ah,kernel_task_no + + call grab_free_default_page + add ebx,fpage_grant - fpage_map_read_write + REPEAT + + ELSE_ + call grab_free_default_page + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + mov eax,map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + REPEAT + FI + + IFZ bl,2 + call unmap_4K_page + REPEAT + FI + + call reply_nak + REPEAT + OD + + + +reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_page: + + cmp edx,GB1 + xc ae,perhaps_special_device_4M_frame,long + + and edx,-pagesize + + push edx + + IFAE esi,booter_task + CANDB esi, + CANDA edx,KB64 + mov edi,edx + shr edi,24 + and edi,L2_cache_colors/2-1 + add edi,L2_cache_colors/2 + IFAE esi,sigma2_task + add edi,L2_cache_colors/4 + FI + and edx,(KB128-1) AND -pagesize + imul edx,L2_cache_colors + shl edi,log2_pagesize + lea edx,[edi+edx+MB1] + + ELIFAE esi,sigma2_task + CANDB esi, + CANDA edx,KB64 + + IF partitioning_strategy EQ partitioned + test edx,(L2_cache_colors/2)*pagesize + IFNZ + add edx,KB512-(L2_cache_colors/2)*pagesize + FI + ENDIF + FI + + + + + + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + mov al,[edi+ebx] + + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + + mov [edi+ebx],ah + + lea ebx,[edx+log2_pagesize*4 + fpage_map_read_write] + pop edx + + mov eax,map_msg + ret + FI + FI + + pop edx + call reply_nak + ret + + + + +XHEAD perhaps_special_device_4M_frame + + cmp edx,3*GB1 + xret ae ,long + + mov ebx,edx + and ebx,-1 SHL 22 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + +grab_specific_4M_or_4K_page: + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + cmp ecx,MB4/pagesize + jb grab_specific_page + + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + jnz grab_specific_page + + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + DO + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + lea edx,[edi+1] + sub edx,[ebp+memmap_descriptor].mem_begin + and edx,L2_cache_colors-1 + cmp edx,L2_cache_colors/2 + REPEATAE + + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + add ebx,log2_pagesize*4 + fpage_map_read_write + + mov eax,map_msg + ret + FI + OD + + call reply_nak + ret + + + + +;---------------------------------------------------------------------------- +; +; unmap 4K page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX 0 +; +;---------------------------------------------------------------------------- + + +unmap_4K_page: + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + and edx,-pagesize + mov al,[edi+ebx] + + IFZ al,ah + + ; mov byte ptr [edi+ebx],free_mem + + pushad + mov eax,edx + and eax,-pagesize + add eax,12*4+2 + mov cl,0FFh + int fpage_unmap + popad + FI + FI + + sub eax,eax + ret + + + + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad ;Ž90-09-15 + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad ;...Ž + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-4test/rtas-specials/sigma0-rtx.asm b/l4-x86/l4-4test/rtas-specials/sigma0-rtx.asm new file mode 100644 index 0000000..67609ae --- /dev/null +++ b/l4-x86/l4-4test/rtas-specials/sigma0-rtx.asm @@ -0,0 +1,769 @@ +include l4pre.inc + + scode + + Copyright GMD, L4.sigma0 , 20,04,97, 200 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** special RT version Author: J.Liedtke ****** +;****** ****** +;****** created: 24.09.95 ****** +;****** modified: 19.07.96 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include intrifc.inc +include tcb.inc +include msg.inc +include msgmac.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dd 4 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + + + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop eax + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],eax + + mov eax,[eax+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + sub eax,eax + dec eax + + + + sub esi,esi + sub eax,eax + + DO + push ebp + sub ecx,ecx + mov edi,esi + mov esi,waiting_any + int ipc3 + pop ebp + + cmp eax,ipc_control_mask + mov eax,esi + REPEATA + + and eax,mask task_no + and edx,NOT 10b + + ror eax,task_no-8 + + cmp eax,dedicated_mem SHL 8 + REPEATAE + + test edx,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + REPEAT + + ELIFZ ah,kernel_task_no + + call grab_free_default_page + add ebx,fpage_grant - fpage_map_read_write + REPEAT + + ELSE_ + call grab_free_default_page + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + mov eax,map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + REPEAT + FI + + IFZ bl,2 + call unmap_4K_page + REPEAT + FI + + call reply_nak + REPEAT + OD + + + +reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + ret + +;---------------------------------------------------------------------------- + + +L2_cache_size equ KB256 +L2_cache_ways equ 1 + +L2_cache_colors equ (L2_cache_size / (L2_cache_ways*pagesize)) + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_page: + + cmp edx,GB1 + xc ae,perhaps_special_device_4M_frame,long + + and edx,-pagesize + + push edx + + IFAE esi,booter_task + CANDB esi, + CANDA edx,KB64 + + mov edi,edx + and edx,KB32-1 + shr edi,24 + shl edi,15 + add edi,edx + and edi,-pagesize + sub edx,edi + shl edi,6 + add edx,edi + add edx,MB1 + + ; mov edi,edx + ; shr edi,24 + ; and edi,L2_cache_colors-1 + ; add edi,L2_cache_colors/2 + ; IFAE esi,sigma2_task + ; add edi,L2_cache_colors/4 + ;; add edi,-MB1/pagesize + ; FI + ; and edx,(KB128-1) AND -pagesize + ; imul edx,L2_cache_colors + ; shl edi,log2_pagesize + ; lea edx,[edi+edx+MB1] + + ELIFAE esi,sigma2_task + CANDB esi, + CANDA edx,KB64 + + test edx,(L2_cache_colors/2)*pagesize + IFNZ + ; add edx,KB512-(L2_cache_colors/2)*pagesize + FI + FI + + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + mov al,[edi+ebx] + + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + + mov [edi+ebx],ah + + lea ebx,[edx+log2_pagesize*4 + fpage_map_read_write] + pop edx + + mov eax,map_msg + ret + FI + FI + + pop edx + call reply_nak + ret + + + + +XHEAD perhaps_special_device_4M_frame + + cmp edx,3*GB1 + xret ae ,long + + mov ebx,edx + and ebx,-1 SHL 22 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + +grab_specific_4M_or_4K_page: + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + cmp ecx,MB4/pagesize + jb grab_specific_page + + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + jnz grab_specific_page + + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + add ebx,22*4 + fpage_map_read_write + + mov eax,map_msg + ret + + + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + DO + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + lea edx,[edi+1] + sub edx,[ebp+memmap_descriptor].mem_begin + and edx,L2_cache_colors-1 + cmp edx,L2_cache_colors/2 + REPEATAE + + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + add ebx,log2_pagesize*4 + fpage_map_read_write + + mov eax,map_msg + ret + FI + OD + + call reply_nak + ret + + + + +;---------------------------------------------------------------------------- +; +; unmap 4K page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX 0 +; +;---------------------------------------------------------------------------- + + +unmap_4K_page: + + mov ebx,[ebp+memmap_descriptor].mem_begin + mov edi,edx + + shr edi,log2_pagesize + mov ecx,[ebp+memmap_size] + + IFB_ edi,ecx + + and edx,-pagesize + mov al,[edi+ebx] + + IFZ al,ah + + ; mov byte ptr [edi+ebx],free_mem + + pushad + mov eax,edx + and eax,-pagesize + add eax,12*4+2 + mov cl,0FFh + int fpage_unmap + popad + FI + FI + + sub eax,eax + ret + + + + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad ;Ž90-09-15 + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad ;...Ž + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-4test/userifc/msg.inc b/l4-x86/l4-4test/userifc/msg.inc new file mode 100644 index 0000000..ef0397f --- /dev/null +++ b/l4-x86/l4-4test/userifc/msg.inc @@ -0,0 +1,115 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cca:1,ccfree:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm +mem_msg equ mask cca + + + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+mem_msg+mask ccfree) + + + + diff --git a/l4-x86/l4-4test/userifc/msgmac.inc b/l4-x86/l4-4test/userifc/msgmac.inc new file mode 100644 index 0000000..5536028 --- /dev/null +++ b/l4-x86/l4-4test/userifc/msgmac.inc @@ -0,0 +1,326 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + IF v equ 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + mov eax,msg + iiia=-1 + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + diff --git a/l4-x86/l4-4test/userifc/proj.err b/l4-x86/l4-4test/userifc/proj.err new file mode 100644 index 0000000..c228461 --- /dev/null +++ b/l4-x86/l4-4test/userifc/proj.err @@ -0,0 +1,6 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +'\l4\bin-486\l4.exe' is up-to-date diff --git a/l4-x86/l4-4test/userifc/syscalls.inc b/l4-x86/l4-4test/userifc/syscalls.inc new file mode 100644 index 0000000..cf5096a --- /dev/null +++ b/l4-x86/l4-4test/userifc/syscalls.inc @@ -0,0 +1,23 @@ +;********************************************************************* +;****** ****** +;****** L4 System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + +ipc3 equ 3Fh + diff --git a/l4-x86/l4-4test/userifc/uid.inc b/l4-x86/l4-4test/userifc/uid.inc new file mode 100644 index 0000000..7291bea --- /dev/null +++ b/l4-x86/l4-4test/userifc/uid.inc @@ -0,0 +1,227 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_low record ver1:4, task_no:16, lthread_no:3, ver0:9 + +thread_lowx record xver1:4, thread_no:19, xver0:9 + +thread_high record depth:4, chief_no:16, site_no:12 + + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + +sigma0_task equ (2 SHL task_no+initial_version) +sigma0_pager equ sigma0_task +sigma0_disk_driver equ (sigma0_task+(1 SHL lthread_no)) +sigma0_booter equ (sigma0_task+(2 SHL lthread_no)) + +sigma1_task equ (3 SHL task_no+initial_version) + +booter_task equ (4 SHL task_no+initial_version) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + +sigma2_task equ (5 SHL task_no+initial_version) +sigma2_lthread equ (0 SHL lthread_no) +sigma2_thread equ (sigma2_task+sigma2_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-x-0/c-bind/new/compiler.h b/l4-x86/l4-x-0/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x-0/c-bind/new/idt.h b/l4-x86/l4-x-0/c-bind/new/idt.h new file mode 100644 index 0000000..98d2fab --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/new/ipc-trent.c b/l4-x86/l4-x-0/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x-0/c-bind/new/ipc.h b/l4-x86/l4-x-0/c-bind/new/ipc.h new file mode 100644 index 0000000..865ccda --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x-0/c-bind/new/kdebug.h b/l4-x86/l4-x-0/c-bind/new/kdebug.h new file mode 100644 index 0000000..f0f83cd --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x-0/c-bind/new/kernel.h b/l4-x86/l4-x-0/c-bind/new/kernel.h new file mode 100644 index 0000000..0bdc7a2 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x-0/c-bind/new/syscalls.h b/l4-x86/l4-x-0/c-bind/new/syscalls.h new file mode 100644 index 0000000..c1ef7fc --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/new/test.c b/l4-x86/l4-x-0/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-x-0/c-bind/new/types.h b/l4-x86/l4-x-0/c-bind/new/types.h new file mode 100644 index 0000000..f1b0bc1 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x-0/c-bind/new/x-compiler.h b/l4-x86/l4-x-0/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x-0/c-bind/new/x-idt.h b/l4-x86/l4-x-0/c-bind/new/x-idt.h new file mode 100644 index 0000000..d5e005d --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/new/x-ipc.h b/l4-x86/l4-x-0/c-bind/new/x-ipc.h new file mode 100644 index 0000000..42a8299 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x-0/c-bind/new/x-kdebug.h b/l4-x86/l4-x-0/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..5e29ac8 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x-0/c-bind/new/x-kernel.h b/l4-x86/l4-x-0/c-bind/new/x-kernel.h new file mode 100644 index 0000000..c5f5019 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x-0/c-bind/new/x-lid.c b/l4-x86/l4-x-0/c-bind/new/x-lid.c new file mode 100644 index 0000000..5a767d8 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-x-0/c-bind/new/x-syscalls.h b/l4-x86/l4-x-0/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..64d7fff --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/new/x-types.h b/l4-x86/l4-x-0/c-bind/new/x-types.h new file mode 100644 index 0000000..b1b73ba --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x-0/c-bind/orig/compiler.h b/l4-x86/l4-x-0/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x-0/c-bind/orig/idt.h b/l4-x86/l4-x-0/c-bind/orig/idt.h new file mode 100644 index 0000000..98d2fab --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/orig/ipc-trent.c b/l4-x86/l4-x-0/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x-0/c-bind/orig/ipc.h b/l4-x86/l4-x-0/c-bind/orig/ipc.h new file mode 100644 index 0000000..865ccda --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x-0/c-bind/orig/kdebug.h b/l4-x86/l4-x-0/c-bind/orig/kdebug.h new file mode 100644 index 0000000..f0f83cd --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x-0/c-bind/orig/kernel.h b/l4-x86/l4-x-0/c-bind/orig/kernel.h new file mode 100644 index 0000000..0bdc7a2 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x-0/c-bind/orig/syscalls.h b/l4-x86/l4-x-0/c-bind/orig/syscalls.h new file mode 100644 index 0000000..c1ef7fc --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/orig/types.h b/l4-x86/l4-x-0/c-bind/orig/types.h new file mode 100644 index 0000000..f1b0bc1 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x-0/c-bind/provisional/compiler.h b/l4-x86/l4-x-0/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x-0/c-bind/provisional/idl.m4 b/l4-x86/l4-x-0/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-x-0/c-bind/provisional/idt.h b/l4-x86/l4-x-0/c-bind/provisional/idt.h new file mode 100644 index 0000000..98d2fab --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/provisional/ipc-trent.c b/l4-x86/l4-x-0/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x-0/c-bind/provisional/ipc.h b/l4-x86/l4-x-0/c-bind/provisional/ipc.h new file mode 100644 index 0000000..402e523 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x-0/c-bind/provisional/kdebug.h b/l4-x86/l4-x-0/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..f0f83cd --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x-0/c-bind/provisional/kernel.h b/l4-x86/l4-x-0/c-bind/provisional/kernel.h new file mode 100644 index 0000000..0bdc7a2 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x-0/c-bind/provisional/syscalls.h b/l4-x86/l4-x-0/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..c1ef7fc --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x-0/c-bind/provisional/types.h b/l4-x86/l4-x-0/c-bind/provisional/types.h new file mode 100644 index 0000000..f1b0bc1 --- /dev/null +++ b/l4-x86/l4-x-0/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:46 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x-0/kernel/adrsman.asm b/l4-x86/l4-x-0/kernel/adrsman.asm new file mode 100644 index 0000000..a18d1e2 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/adrsman.asm @@ -0,0 +1,954 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 08, 08, 99, 9025 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 08.08.99 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86 + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + lno___task eax,ebp ; + load__proot eax,eax ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + lno___task edi,ebx ; + ; + call detach_associated_small_space ; + ; + load__proot edi,edi ; + ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + mov ecx,[(ecx*8)+task_proot].switch_ptr + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax ; + lea___tcb ebp,eax ; + ; + IFZ [edi*8+task_proot].proot_ptr,0 ; + mov edi,[edi*8+task_proot].switch_ptr ; + sub edi,ds:[empty_proot] ; + ELSE_ ; + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + pop eax + + lno___task ebp + store_proot eax,ebp + FI + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + + ret + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + + lno___task ebp,esi + lea edi,[ebp*8+task_proot] + + movzx eax,ah + movzx ecx,[edi].small_as + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*2)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*2)+small_associated_task],bp + FI + mov ecx,eax + mov [edi].small_as,al + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + mov [edi].switch_ptr,ecx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push eax + push edi + + movzx edi,[(ecx*2)+small_associated_task] + test edi,edi + IFNZ + mov word ptr [(ecx*2)+small_associated_task],0 + + call flush_small_pde_block_in_all_pdirs + + lea ecx,[(edi*8)+task_proot] + + mov eax,cr3 + mov cr3,eax + + mov eax,[ecx].proot_ptr + mov al,0 + mov [ecx].switch_ptr,eax + mov [ecx].proot_ptr,eax + FI + + lno___task eax,esp + IFZ eax,edi + call make_own_address_space_large + FI + + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; detach associated small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push ecx + + movzx ecx,[edi*8+task_proot].small_as + test ecx,ecx + IFNZ + call detach_small_space + FI + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; EDI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[edi].switch_ptr + mov edi,ds:[kernel_proot] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + lno___task edi,esp + + lea edi,[(edi*8)+task_proot] + mov eax,[edi].proot_ptr + mov al,0 + mov [edi].switch_ptr,eax + + mov edi,eax + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + mov fs,eax + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + mov edx,offset task_proot + DO + mov ebp,[edx].proot_ptr + add edx,8 + and ebp,0FFFFFF00h + REPEATZ + + EXITS + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + lno___task eax,esi + mov eax,[eax*8+task_proot].switch_ptr + + test eax,eax + IFNS + mov al,0 + ret + FI + + rol eax,8 + xchg al,ah + shr eax,22-16 + sub al,(offset small_virtual_spaces SHR 22) AND 0FFh + add al,al + add al,ds:[small_space_size_DIV_MB4] + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/atrace.asm b/l4-x86/l4-x-0/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-x-0/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-x-0/kernel/boot.asm b/l4-x86/l4-x-0/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-x-0/kernel/contents b/l4-x86/l4-x-0/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-x-0/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/cpuctr.asm b/l4-x86/l4-x-0/kernel/cpuctr.asm new file mode 100644 index 0000000..7f950a6 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/cpuctr.asm @@ -0,0 +1,1195 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 24,08,99, 68, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + + switch_thread con,ebx + + shr ebp,task_no + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + push eax + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + pop eax + + mov esi,ebp + shr ebp,task_no + + push ds + switch_space ; switch space may load user_linear space into ds + pop ds + + mov ebp,esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret + + +deallocate_ressources: + + push eax + + test [edi+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + mov eax,ebp + shr eax,task_no + mov eax,[(eax*8)+task_proot-(offset tcb_space SHR (task_no-3))] + CORA eax, + IFZ ds:[cpu_cr3],eax + + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd + push offset reallocate_ressources_by_ret + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],phys_mem_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/dispatch.asm b/l4-x86/l4-x-0/kernel/dispatch.asm new file mode 100644 index 0000000..3f1dac0 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/dispatch.asm @@ -0,0 +1,1419 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 11,03,99, 9089, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86 + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + klign 16 + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + ELIFZ ebx,[esi+int_preempter] + add dl,20h + ELIFZ ebx,[esi+ext_preempter] + add dl,30h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + FI + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFB_ ah,max_small_spaces + call attach_small_space + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov ebx,[esi+ext_preempter] + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + clign 4 + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + clign 16 + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/emuctr.asm b/l4-x86/l4-x-0/kernel/emuctr.asm new file mode 100644 index 0000000..1587a73 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/emuctr.asm @@ -0,0 +1,512 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86 + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + clign 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/idecode.asm b/l4-x86/l4-x-0/kernel/idecode.asm new file mode 100644 index 0000000..6a3760f --- /dev/null +++ b/l4-x86/l4-x-0/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],phys_mem_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-x-0/kernel/intctr.asm b/l4-x86/l4-x-0/kernel/intctr.asm new file mode 100644 index 0000000..ccbce79 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/intctr.asm @@ -0,0 +1,533 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 12,12,97, 57 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86 + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler + db dpl3 + dd offset initial_debug_exception_handler + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler + db dpl3 + dd offset overflow_handler + db dpl3 + dd offset bound_check_handler + db dpl3 + dd offset invalid_opcode_handler + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler + db dpl0 + dd offset stack_exception_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler + db dpl0 + dd offset alignment_check_handler + db dpl0 + dd offset machine_check_exception + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,phys_mem_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + mov ecx,linear_space ; + CORNZ [esp+ip_ds],ecx ; + mov edx,es ; + IFNZ edx,ecx ; + test byte ptr ss:[esp+ip_cs],11b + IFNZ ; + mov [esp+ip_ds],ecx; do not update DS + FI ; if within kernel ! + mov es,ecx ; (DS might be kernel seg) + ipost ; + FI ; + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + lno___task edi,esp + test byte ptr ss:[edi*8+task_proot+3].switch_ptr,80h + CANDNZ + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/ipcman.asm b/l4-x86/l4-x-0/kernel/ipcman.asm new file mode 100644 index 0000000..3f8f4b4 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/ipcman.asm @@ -0,0 +1,3520 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 27,09,99, 9174, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + shr ebp,task_no + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + + + push eax + push ebx + + cmp eax,virtual_space_size-MB4 + jae receive_only + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + mov [ebx+waiting_for],esi + and al,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + ; + and ebp,mask task_no ; + mov edx,ebx ; + ; + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + mov edx,[edx+ebp+redirection_table] ; + ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + and ebp,mask thread_no + + mov [ebx+mword2],edi + add ebp,offset tcb_space + + mov edi,[ebx+myself] + ;REDIR: and al,(NOT ipc_control_mask)+deceit+map_msg + + mov edx,[ebp+myself] + xor edi,esi + + test edi,mask chief_no + xc nz,to_chief,long + + cmp esi,edx + jnz ipc_dest_not_existent + + test al,deceit + xc nz,propagate_pre,long + + mov dl,[ebp+fine_state] + + + and dl,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + xc nz,pending_or_auto_propagating,long + FI + + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + + mov edx,[ebx+rcv_descriptor] + mov ch,running + + mov [ebp+fine_state],ch + cmp edx,virtual_space_size + + mov dh,[ebx+list_state] + IF____xc ae,send_only,long + + ELSE__ + and edx,(is_polled SHL 8) + nclos + + cmp edx,(is_polled SHL 8) + nclos + jz fetch_next + + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + +;;;;; switch_thread ipc,edi + mov cl,[edi+ressources] + + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + shr ebp,task_no + mov esi,[edi+myself] + + test al,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + + +;;;;;;;;;;;; switch_space + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + cmp byte ptr ds:[gdt+linear_space/8*8+7],0 + mov cr3,ebp + mov ebp,linear_space + IFZ + mov ds,ebp + pop ebp + iretd + FI + FI + mov ebp,00CCF300h + FI + + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + + mov ds:[gdt+linear_space_exec/8*8+4],ebp + mov ebp,linear_space + + mov es,ebp + + mov fs,ebp + + mov gs,ebp + + mov ds,ebp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pop ebp + iretd + + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z + + mov esi,[edi+virtual_sender] + xret + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + mov edi,[esp+iret_esp+3*4] ; must be read from user space, + sub edx,edx + + mov [ebx+propagatee_tcb],edx + mov edi,es:[edi] ; potentially small space + + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + mov [ebx+virtual_sender],edi + + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + test esi,mask task_no + IFZ + lea___tcb esi,edi + + test__page_writable esi + IFNC + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + CANDZ dl,closed_wait + CANDZ [ebx+myself],edi + + mov [ebx+propagatee_tcb],esi + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + xret ,long + FI + + + ;REDIR begin -------------------------------- + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + test edx,mask chief_no ; ; + xret z,long ; + ; + mov edx,[ebx+myself] ; + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; + ; + and ebp,mask task_no ; + mov esi,edi ; + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + pop ebp ; + pop ecx ; + xret ,long ; + OD ; + pop ebp ; + pop ecx ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + ;REDIR ends ----------------------------------- + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + mov edx,(locked_running SHL 8) + (locked_waiting AND 0FFh) + + mov [ebx+fine_state],dh + mov [ebp+fine_state],dl + + and al,ipc_control_mask + mov esi,[esp+4+4] + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + IFNZ + mov bl,al + mov eax,es:[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + ;; mov [ebx+com_partner],ebp + + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + ;;; mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w3 + nop + + mov eax,[eax*8+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w3] + + mov edi,[edx+32] + lea edi,[edx+msg_w3] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressource ebx,com_used + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + nop + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w3 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + IFB_ eax,ecx + mov ecx,eax + FI + IFB_ ebx,ecx + mov ecx,ebx + FI + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + + + if 0 ;----------------------------------------- + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w3-2*4] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w3-2*4] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + + push eax + push ebx + + mov eax,[edi+buf_addr] + mov [edi+str_len],ecx + mov [edi+str_addr],eax + + mov esi,[esi+str_addr] + mov edi,eax + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + + + endif ;-------------------------------------- + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +XHEAD prepare_small_string_source + + shl eax,16 + + lea edx,[esi+ecx] + sass__32 cmp,edx,MB4 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + align 16 + + + +fetch_next: + + add dl,locked_closed_waiting + mov [ebx+fine_state],dl + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/kdebug.asm b/l4-x86/l4-x-0/kernel/kdebug.asm new file mode 100644 index 0000000..ce284cb --- /dev/null +++ b/l4-x86/l4-x-0/kernel/kdebug.asm @@ -0,0 +1,5650 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 07,10,99, 76 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 07.10.99 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_proot +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86 + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,cs:[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_proot + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,cs:[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ cs:[no_breakpoint_thread],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ cs:[breakpoint_thread],0 + cmp cs:[breakpoint_thread],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp cs:[debug_exception_handler] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ cs:[bx_size],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + test cs:[physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + mov eax,cs:[kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + IFZ ebp,cs:[kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_proot + ELIFZ al,'t' + mov eax,offset task_proot + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ds + + popad + jmp cs:[page_fault_handler] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop ds + + popad + add esp,4 + jmp cs:[ipc_handler] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,cs:[monitored_exception] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,cs:[monitored_ec_min] + movzx ecx,cs:[monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop ds + + popad + + CORB cs:[monitored_exception],8 + IFA cs:[monitored_exception],14 + IFNZ cs:[monitored_exception],17 + add esp,4 + FI + FI + + jmp cs:[monitored_exception_handler] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop ds + + popad + add esp,4 + FI + + jmp cs:[timer_intr_handler] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_proot + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__proot edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0 + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov [trace_buffer_in_pointer],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + shr ecx,2 + sub eax,eax + cld + rep stosd + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + mov ecx,event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,event_select_msr + mov eax,ebx + wrmsr + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + IFAE esp,virtual_space_size + call open_trace_buffer + CANDNC + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + FI + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +event_select_msr equ 11h +event_counter0_msr equ 12h +event_counter1_msr equ 13h + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 00011111b +w_stall equ 00011001b +r_stall equ 00011010b +x_stall equ 00011011b +agi_stall equ 00011111b + +bus_util equ 00011000b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + + +set_performance_tracing: + + kd____clear_page + call show_trace_perf_monitoring_mode + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + sub ebx,ebx + IFZ al,'i' + mov ebx,instrs_ex + (instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,rw_miss + (ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,rw_tlb + (ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,r_stall + (w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,agi_stall + (bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,bus_util + (instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,event_select_msr + wrmsr + mov ecx,event_counter0_msr + wrmsr + mov ecx,event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,event_select_msr + wrmsr + FI + + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/kdiopc.asm b/l4-x86/l4-x-0/kernel/kdiopc.asm new file mode 100644 index 0000000..328080e --- /dev/null +++ b/l4-x86/l4-x-0/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86 + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/kernel.asm b/l4-x86/l4-x-0/kernel/kernel.asm new file mode 100644 index 0000000..af753d0 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '24.08.99' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-X Nucleus (x86), Copyright (C) IBM 1997 & University of Karlsruhe 1999',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/ktest.asm b/l4-x86/l4-x-0/kernel/ktest.asm new file mode 100644 index 0000000..69d848c --- /dev/null +++ b/l4-x86/l4-x-0/kernel/ktest.asm @@ -0,0 +1,1058 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 02,09,97, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 02.09.97 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86 + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' +; +; +; +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; +; mov esi,MB1 +; mov ecx,1024 +; DO +; mov eax,[esi] +; mov eax,[esi+28] +; add esi,32 +; dec ecx +; REPEATNZ +; OD +; +; rdtsc +; sub eax,ebx +; sub eax,12 +; add eax,511 +; shr eax,10 +; push eax +; +; +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; kd____disp <13,10,'RAM cache-line read: '> +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,1000h + ; cmp byte ptr ds:[ebx],0 + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 1' + ; + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,MB16 + ; and ebx,-pagesize + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 2' + ; + + + + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma1_task +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + ; mov edx,ecx + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + mov eax,3 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + ;------------------- for translate test only: + ; or byte ptr ds:[MB4],0 + ;---------------------------------------- + + clign 16 + DO + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count mem2pipe,cnt_event,bank_conf,cnt_event +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 +; P_count r_stall,cnt_event_PL3,w_stall,cnt_event_PL3 + rdtsc + push eax + + clign 16 + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/memctr.asm b/l4-x86/l4-x-0/kernel/memctr.asm new file mode 100644 index 0000000..1d66a75 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/memctr.asm @@ -0,0 +1,519 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86 + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + load__proot ebx,<((sigma0_task AND mask task_no) SHR task_no)> + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/pagctr.asm b/l4-x86/l4-x-0/kernel/pagctr.asm new file mode 100644 index 0000000..e49fdac --- /dev/null +++ b/l4-x86/l4-x-0/kernel/pagctr.asm @@ -0,0 +1,1184 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 24,08,99, 116 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_proot + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + mov [edi+4],ecx + add edi,8 + cmp edi,offset proot_end_marker + REPEATB + OD + dec ecx + mov [edi],ecx + mov [edi+4],ecx + + + mov ds:[kernel_proot],edx + mov ds:[kernel_proot+4],edx + mov ds:[empty_proot],ebx + mov ds:[empty_proot+4],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/pagfault.asm b/l4-x86/l4-x-0/kernel/pagfault.asm new file mode 100644 index 0000000..72597f7 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/pagfault.asm @@ -0,0 +1,753 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 11,03,99, 9163, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86 + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_cs+4],phys_mem_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + IFNZ [ebp+fine_state],locked_running + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + push 0 + push phys_mem_exec + push offset ipcret + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + call push_ipc_state + + IFNZ + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + test__page_present edx + CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin + CANDBE eax,offset ipc_critical_region_end + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + mov ah,byte ptr ds:[gdt+(linear_space AND -8)+7] + mov al,byte ptr ds:[gdt+(linear_space AND -8)+4] + shl eax,16 + xor eax,edx + shr eax,22 + mov cl,ch + shr eax,cl + + mov esi,ebp + IFNZ + mov esi,[ebp+com_partner] + FI + lno___task esi,esi + load__proot esi,esi + add esi,PM + + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + mov ebp,edi + pop esi + REPEAT + OD + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__proot eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/pagmap.asm b/l4-x86/l4-x-0/kernel/pagmap.asm new file mode 100644 index 0000000..3579cc4 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/pagmap.asm @@ -0,0 +1,1889 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 27,08,99, 43 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.08.99 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86 + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_ + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page + jmp short do_fpage + FI + push offset unmap_write_page + jmp short do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page + jmp short do_fpage + FI + push offset flush_write_page + jmp short do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,ebx + mov bl,[ebx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + xc z,unmap_in_own_address_space + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + ; xchg ebp,[esp] + ; mov byte ptr [ebp+tlb_flush_indicator],2 + ; xchg ebp,[esp] + + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + + + mov ebx,[eax].pte_ptr + cmp ebx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp ebx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + + + +; xchg ebp,[esp] +; mov byte ptr [ebp+tlb_flush_indicator],2 +; xchg ebp,[esp] +; xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + lno___task edx,ebp + load__proot edx,edx + add edx,PM + + mov ecx,cr3 + IFAE , + lno___task ecx,esp + load__proot ecx,ecx + FI + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-x-0/kernel/proj.err b/l4-x86/l4-x-0/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-x-0/kernel/sgmctr.asm b/l4-x86/l4-x-0/kernel/sgmctr.asm new file mode 100644 index 0000000..09e27ec --- /dev/null +++ b/l4-x86/l4-x-0/kernel/sgmctr.asm @@ -0,0 +1,256 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.09.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +.list + + +ok_for x86 + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS phys_mem_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6,phys_mem_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + + descriptor xr32, dpl0, PM, ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-x-0/kernel/sigma0.asm b/l4-x86/l4-x-0/kernel/sigma0.asm new file mode 100644 index 0000000..7c1a0e0 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/sigma0.asm @@ -0,0 +1,769 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-x-0/kernel/start.asm b/l4-x86/l4-x-0/kernel/start.asm new file mode 100644 index 0000000..f6f08f7 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/start.asm @@ -0,0 +1,354 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86 + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/startpc.asm b/l4-x86/l4-x-0/kernel/startpc.asm new file mode 100644 index 0000000..4bf695d --- /dev/null +++ b/l4-x86/l4-x-0/kernel/startpc.asm @@ -0,0 +1,1288 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + inrtc rtc_seconds + mov ah,al + DO + inrtc rtc_seconds + cmp ah,al + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-x-0/kernel/tables.asm b/l4-x86/l4-x-0/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/tcbman.asm b/l4-x86/l4-x-0/kernel/tcbman.asm new file mode 100644 index 0000000..93e6fb7 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/tcbman.asm @@ -0,0 +1,733 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 16,03,99, 9141 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + extrn sigma_1_installed:byte + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86 + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + cmp ebx,-1 + IFNZ + xchg ebx,[ebp+int_preempter] + ELSE_ + mov ebx,[ebp+int_preempter] + FI + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret + + mov dword ptr [esi+4],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; FI + mov [ebp+pager],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + ELSE_ + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/x.asm b/l4-x86/l4-x-0/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernel/y.asm b/l4-x86/l4-x-0/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-x-0/kernel/yoonseva.asm b/l4-x86/l4-x-0/kernel/yoonseva.asm new file mode 100644 index 0000000..f914529 --- /dev/null +++ b/l4-x86/l4-x-0/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),phys_mem_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/adrspac5.inc b/l4-x86/l4-x-0/kernifc/adrspac5.inc new file mode 100644 index 0000000..4f3d1de --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/adrspac5.inc @@ -0,0 +1,200 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ( 64*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ( 88*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00B63000h-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd tasks*dwords_per_task_proot dup (?) ; | + proot_end_marker dd dwords_per_task_proot dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd 0,0 + kernel_proot dd 0,0 + sigma0_proot dd 0,0 + +special_proots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) diff --git a/l4-x86/l4-x-0/kernifc/adrspace.inc b/l4-x86/l4-x-0/kernifc/adrspace.inc new file mode 100644 index 0000000..85947b8 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ x86 + +subtitle L4/x86 Version X + +kernel_type = x86 + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-x-0/kernifc/apic.inc b/l4-x86/l4-x-0/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/contents b/l4-x86/l4-x-0/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/cpucb.inc b/l4-x86/l4-x-0/kernifc/cpucb.inc new file mode 100644 index 0000000..4b3149c --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/cpucb.inc @@ -0,0 +1,7 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/l4-x-0/kernifc/cpucb5.inc b/l4-x86/l4-x-0/kernifc/cpucb5.inc new file mode 100644 index 0000000..826accb --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/cpucb5.inc @@ -0,0 +1,286 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-x-0/kernifc/intrifc.inc b/l4-x86/l4-x-0/kernifc/intrifc.inc new file mode 100644 index 0000000..c9101d5 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/intrifc.inc @@ -0,0 +1,323 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/kpage.inc b/l4-x86/l4-x-0/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-x-0/kernifc/l4const.inc b/l4-x86/l4-x-0/kernifc/l4const.inc new file mode 100644 index 0000000..df2a916 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/l4const.inc @@ -0,0 +1,95 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +linear_kernel_space equ 0008h + +linear_space equ (0010h+3) +linear_space_exec equ (0018h+3) + +phys_mem_exec equ 0020h +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/l4kd.inc b/l4-x86/l4-x-0/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-x-0/kernifc/l4pre.inc b/l4-x86/l4-x-0/kernifc/l4pre.inc new file mode 100644 index 0000000..ef2ebee --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/l4pre.inc @@ -0,0 +1,871 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxhl equ ax +ebxhl equ bx +ecxhl equ cx +edxhl equ dx +esihl equ si +edihl equ di +ebphl equ bp +eaxl equ al +ebxl equ bl +ecxl equ cl +edxl equ dl +eaxh equ ah +ebxh equ bh +ecxh equ ch +edxh equ dh +axl equ al +bxl equ bl +cxl equ cl +dxl equ dl +axh equ ah +bxh equ bh +cxh equ ch +dxh equ dh + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + +clign macro alignment,off + +ifb +aax=($-modstart) AND (alignment-1) +else +aax=($-modstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +klign macro alignment,off + +ifb +aax=($-kmodstart) AND (alignment-1) +else +aax=($-kmodstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-x-0/kernifc/lbmac.inc b/l4-x86/l4-x-0/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-x-0/kernifc/pagcb.inc b/l4-x86/l4-x-0/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-x-0/kernifc/pagconst.inc b/l4-x86/l4-x-0/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-x-0/kernifc/pagmac.inc b/l4-x86/l4-x-0/kernifc/pagmac.inc new file mode 100644 index 0000000..bcb4b50 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/pagmac.inc @@ -0,0 +1,123 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +x86_proot struc + + switch_ptr dd 0 + proot_ptr dd 0 + +x86_proot ends + +x86_prootx struc + + dd 0 + small_as db 0 + db 0,0,0 + +x86_prootx ends + + +load__proot macro reg,task_no + + mov reg,ds:[(task_no*8)+task_proot+4] + IFIDN , + mov al,0 + ELSEIFIDN , + mov bl,0 + ELSEIFIDN , + mov cl,0 + ELSEIFIDN , + mov dl,0 + ELSE + and reg,0FFFFFF00h + ENDIF + endm + + +store_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + mov ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + +store_inactive_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot],reg + mov ds:[(task_no*8)+task_proot+4],0 + endm + + +chnge_proot macro reg,task_no + + test byte ptr ds:[(task_no*8)+task_proot+3],80h + IFZ + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + + diff --git a/l4-x86/l4-x-0/kernifc/perfmon.inc b/l4-x86/l4-x-0/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-x-0/kernifc/pnodes.inc b/l4-x86/l4-x-0/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-x-0/kernifc/proj.err b/l4-x86/l4-x-0/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-x-0/kernifc/schedcb.inc b/l4-x86/l4-x-0/kernifc/schedcb.inc new file mode 100644 index 0000000..8f80035 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-x-0/kernifc/schedcb2.inc b/l4-x86/l4-x-0/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-x-0/kernifc/small-as.inc b/l4-x86/l4-x-0/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-x-0/kernifc/tcb.inc b/l4-x86/l4-x-0/kernifc/tcb.inc new file mode 100644 index 0000000..5579288 --- /dev/null +++ b/l4-x86/l4-x-0/kernifc/tcb.inc @@ -0,0 +1,275 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + pager dd 0 + dd 0 + + com_partner dd 0 + waddr dd 0 + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + + + myself dd 0 + dd 0 + waiting_for dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + ext_preempter dd 0 + dd 0 + int_preempter dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:4,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_proot/(dwords_per_task_proot*4) GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_proot)/(dwords_per_task_proot*4) - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-x-0/make/l4.rsp b/l4-x86/l4-x-0/make/l4.rsp new file mode 100644 index 0000000..4ceee3c --- /dev/null +++ b/l4-x86/l4-x-0/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-x-0/make/make-l4 b/l4-x86/l4-x-0/make/make-l4 new file mode 100644 index 0000000..89b2e9c --- /dev/null +++ b/l4-x86/l4-x-0/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-x\kernel\;\liedtke\l4-x\kernifc\;\liedtke\l4-x\userifc\} +a=d:\liedtke\l4-x\x86^\ +all_includes_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_x86) $(p)adrsman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 adrsman asm + +$(a)cpuctr.obj : $(all_includes_x86) $(p)cpuctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 cpuctr asm + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman.obj : $(all_includes_x86) $(p)ipcman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 ipcman asm + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kernel asm + +$(a)ktest.obj : $(all_includes_x86) $(p)ktest.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 ktest asm + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr.obj : $(all_includes_x86) $(p)pagctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagctr asm + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap.obj : $(all_includes_x86) $(p)pagmap.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagmap asm + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 tcbman asm + +$(a)yoonseva.obj : $(all_includes_x86) $(p)yoonseva.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-x\x86 + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-x\x86 + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-x-0/make/ml-x86.bat b/l4-x86/l4-x-0/make/ml-x86.bat new file mode 100755 index 0000000..37080f7 --- /dev/null +++ b/l4-x86/l4-x-0/make/ml-x86.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=x86 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-x-0/make/proj.err b/l4-x86/l4-x-0/make/proj.err new file mode 100644 index 0000000..b705f89 --- /dev/null +++ b/l4-x86/l4-x-0/make/proj.err @@ -0,0 +1,11 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\kdebug.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-x-0/userifc/contents b/l4-x86/l4-x-0/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-x-0/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-x-0/userifc/msg.inc b/l4-x86/l4-x-0/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-x-0/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-x-0/userifc/scmac.inc b/l4-x86/l4-x-0/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-x-0/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-x-0/userifc/syscalls.inc b/l4-x86/l4-x-0/userifc/syscalls.inc new file mode 100644 index 0000000..ff0f980 --- /dev/null +++ b/l4-x86/l4-x-0/userifc/syscalls.inc @@ -0,0 +1,25 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 \ No newline at end of file diff --git a/l4-x86/l4-x-0/userifc/uid.inc b/l4-x86/l4-x-0/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-x-0/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-x/c-bind/new/compiler.h b/l4-x86/l4-x/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x/c-bind/new/idt.h b/l4-x86/l4-x/c-bind/new/idt.h new file mode 100644 index 0000000..2367ef5 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x/c-bind/new/ipc-trent.c b/l4-x86/l4-x/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x/c-bind/new/ipc.h b/l4-x86/l4-x/c-bind/new/ipc.h new file mode 100644 index 0000000..28ef5b6 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x/c-bind/new/kdebug.h b/l4-x86/l4-x/c-bind/new/kdebug.h new file mode 100644 index 0000000..ba636e0 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x/c-bind/new/kernel.h b/l4-x86/l4-x/c-bind/new/kernel.h new file mode 100644 index 0000000..60185ba --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x/c-bind/new/syscalls.h b/l4-x86/l4-x/c-bind/new/syscalls.h new file mode 100644 index 0000000..40ebac6 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x/c-bind/new/test.c b/l4-x86/l4-x/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-x/c-bind/new/types.h b/l4-x86/l4-x/c-bind/new/types.h new file mode 100644 index 0000000..11dc054 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x/c-bind/new/x-compiler.h b/l4-x86/l4-x/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x/c-bind/new/x-idt.h b/l4-x86/l4-x/c-bind/new/x-idt.h new file mode 100644 index 0000000..e7fa7f4 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x/c-bind/new/x-ipc.h b/l4-x86/l4-x/c-bind/new/x-ipc.h new file mode 100644 index 0000000..6f545d1 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x/c-bind/new/x-kdebug.h b/l4-x86/l4-x/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..9aaee28 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x/c-bind/new/x-kernel.h b/l4-x86/l4-x/c-bind/new/x-kernel.h new file mode 100644 index 0000000..3129490 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x/c-bind/new/x-lid.c b/l4-x86/l4-x/c-bind/new/x-lid.c new file mode 100644 index 0000000..6f27423 --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-x/c-bind/new/x-syscalls.h b/l4-x86/l4-x/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..26bf66a --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x/c-bind/new/x-types.h b/l4-x86/l4-x/c-bind/new/x-types.h new file mode 100644 index 0000000..eea5ccd --- /dev/null +++ b/l4-x86/l4-x/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:43 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x/c-bind/orig/compiler.h b/l4-x86/l4-x/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x/c-bind/orig/idt.h b/l4-x86/l4-x/c-bind/orig/idt.h new file mode 100644 index 0000000..f595d7a --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x/c-bind/orig/ipc-trent.c b/l4-x86/l4-x/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x/c-bind/orig/ipc.h b/l4-x86/l4-x/c-bind/orig/ipc.h new file mode 100644 index 0000000..389c8bc --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x/c-bind/orig/kdebug.h b/l4-x86/l4-x/c-bind/orig/kdebug.h new file mode 100644 index 0000000..f7f47bb --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x/c-bind/orig/kernel.h b/l4-x86/l4-x/c-bind/orig/kernel.h new file mode 100644 index 0000000..479eb7f --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x/c-bind/orig/syscalls.h b/l4-x86/l4-x/c-bind/orig/syscalls.h new file mode 100644 index 0000000..81695a7 --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x/c-bind/orig/types.h b/l4-x86/l4-x/c-bind/orig/types.h new file mode 100644 index 0000000..f0537d9 --- /dev/null +++ b/l4-x86/l4-x/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x/c-bind/provisional/compiler.h b/l4-x86/l4-x/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-x/c-bind/provisional/idl.m4 b/l4-x86/l4-x/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-x/c-bind/provisional/idt.h b/l4-x86/l4-x/c-bind/provisional/idt.h new file mode 100644 index 0000000..f595d7a --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-x/c-bind/provisional/ipc-trent.c b/l4-x86/l4-x/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-x/c-bind/provisional/ipc.h b/l4-x86/l4-x/c-bind/provisional/ipc.h new file mode 100644 index 0000000..9c08fe0 --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-x/c-bind/provisional/kdebug.h b/l4-x86/l4-x/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..f7f47bb --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-x/c-bind/provisional/kernel.h b/l4-x86/l4-x/c-bind/provisional/kernel.h new file mode 100644 index 0000000..479eb7f --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-x/c-bind/provisional/syscalls.h b/l4-x86/l4-x/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..81695a7 --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-x/c-bind/provisional/types.h b/l4-x86/l4-x/c-bind/provisional/types.h new file mode 100644 index 0000000..f0537d9 --- /dev/null +++ b/l4-x86/l4-x/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:44 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-x/hazelkd/adrspace.inc b/l4-x86/l4-x/hazelkd/adrspace.inc new file mode 100644 index 0000000..276b0b9 --- /dev/null +++ b/l4-x86/l4-x/hazelkd/adrspace.inc @@ -0,0 +1,29 @@ + + +virtual_space_size equ 0C0000000h + + +tcb_space equ 0E0000000h +tcb_space_size equ (16*MB) + +com_space_size equ (8*MB) +com0_base equ (tcb_space+32*MB) +com1_base equ (com0_base+com_space_size) + +shared_table_base equ (tcb_space) +shared_table_size equ (com1_base+com_space_size-shared_table_base) + +PM equ 0F0000000h + +KR equ PM + +physical_kernel_mem_size equ 128*MB + +kdebug_cached_alias_mem equ 0FF000000h + +kernel_begin equ 1*MB +kernel_size equ 72*KB + +shared_pseudotask_no equ 1 + + diff --git a/l4-x86/l4-x/hazelkd/intrifc.inc b/l4-x86/l4-x/hazelkd/intrifc.inc new file mode 100644 index 0000000..1954ead --- /dev/null +++ b/l4-x86/l4-x/hazelkd/intrifc.inc @@ -0,0 +1,136 @@ + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + + +int_pm_stack struc + + ip_es dd 0 + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) + + + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + push es + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + diff --git a/l4-x86/l4-x/hazelkd/kdinit.inc b/l4-x86/l4-x/hazelkd/kdinit.inc new file mode 100644 index 0000000..ca339bb --- /dev/null +++ b/l4-x86/l4-x/hazelkd/kdinit.inc @@ -0,0 +1,17 @@ + +kd_init struc + + kdebug_extension dd 0 + io_apic_ptr dd 0 + local_apic_ptr dd 0 + physical_kernel_info_page_ptr dd 0 + kernel_proot_ptr_ptr dd 0 + kdebug_configuration dd 0 + kdebug_permissions dd 0 + irq0_intr_number dd 0 + grab_frame_proc dd 0 + +kd_init ends + + + \ No newline at end of file diff --git a/l4-x86/l4-x/hazelkd/ktype.inc b/l4-x86/l4-x/hazelkd/ktype.inc new file mode 100644 index 0000000..c156fdb --- /dev/null +++ b/l4-x86/l4-x/hazelkd/ktype.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ x86 + +subtitle Hazelnut Kdebug/x86 Version X + +kernel_family = hazelnut + +kernel_type = x86 + +gver = 2 + +kernel_x2 = 0 +precise_cycles = 0 +random_sampling = 0 +random_profiling = 0 ; = 1 REQUIRES random_sampling = 1 + + ENDIF + + + + + + diff --git a/l4-x86/l4-x/hazelkd/pagmac.inc b/l4-x86/l4-x/hazelkd/pagmac.inc new file mode 100644 index 0000000..d7287a6 --- /dev/null +++ b/l4-x86/l4-x/hazelkd/pagmac.inc @@ -0,0 +1,32 @@ + +;---------------------------------------------------------------------------- +; +; load proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +load__proot macro reg,task_no + + ke 'load_proot' + endm + + + + + diff --git a/l4-x86/l4-x/hazelkd/segs.inc b/l4-x86/l4-x/hazelkd/segs.inc new file mode 100644 index 0000000..54367af --- /dev/null +++ b/l4-x86/l4-x/hazelkd/segs.inc @@ -0,0 +1,21 @@ + + +;------------------------------------------------------------------------ +; +; Hazelnut segment selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +kernel_space_exec equ 0008h +linear_kernel_space equ 0010h + +linear_space_exec equ (0018h+3) +linear_space equ (0020h+3) + +phys_mem equ 0030h + +cpu0_tss equ 0028h + + diff --git a/l4-x86/l4-x/hazelkd/tcb.inc b/l4-x86/l4-x/hazelkd/tcb.inc new file mode 100644 index 0000000..a36b2e0 --- /dev/null +++ b/l4-x86/l4-x/hazelkd/tcb.inc @@ -0,0 +1,142 @@ + +thread_control_block struc + + ipc_buffer dd 0,0,0 + ipc_timeout dd 0 + rcv_descriptor dd 0 + proot_ptr dd 0 + myself dd 0 + pager dd 0 + + + thread_idt_base dd 0 + thread_esp dd 0 + fine_state dd 0 + list_state dd 0 + prio dd 0 + timeslice dd 0 + rem_timeslice dd 0 + wakeup dd 0,0 ; /* valid, iff (queue_state & TS_QUEUE_WAKEUP) */ + + present_llink dd 0,0 ; /* valid, iff (list_state & is_PRESENT) */ + ready_llink dd 0,0 ; /* valid, iff (list_state & is_READY) */ + wakeup_llink dd 0,0 ; /* valid, iff (list_state & is_WAKEUP) */ + ressources dd 0 + + copy_area1 dd 0 + copy_area2 dd 0 + send_queue_head dd 0 + sndq_llink dd 0,0 ; /* valid, iff (list_state & is_WAKEUP) */ + partner dd 0 ; /* IPC-partner (if in IPC), otherwise partner we wait for, L4_NIL_ID if open wait */ + intr_pending dd 0 + unwind_ipc_sp dd 0 + + ifdef SMP + cpu dd 0 + tcb_spinlock dd 0 + endif + + scratch dd 0 + magic dd 0 + +thread_control_block ends + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +llinks struc + + pred dd 0 + succ dd 0 + +llinks ends + + + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xfree:4,xxcpu:1,xnlk:1,xnpo:1,xnbu:1 + +nready equ mask xnbu +npoll equ mask xnpo +nlock equ mask xnlk +xcpu equ mask xxcpu + + + +running equ ( +nlock+npoll ) +locked_waiting equ ( npoll+nready ) +locked_running equ ( npoll ) +polling equ ( nlock+ nready ) +aborted equ ( nlock+npoll+nready ) +waiting equ (-1) + +xcpu_locked_waiting equ (xcpu+ npoll+nready ) +xcpu_locked_running equ (xcpu+ npoll ) + + + +;------ list state masks --------------------- + + +is_ready equ 01 +is_present equ 02 +is_wakeup equ 04 +is_sendq equ 08 + + + +;------ resources ---------------------------- + + +com0_used equ 01 +com1_used equ 02 + +no_copy_area equ (-1) + + + + + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + diff --git a/l4-x86/l4-x/kernel/adrsman.asm b/l4-x86/l4-x/kernel/adrsman.asm new file mode 100644 index 0000000..43daacd --- /dev/null +++ b/l4-x86/l4-x/kernel/adrsman.asm @@ -0,0 +1,959 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 08, 08, 99, 9025 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 08.08.99 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86 + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + lno___task eax,ebp ; + load__proot eax,eax ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + lno___task edi,ebx ; + ; + call detach_associated_small_space ; + ; + load__proot edi,edi ; + ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + mov ecx,[(ecx*8)+task_proot].switch_ptr + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax ; + lea___tcb ebp,eax ; + ; + IFZ [edi*8+task_proot].proot_ptr,0 ; + mov edi,[edi*8+task_proot].switch_ptr ; + sub edi,ds:[empty_proot] ; + ELSE_ ; + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + pop eax + + lno___task ebp + store_proot eax,ebp + FI + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + + ret + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + + lno___task ebp,esi + lea edi,[ebp*8+task_proot] + + movzx eax,ah + movzx ecx,[edi].small_as + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*2)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*2)+small_associated_task],bp + FI + mov ecx,eax + mov [edi].small_as,al + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + mov [edi].switch_ptr,ecx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push eax + push edi + + movzx edi,[(ecx*2)+small_associated_task] + test edi,edi + IFNZ + mov word ptr [(ecx*2)+small_associated_task],0 + + call flush_small_pde_block_in_all_pdirs + + lea ecx,[(edi*8)+task_proot] + + mov eax,cr3 + mov cr3,eax + + mov eax,[ecx].proot_ptr + mov al,0 + mov [ecx].switch_ptr,eax + mov [ecx].proot_ptr,eax + FI + + lno___task eax,esp + IFZ eax,edi + call make_own_address_space_large + FI + + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; detach associated small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push ecx + + movzx ecx,[edi*8+task_proot].small_as + test ecx,ecx + IFNZ + call detach_small_space + FI + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; EDI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[edi].switch_ptr + mov edi,ds:[kernel_proot] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + lno___task edi,esp + + lea edi,[(edi*8)+task_proot] + mov eax,[edi].proot_ptr + mov al,0 + mov [edi].switch_ptr,eax + + mov edi,eax + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + mov fs,eax + if random_sampling OR fast_myself + mov eax,sampling_space + endif + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + mov edx,offset task_proot + DO + mov ebp,[edx].proot_ptr + add edx,8 + and ebp,0FFFFFF00h + REPEATZ + + EXITS + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + lno___task eax,esi + mov eax,[eax*8+task_proot].switch_ptr + + test eax,eax + IFNS + mov al,0 + ret + FI + + rol eax,8 + xchg al,ah + shr eax,22-16 + sub al,(offset small_virtual_spaces SHR 22) AND 0FFh + add al,al + add al,ds:[small_space_size_DIV_MB4] + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/atrace.asm b/l4-x86/l4-x/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-x/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-x/kernel/boot.asm b/l4-x86/l4-x/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-x/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-x/kernel/contents b/l4-x86/l4-x/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-x/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/cpuctr.asm b/l4-x86/l4-x/kernel/cpuctr.asm new file mode 100644 index 0000000..205715e --- /dev/null +++ b/l4-x86/l4-x/kernel/cpuctr.asm @@ -0,0 +1,1259 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 22,11,00, 73, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 22.11.00 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include cpucb.inc +.nolist +include segs.inc +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + shr al,4 + CORA al,p6_family + IFB_ al,p5_family + mov al,other_family + FI + mov ds:[cpu_family],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler + call define_idt_gate + + IFAE ds:[cpu_family],p6_family + + mov eax,cr4 + bts eax,cr4_enable_rdpmc + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + + switch_thread con,ebx + + shr ebp,task_no + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + push ebp + + shr ebp,task_no + + mov esi,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))].switch_ptr + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + and ebp,0FFFFFF00h + + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + + test esi,esi + IFNS + mov esi,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],esi + add esi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],esi + + pop ebp + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret + + +deallocate_ressources: + + push eax + + mov al,[edi+ressources] + +.errnz mask ts_prot-80h + test al,mask ts_prot+mask x87_used + xc s,thread_switch_prot,long + + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + mov eax,ebp + shr eax,task_no + mov eax,[(eax*8)+task_proot-(offset tcb_space SHR (task_no-3))] + CORA eax, + IFZ ds:[cpu_cr3],eax + + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used+mask in_partner_space + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd + push offset reallocate_ressources_by_ret + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +XHEAD thread_switch_prot + + or [ebp+ressources],mask ts_prot + + lno___thread eax,ebp + ke '/-cs->' + + mov al,[edi+ressources] + and al,NOT mask ts_prot + xret nz,long + + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + push eax + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + pop eax + FI + + test al,mask in_partner_space + IFNZ + mov eax,[ebp+com_partner] + lno___task eax,eax + mov eax,ss:[(eax*8)+task_proot+4] + and eax,0FFFFFF00h + + IFNZ eax,ss:[cpu_cr3] + mov ss:[cpu_cr3],eax + mov cr3,eax + FI + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],phys_mem_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/dispatch.asm b/l4-x86/l4-x/kernel/dispatch.asm new file mode 100644 index 0000000..4a27b8d --- /dev/null +++ b/l4-x86/l4-x/kernel/dispatch.asm @@ -0,0 +1,2351 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 07,12,00, 9095, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 07.12.00 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + extrn grab_frame:near + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +include segs.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +include pagmac.inc +.list + + +ok_for x86 + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc + call define_idt_gate + + if V4_clock_features + + mov eax,ds:[logical_info_page].cpu_clock_freq + call set_clock_factors + + call get_clock_usc + add eax,1000 + mov ds:[next_timer_int],eax + mov ds:[next_clock_tick],eax + mov ds:[next_random_sampling_event],eax + mov ds:[next_wakeup_event],eax + mov ds:[next_wakeup_precision],0 + + else + + mov ds:[system_clock],1 + + endif + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + if V4_clock_features EQ 0 + mov ecx,ds:[system_clock+4] + mov [ebp+wakeup+4],ecx + endif + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + if V4_clock_features EQ 0 + btr [ebp+wakeup],31 + IFC + mov eax,ds:[system_clock+4] + mov [ebp+wakeup+4],eax + FI + endif + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + klign 16 + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + cpu___cycles ebx + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + if precise_cycles + push ebx + mov ebx,offset dispatcher_tcb + cpu___cycles ebx + pop ebx + endif + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + if V4_clock_features EQ 0 + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock + + sub [esi+pulse_counter-offset system_clock],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + if precise_cycles eq 0 + add [ebx+cpu_clock],edx + xc c,inc_cpu_clock_high + endif + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc dword ptr ds:[esi+4] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + + if precise_cycles eq 0 + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock+4] + xret + + endif + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + endif + + + + + + + + if V4_clock_features + + + +;---------------------------------------------------------------------------- +;---------------------------------------------------------------------------- +; +; V4 timer interrupts +; +;---------------------------------------------------------------------------- +;---------------------------------------------------------------------------- + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + jmp timer_int + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + + mov ebx,esp + and ebx,-sizeof tcb + + call get_clock_usc + mov esi,eax + mov edi,edx + + mov eax,ds:[next_clock_tick] + sub eax,esi + sar eax,clock_tick_precision ; ! OF undefined after SAR ! + test eax,eax + xc le,clock_tick,long + + mov eax,ds:[next_random_sampling_event] + sub eax,esi + sar eax,random_sampling_precision ; ! OF undefined after SAR ! + test eax,eax + xc le,random_sampling_event,long + + mov eax,ds:[next_wakeup_event] + mov cl,ds:[next_wakeup_precision] + sub eax,esi + sar eax,cl ; ! OF undefined after SAR ! + test eax,eax + IFLE + + push edi + + lea edi,[esi+2*ticklength] + mov ch,clock_tick_precision + + movl__root ebp,instant_wakeup + DO + movl__next ebp,edx,instant_wakeup + EXITZ + + test [ebp+fine_state],nwake + IFZ + mov eax,[ebp+wakeup] + mov cl,[ebp+wakeup_precision] + sub eax,esi + sar eax,cl + test eax,eax + + IFG + mov eax,[ebp+wakeup] + cmp eax,edi + REPEATNS + mov edi,eax + mov ch,[ebp+wakeup_precision] + REPEAT + FI + + push esi + push edi + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + + pop edi + pop esi + ;mark__ready ebp + FI + ldel ebp,edx,soon_wakeup + REPEAT + OD + mov ds:[next_wakeup_event],edi + mov ds:[next_wakeup_precision],ch + + pop edi + + FI + + mov eax,ds:[next_clock_tick] + mov ecx,eax + mov edx,eax + + mov eax,ds:[next_random_sampling_event] + mov ecx,eax + sub eax,edi + IFS + mov edi,ecx + FI + + mov eax,ds:[next_wakeup_event] + mov ecx,eax + sub eax,edi + IFS + mov edi,ecx + FI + + mov ds:[next_clock_tick],edi + + mov eax,edi + sub eax,esi + IFB_ eax,4 + ke 'timer_too_close' + FI + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; setup timer + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + ipost + + + + + + + +XHEAD clock_tick + + add ds:[logical_info_page].user_clock,ticklength + xc c,inc_user_clock_high + + if precise_cycles eq 0 + add [ebx+cpu_clock],ticklength/1000 + xc c,inc_cpu_clock_high + endif + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + add ds:[next_clock_tick],ticklength + + xret ,long + + + + + +XHEAD inc_user_clock_high + + inc ds:[logical_info_page].user_clock+4 + xret + + + + + if precise_cycles eq 0 + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock+4] + xret + + endif + + + + + + + +XHEAD random_sampling_event + + xret ,long + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + mov edi,ds:[next_wakeup_event] + movl__root ebp,soon_wakeup + + klign 16 + DO + movl__next ebp,edx,soon_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + mov eax,[ebp+wakeup] + mov ecx,eax + sub eax,esi + cmp eax,2*ticklength + REPEATA + + test [ebp+list_state],is_instant_wakeup + IFZ + lins ebp,eax,instant_wakeup + + sub ecx,edi + IFS + mov edi,[ebp+wakeup] + mov al,[ebp+wakeup_precision] + mov ds:[next_wakeup_event],edi + mov ds:[next_wakeup_precision],al + FI + FI + FI + ldel ebp,edx,late_wakeup + REPEAT + OD + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + mov eax,[ebp+wakeup] + sub eax,esi + cmp eax,late_wakeup_interval*ticklength + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,eax,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + + sub dl,dl + mov edi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + mov eax,[ebp+wakeup] + sub eax,esi + cmp eax,late_late_wakeup_interval*ticklength + REPEATG + + lins ebp,eax,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp edi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + endif + + + + + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + ELIFZ ebx,[esi+int_preempter] + add dl,20h + ELIFZ ebx,[esi+ext_preempter] + add dl,30h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + FI + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFBE ah,2*max_small_spaces-1 + call attach_small_space + FI + + FI + mov ebx,edx + + + if precise_cycles + + mov ecx,[esi+cpu_cycles] + mov edx,[esi+cpu_cycles+4] + + else + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup] + if V4_clock_features + call get_clock_usc + mov edi,eax + mov eax,[esi+wakeup] + sub eax,edi + mov edi,[esi+wakeup+4] + sub edi,edx + mov edx,edi + else + sub eax,ds:[system_clock] + mov edx,1000 + mul edx + endif + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock] + mov edi,1000 + mul edi + add edx,ecx + mov ecx,[esi+cpu_clock+4] + imul ecx,edi + add edx,ecx + mov ecx,eax + + endif + + + mov eax,ebx + + mov ebx,[esi+ext_preempter] + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + if V4_clock_features + + + public get_clock_usc + + +;---------------------------------------------------------------------------- +; +; USC get clock +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; user mode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX:EDX time in microseconds +; +;---------------------------------------------------------------------------- + + strtseg + + ; 1 000 000 ( tsc ö freq) + (1 000 000 (tsc % freq) + freq/2) ö freq + +get_clock_usc: + + push esi + push edi + + mov esi,1000000 + + clock_rate_immediate equ ($+1) + mov edi,999999 + + rdtsc + + div edi + + push eax + mov eax,edx + sub edx,edx + mul esi + clock_rate_half_immediate equ ($+1) + add eax,99999 + adc edx,0 + div edi + mov edi,eax + pop eax + + sub edx,edx + mul esi + + add eax,edi + adc edx,0 + + pop edi + pop esi + ret + + + + strt ends + + + +;---------------------------------------------------------------------------- +; +; set clock factors +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX processor frequency +; +;---------------------------------------------------------------------------- + + +set_clock_factors: + + push eax + + mov dword ptr ds:[clock_rate_immediate+PM],eax + shr eax,1 + adc eax,0 + mov dword ptr ds:[clock_rate_half_immediate+PM],eax + + pop eax + ret + + + +endif + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + clign 4 + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + clign 16 + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + if random_sampling OR fast_myself + + +;*************************************************************************************************** +;*************************************************************************************************** +;********* ******** +;********* ******** +;********* Random Samlpling (Measurement Support) ******** +;********* ******** +;********* ******** +;*************************************************************************************************** +;*************************************************************************************************** + + + align 16 + + + public init_random_sampling + + public profiling_space_begin + public profiling_space_size + + + extrn irq0_intr:abs + + + + +;;sampled_total dd 0 +;; +;;sampled dd 6 dup (0) +;; +;;sampl_flags dd 0 +;; +;; +;;sampl_block equ sampled_total +;;sampl_block_len equ (8*4) +;; + + + + +random_seed dd 0 + +random_mul equ 9301 +random_add equ 49297 +random_mod equ 233280 + +ctc_8253_freq equ 1193180 ; Hz + +ticks_per_milli equ (ctc_8253_freq/1000) + + +ctc_cmd equ 43h +ctc_channel0 equ 40h + +one_shot_channel0 equ 00110000b + + + +pic1_imr equ 21h +pic1_ocw2 equ 20h + +seoi0 equ 60h + + + +profiling_space_begin dd 0 + +profiling_min equ (0*MB) +profiling_max equ (64*MB) + +profiling_space_size equ ((profiling_max-profiling_min)/32*4) + + + + +;--------------------------------------------------------------------------------------------- +; +; random ticks +; +;--------------------------------------------------------------------------------------------- +; random_ticks POSTCONDITION +; +; +; EAX random ticks: [10 ticks ... 1 ms) +; +;--------------------------------------------------------------------------------------------- + + + + icode + + +init_random: + + pushad + + rdtsc + mov ecx,eax + + ke 'random sampling kernel' + + rdtsc + sub eax,ecx + + sub edx,edx + mov ecx,random_mod + div ecx + + mov ds:[random_seed],edx + + popad + ret + + + icod ends + + + + + +random_ticks: + + push ecx + push edx + + mov eax,ds:[random_seed+PM] + mov ecx,random_mul + mul ecx + + add eax,random_add + adc edx,0 + + mov ecx,random_mod + div ecx + + mov ds:[random_seed+PM],edx + + mov eax,edx + mov ecx,ticks_per_milli + mul ecx + mov ecx,random_mod + div ecx + + IFB_ eax,10 + add eax,10 + FI + + pop edx + pop ecx + ret + + + + +;--------------------------------------------------------------------------------------------- +; +; random sampling interrupt +; +;--------------------------------------------------------------------------------------------- + + + icode + + + +init_random_sampling: + + mov word ptr ds:[gdt+(sampling_space AND -8)],sampl_block_len-1 + + mov eax,offset sampl_block + mov word ptr ds:[gdt+(sampling_space AND -8)+2],ax + shr eax,16 + mov byte ptr ds:[gdt+(sampling_space AND -8)+4],al + mov byte ptr ds:[gdt+(sampling_space AND -8)+7],ah + + push sampling_space + pop gs + + if random_sampling + + call init_random + + mov bl,irq0_intr + mov bh,0 SHL 5 + mov eax,offset random_sampling_interrupt_handler + call define_idt_gate + + mov al,one_shot_channel0 + out [ctc_cmd],al + + call random_ticks + + out [ctc_channel0],al + mov al,ah + out [ctc_channel0],al + + in al,[pic1_imr] + and al,11111110b + out [pic1_imr],al + + if random_profiling + + call init_random_profiling + + endif + + endif + + ret + + + icod ends + + + + +random_sampling_interrupt_handler: + + ipre fault + + + inc ds:[sampled_total] + + mov eax,ds:[sampl_flags] + and eax,111111b + + mov ebx,offset sampled + DO + test eax,eax + EXITZ + shr eax,1 + adc dword ptr ds:[ebx],0 + add ebx,4 + REPEAT + OD + + + if random_profiling + + mov edi,ss:[esp+ip_eip] + IFZ ss:[esp+ip_cs],phys_mem_exec + add edi,PM + ELSE_ + mov eax,ds:[gdt+linear_space_exec/8*8] + mov ebx,ds:[gdt+linear_space_exec/8*8+4] + shr eax,16 + and ebx,0FF0000FFh + rol ebx,8 + bswap ebx + add eax,ebx + add edi,eax + FI + + mov ebx,cr3 + and ebx,-pagesize + xpdir eax,edi + mov ebx,dword ptr ds:[eax*4+ebx+PM] + test ebx,page_present + IFNZ + test ebx,superpage + IFZ + and ebx,-pagesize + xptab eax,edi + mov ebx,dword ptr ds:[eax*4+ebx+PM] + FI + and ebx,-pagesize + mov eax,edi + and eax,pagesize-1 + add eax,ebx + IFAE eax,profiling_min + CANDB eax,profiling_max + + shr eax,5 + mov ebx,ds:[profiling_space_begin+PM] + lea ebx,[eax*4+ebx+PM] + + mov eax,dword ptr ds:[ebx] + inc eax + and eax,pagesize-1 + IFNZ + and edi,-pagesize + or eax,edi + mov dword ptr ds:[ebx],eax + FI + FI + FI + + endif + + + mov al,one_shot_channel0 + out [ctc_cmd],al + + call random_ticks + + out [ctc_channel0],al + mov al,ah + out [ctc_channel0],al + + mov al,seoi0 + out [pic1_ocw2],al + + + ipost + + + + endif + + + + if random_profiling + + +;--------------------------------------------------------------------------------------------- +; +; random profiling +; +;--------------------------------------------------------------------------------------------- + + + + icode + + +init_random_profiling: + + pushad + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + cmp ecx,profiling_space_size + REPEATB + ELSE_ + ke 'not enough profiling space' + lea eax,[eax+ebx] + FI + OD + + mov [profiling_space_begin],eax + + push ds + pop es + + lea edi,[eax+PM] + mov ecx,profiling_space_size/4 + sub eax,eax + cld + rep stosd + + popad + ret + + + icod ends + + + endif + + + + + + + + + + + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/emuctr.asm b/l4-x86/l4-x/kernel/emuctr.asm new file mode 100644 index 0000000..f8df428 --- /dev/null +++ b/l4-x86/l4-x/kernel/emuctr.asm @@ -0,0 +1,514 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86 + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + clign 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-x/kernel/idecode.asm b/l4-x86/l4-x/kernel/idecode.asm new file mode 100644 index 0000000..6a3760f --- /dev/null +++ b/l4-x86/l4-x/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],phys_mem_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-x/kernel/intctr.asm b/l4-x86/l4-x/kernel/intctr.asm new file mode 100644 index 0000000..472137a --- /dev/null +++ b/l4-x86/l4-x/kernel/intctr.asm @@ -0,0 +1,560 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 18,12,00, 61 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 18.12.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include segs.inc +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86 + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler + db dpl3 + dd offset initial_debug_exception_handler + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler + db dpl3 + dd offset overflow_handler + db dpl3 + dd offset bound_check_handler + db dpl3 + dd offset invalid_opcode_handler + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler + db dpl0 + dd offset stack_exception_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler + db dpl0 + dd offset alignment_check_handler + db dpl0 + dd offset machine_check_exception + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,phys_mem_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + push es + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + ; mov ecx,linear_space ; + ; CORNZ [esp+ip_ds],ecx ; + ; mov edx,es ; + ; IFNZ edx,ecx ; + ; test byte ptr ss:[esp+ip_cs],11b + ; IFNZ ; + ; mov [esp+ip_ds],ecx; do not update DS + ; mov [esp+ip_es],ecx; do not update ES + ; ; if within kernel ! + ; ipost ; (DS might be kernel seg) + ; FI ; + ; FI ; + + + IFBE word ptr ss:[esp+ip_ds],3 + mov [esp+ip_ds],linear_space + ipost + FI + IFBE word ptr ss:[esp+ip_es],3 + mov [esp+ip_es],linear_space + ipost + FI + + if random_sampling OR fast_myself + mov edx,gs + IFNZ edx,sampling_space + push sampling_space + pop gs + ipost + FI + endif + + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + lno___task edi,esp + test byte ptr ss:[edi*8+task_proot+3].switch_ptr,80h + CANDNZ + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_permissions.max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + push eax + push 0 + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-x/kernel/ipcman.asm b/l4-x86/l4-x/kernel/ipcman.asm new file mode 100644 index 0000000..79ed654 --- /dev/null +++ b/l4-x86/l4-x/kernel/ipcman.asm @@ -0,0 +1,3645 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCmvs, 07,09,00, 9182, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 07.09.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + +;;;cache_align db (KB2+384) dup (0) + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + + push ds + push es + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + shr ebp,task_no + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + cpu___cycles ebx ; ebx = dispatcher_tcb + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + + + push eax + push ebx + + cmp eax,virtual_space_size-MB4 + jae receive_only + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + mov [ebx+waiting_for],esi + + if redirection + + and al,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + ; + and ebp,mask task_no ; + mov edx,ebx ; + ; + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + mov edx,[edx+ebp+redirection_table] ; + ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + endif + + and ebp,mask thread_no + + mov [ebx+mword2],edi + add ebp,offset tcb_space + + mov edi,[ebx+myself] + + if redirection EQ 0 + and al,(NOT ipc_control_mask)+deceit+map_msg + endif + + mov edx,[ebp+myself] + xor edi,esi + + test edi,mask chief_no + xc nz,to_chief,long + + cmp esi,edx + jnz ipc_dest_not_existent + + test al,deceit + xc nz,propagate_pre,long + + mov dl,[ebp+fine_state] + + + and dl,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + xc nz,pending_or_auto_propagating,long + FI + + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + + mov edx,[ebx+rcv_descriptor] + mov ch,running + + mov [ebp+fine_state],ch + cmp edx,virtual_space_size + + mov dh,[ebx+list_state] + IF____xc ae,send_only,long + + ELSE__ + and edx,(is_polled SHL 8) + nclos + + cmp edx,(is_polled SHL 8) + nclos + jz fetch_next + + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + +;;;;; switch_thread ipc,edi + mov cl,[edi+ressources] + + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + cpu___cycles edi + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + shr ebp,task_no + mov esi,[edi+myself] + + test al,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + + +;;;;;;;;;;;; switch_space + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + cmp byte ptr ds:[gdt+linear_space/8*8+7],0 + mov cr3,ebp + mov ebp,linear_space + IFZ + mov ds,ebp + pop ebp + iretd + FI + FI + mov ebp,00CCF300h + FI + + IFNZ ebp,ds:[gdt+linear_space/8*8+4] + + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + + mov ds:[gdt+linear_space_exec/8*8+4],ebp + FI + + mov ebp,linear_space + + mov es,ebp + + mov fs,ebp + + mov ds,ebp + + if random_sampling OR fast_myself + mov ebp,sampling_space + endif + mov gs,ebp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pop ebp + iretd + + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z + + mov esi,[edi+virtual_sender] + xret + + + + + +XHEAD send_only + + if prio_sensitive_donation_on_send + + mov cl,[ebp+prio] + mov ch,[ebx+prio] + cmp cl,ch + jb send_without_donate + + endif + + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + mov edi,[esp+iret_esp+3*4] ; must be read from user space, + sub edx,edx + + mov [ebx+propagatee_tcb],edx + mov edi,es:[edi] ; potentially small space + + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + mov [ebx+virtual_sender],edi + + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + test esi,mask task_no + IFZ + lea___tcb esi,edi + + test__page_writable esi + IFNC + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + CANDZ dl,closed_wait + CANDZ [ebx+myself],edi + + mov [ebx+propagatee_tcb],esi + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + xret ,long + FI + + if redirection + + ;REDIR begin -------------------------------- + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + test edx,mask chief_no ; ; + xret z,long ; + ; + mov edx,[ebx+myself] ; + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; + ; + and ebp,mask task_no ; + mov esi,edi ; + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + pop ebp ; + pop ecx ; + xret ,long ; + OD ; + pop ebp ; + pop ecx ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + ;REDIR ends ----------------------------------- + endif + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + if V4_clock_features + ;;;;;;;;;;;;;;;;;;;;;; + else + add edi,ds:[system_clock] + mov [ebx+wakeup],edi + endif + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + mov edx,(locked_running SHL 8) + (locked_waiting AND 0FFh) + + mov [ebx+fine_state],dh + mov [ebp+fine_state],dl + + and al,ipc_control_mask + mov esi,[esp+4+4] + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + IFNZ + mov bl,al + mov eax,es:[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w3 + nop + + mov eax,[eax*8+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + and eax,0FFFFFF00h + mov edx,ds:[cpu_cr3] + + IFNZ eax,edx + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + + ELSE_ + + mark__ressource ebx,in_partner_space + + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w3] + + mov edi,[edx+32] + lea edi,[edx+msg_w3] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressources ebx,com_used,in_partner_space + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + nop + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w3 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + push es + push ds + pop es + mov eax,ecx + and ecx,-8 + and eax,8-1 + rep movsd + mov ecx,eax + pop es + ret + + ;; DO + ;; mov eax,[esi] + ;; mov ebx,[edi+32] + ;; mov ebx,[esi+4] + ;; mov [edi],eax + ;; mov [edi+4],ebx + ;; mov eax,[esi+8] + ;; mov ebx,[esi+12] + ;; mov [edi+8],eax + ;; mov [edi+12],ebx + ;; mov eax,[esi+16] + ;; mov ebx,[esi+20] + ;; mov [edi+16],eax + ;; mov [edi+20],ebx + ;; mov eax,[esi+24] + ;; mov ebx,[esi+28] + ;; mov [edi+24],eax + ;; mov [edi+28],ebx + ;; add esi,32 + ;; add edi,32 + ;; sub ecx,8 + ;; cmp ecx,8 + ;; REPEATA + ;; OD + ;; ret + + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + and eax,7FFFFFFFh + and ebx,7FFFFFFFh + + mov ecx,MB4 + IFB_ eax,ecx + mov ecx,eax + FI + IFB_ ebx,ecx + mov ecx,ebx + FI + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + ;;mov edx,ebx + ;;xor edx,ebp + ;;test edx,mask task_no + ;;IFNZ + + lno___task edx,ebp ;; + mov edx,ds:[edx*8+task_proot].proot_ptr ;; + IFNZ edx,ds:[cpu_cr3] ;; + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATS + + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + + + if 0 ;----------------------------------------- + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w3-2*4] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w3-2*4] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + + push eax + push ebx + + mov eax,[edi+buf_addr] + mov [edi+str_len],ecx + mov [edi+str_addr],eax + + mov esi,[esi+str_addr] + mov edi,eax + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + + + endif ;-------------------------------------- + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +XHEAD prepare_small_string_source + + shl eax,16 + + lea edx,[esi+ecx] + sass__32 cmp,edx,MB4 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + align 16 + + + +fetch_next: + + add dl,locked_closed_waiting + mov [ebx+fine_state],dl + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + if prio_sensitive_donation_on_send + + + align 16 + + + +send_without_donate: + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + mov [ebx+fine_state],running + + pop eax + sub eax,eax + iretd + + + + endif + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + if redirection + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + endif + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + if redirection + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + endif + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebx+myself] + DO + mov dl,[ebp+coarse_state] + add ebp,sizeof tcb + test dl,auto_propagating + EXITZ + + test__page_writable ebp + EXITC + + test [ebp+coarse_state],ndead + EXITZ + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + sub ebp,sizeof tcb + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + if V4_clock_features + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + else + add edi,ds:[system_clock] + mov [ebx+wakeup],edi + endif + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup] + mov edi,[ebp+wakeup+4] + pushfd + cli + if V4_clock_features + extrn get_clock_usc:near + call get_clock_usc + else + mov eax,ds:[system_clock] + mov edx,ds:[system_clock+4] + endif + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,edx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-x/kernel/kdebug-old.asm b/l4-x86/l4-x/kernel/kdebug-old.asm new file mode 100644 index 0000000..6a8c6fd --- /dev/null +++ b/l4-x86/l4-x/kernel/kdebug-old.asm @@ -0,0 +1,6052 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 08,10,00, 81 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 08.10.00 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_proot +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86 + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread0 dd 0 +ipc_prot_thread1 dd 0 +ipc_prot_thread2 dd 0 +ipc_prot_thread3 dd 0 +ipc_prot_thread4 dd 0 +ipc_prot_thread5 dd 0 +ipc_prot_thread6 dd 0 +ipc_prot_thread7 dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + +processor_family db 0 + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,cs:[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,[ebx+1] + IFNZ al,'*' + cmp al,'#' + IFNZ + cmp al,'/' + FI + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + if precise_cycles + IFAE esp, + push ds + push linear_kernel_space + pop ds + push ebx + mov ebx,esp + and ebx,-sizeof tcb + cpu___cycles ebx + pop ebx + pop ds + FI + endif + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + if precise_cycles + IFAE esp, + push ds + push linear_kernel_space + pop ds + push ebx + mov ebx,esp + and ebx,-sizeof tcb + cpu___cycles ebx + pop ebx + pop ds + FI + endif + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_proot + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'S',long + call thread_switch_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'S' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,cs:[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + kd____disp <13,10,'S : monit thrdswtch */- : trace/off'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ cs:[no_breakpoint_thread],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ cs:[breakpoint_thread],0 + cmp cs:[breakpoint_thread],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp cs:[debug_exception_handler] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ cs:[bx_size],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + + call outthread + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup + show <'+'>,wakeup+4 + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + if precise_cycles + kd____disp <6,5,0, 'cpu cycles: '> + mov eax,[esi+cpu_cycles+4] + kd____outhex32 + mov eax,[esi+cpu_cycles] + kd____outhex32 + else + kd____disp <6,5,0, 'cpu time: '> + mov eax,[esi+cpu_clock+4] + kd____outhex8 + mov eax,[esi+cpu_clock] + kd____outhex32 + endif + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + +outthread: + + push eax + + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + + and al,lthreads-1 + kd____outhex8 + + pop eax + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + test cs:[physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + mov eax,cs:[kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + IFZ ebp,cs:[kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_proot + ELIFZ al,'t' + mov eax,offset task_proot + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + kd____disp <6,2,1,'sys clock : '> + if V4_clock_features + extrn get_clock_usc:near + call get_clock_usc + else + mov eax,ds:[system_clock] + mov edx,ds:[system_clock+4] + endif + push eax + mov eax,edx + kd____outhex32 + pop eax + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop es + pop ds + + popad + jmp cs:[page_fault_handler] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread0],eax + mov [ipc_prot_thread1],eax + mov [ipc_prot_thread2],eax + mov [ipc_prot_thread3],eax + mov [ipc_prot_thread4],eax + mov [ipc_prot_thread5],eax + mov [ipc_prot_thread6],eax + mov [ipc_prot_thread7],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + test eax,eax + IFNZ + xchg [ipc_prot_thread0],eax + xchg [ipc_prot_thread1],eax + xchg [ipc_prot_thread2],eax + xchg [ipc_prot_thread3],eax + xchg [ipc_prot_thread4],eax + xchg [ipc_prot_thread5],eax + xchg [ipc_prot_thread6],eax + mov [ipc_prot_thread7],eax + ELSE_ + xchg [ipc_prot_thread7],eax + xchg [ipc_prot_thread6],eax + xchg [ipc_prot_thread5],eax + xchg [ipc_prot_thread4],eax + xchg [ipc_prot_thread3],eax + xchg [ipc_prot_thread2],eax + xchg [ipc_prot_thread1],eax + mov [ipc_prot_thread0],eax + FI + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + sub ecx,ecx + IFB_ ebp,virtual_space_size + mov ecx,ebp + and cl,011b + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + ELSE_ + mov al,0 + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + DO + cmp [ipc_prot_thread0+PM],0 + EXITZ + cmp [ipc_prot_thread0+PM],eax + EXITZ + cmp [ipc_prot_thread1+PM],eax + EXITZ + cmp [ipc_prot_thread2+PM],eax + EXITZ + cmp [ipc_prot_thread3+PM],eax + EXITZ + cmp [ipc_prot_thread4+PM],eax + EXITZ + cmp [ipc_prot_thread5+PM],eax + EXITZ + cmp [ipc_prot_thread6+PM],eax + EXITZ + cmp [ipc_prot_thread7+PM],eax + OD + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + + popad + add esp,4 + jmp cs:[ipc_handler] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + call outthread + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + ELSE_ kd____disp <' -'> + kd____outhex8 + kd____disp <'- '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + call outthread + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,cs:[monitored_exception] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,cs:[monitored_ec_min] + movzx ecx,cs:[monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop es + pop ds + + popad + + CORB cs:[monitored_exception],8 + IFA cs:[monitored_exception],14 + IFNZ cs:[monitored_exception],17 + add esp,4 + FI + FI + + jmp cs:[monitored_exception_handler] + + + + +;---------------------------------------------------------------------------- +; +; monitor thread switch +; +;---------------------------------------------------------------------------- + + +thread_switch_prot: + + IFB_ esp, + ret + FI + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inchar + + IFZ al,'*' + kd____outchar + or ss:[ebp+ressources],mask ts_prot + ret + FI + + IFZ al,'-' + kd____outchar + mov eax,ebp + DO + and ss:[eax+ressources],NOT mask ts_prot + mov eax,ss:[eax+present_llink].succ + cmp eax,ebp + REPEATNZ + DO + ret + FI + + mov al,'?' + kd____outchar + ret + + + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop es + pop ds + + popad + add esp,4 + FI + + jmp cs:[timer_intr_handler] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_proot + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__proot edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + IFZ cl,'/' + mov al,82h + FI + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + IFZ al,80h + push eax + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + kd____disp <', thread='> + pop eax + shr eax,8 + call outthread + ret + FI + + IFZ al,81h + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + kd____disp <', thread='> + pop eax + shr eax,8 + call outthread + ret + FI + + IFZ al,82h + kd____disp <' '> + shr eax,8 + call outthread + kd____disp <' '> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' '> + mov eax,ebx + call outthread + ret + FI + + kd____disp <'???'> + ret + + + + +display_thread_event: + + shr eax,8 + call outthread + + kd____disp <' '> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' '> + mov eax,ebx + call outthread + + ret + + + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0,long + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + mov dword ptr [edi+trace_entry_type],80h + mov dword ptr [edi+trace_entry_string],'-4L ' + mov byte ptr [edi+trace_entry_string],8 + mov dword ptr [edi+trace_entry_string+4],'RATS' + mov dword ptr [edi+trace_entry_string+8],'T' + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + add edi,sizeof trace_buffer_entry + mov [trace_buffer_in_pointer],edi + sub ecx,sizeof trace_buffer_entry + + shr ecx,2 + sub eax,eax + cld + rep stosd + + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ ,,long + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + + mov al,[processor_family+PM] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P5_event_select_msr + mov eax,ebx + wrmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + mov ebx,eax + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P6_event_select0_msr + mov eax,ebx + wrmsr + FI + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov eax,[trace_buffer_in_pointer] + mov ebx,[eax+trace_entry_timestamp] + or ebx,[eax+trace_entry_timestamp+4] + IFZ + sub eax,[trace_buffer_begin] + CANDZ eax,sizeof trace_buffer_entry + ret + FI + + + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + kd____disp <' no trace buffer',13,10> + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + EXITZ + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +P5_event_select_msr equ 11h +P5_event_counter0_msr equ 12h +P5_event_counter1_msr equ 13h + + + +P5_rd_miss equ 000011b +P5_wr_miss equ 000100b +P5_rw_miss equ 101001b +P5_ex_miss equ 001110b + +P5_d_wback equ 000110b + +P5_rw_tlb equ 000010b +P5_ex_tlb equ 001101b + +P5_a_stall equ 00011111b +P5_w_stall equ 00011001b +P5_r_stall equ 00011010b +P5_x_stall equ 00011011b +P5_agi_stall equ 00011111b + +P5_bus_util equ 00011000b + +P5_pipline_flush equ 010101b + +P5_non_cache_rd equ 011110b +P5_ncache_refs equ 011110b +P5_locked_bus equ 011100b + +P5_mem2pipe equ 001001b +P5_bank_conf equ 001010b + + +P5_instrs_ex equ 010110b +P5_instrs_ex_V equ 010111b + + + + + + +P6_event_select0_msr equ 186h +P6_event_select1_msr equ 187h +P6_event_counter0_msr equ 0C1h +P6_event_counter1_msr equ 0C2h + + + + +;P6_rd_miss equ +P6_wr_miss equ 46h +P6_rw_miss equ 45h +P6_ex_miss equ 81h + +P6_d_wback equ 47h + +;P6_rw_tlb equ +P6_ex_tlb equ 85h + +P6_stalls equ 0A2h + +;P6_L2_rd_miss equ +P6_L2_wr_miss equ 25h +P6_L2_rw_miss equ 24h +P6_L2_ex_miss equ + +P6_L2_d_wback equ 27h + + + +P6_bus_util equ 62h + + +P6_instrs_ex equ 0C0h + + + + + + + +set_performance_tracing: + + push ds + push linear_kernel_space + pop ds + mov al,ds:[cpu_family] + pop ds + mov [processor_family],al + + IFNZ al,p5_family + CANDNZ al,p6_family + kd____disp <' not supported by this processor',13,10> + sub eax,eax ; Z! + ret + FI + + + kd____clear_page + call show_trace_perf_monitoring_mode + + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + + mov al,[processor_family] + IFZ al,p5_family,long + + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + ELIFZ al,p6_family,long + + kd____disp <'1 : L1 Dcache Misses (rd/wback)',13,10> + kd____disp <'2 : L2 Cache Misses (rd/wback)',13,10> + kd____disp <'i : Icache/ITLB Misses',13,10> + kd____disp <'I : Instructions/stalls',13,10> + kd____disp <'b : Bus Utilization/Instructions',13,10> + FI + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + mov ah,[processor_family] + IFZ ah,p5_family,long + + sub ebx,ebx + IFZ al,'i' + mov ebx,P5_instrs_ex + (P5_instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,P5_rw_miss + (P5_ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,P5_rw_tlb + (P5_ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,P5_r_stall + (P5_w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,P5_agi_stall + (P5_bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,P5_bus_util + (P5_instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + mov ecx,P5_event_counter0_msr + wrmsr + mov ecx,P5_event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,P5_event_select_msr + wrmsr + FI + + + ELIFZ ah,p6_family,long + + sub ebx,ebx + sub ecx,ecx + + IFZ al,'1' + mov bl,P6_rw_miss + mov cl,P6_d_wback + FI + IFZ al,'2' + mov bl,P6_L2_rw_miss + mov cl,P6_L2_d_wback + FI + IFZ al,'i' + mov bl,P6_ex_miss + mov cl,P6_ex_tlb + FI + IFZ al,'I' + mov bl,P6_instrs_ex + mov cl,P6_stalls + FI + IFZ al,'b' + mov bl,P6_bus_util + mov cl,P6_instrs_ex + FI + + test ebx,ebx + IFNZ + push ecx + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + wrmsr + mov ecx,P6_event_counter1_msr + wrmsr + pop ecx + + bts ebx,22 ; enable counters + + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,10b + ELIFZ al,user_perf_mon + mov al,01b + ELSE_ + mov al,11b + FI + shl eax,16 + or ebx,eax + or ecx,eax + + mov eax,ecx + mov ecx,P6_event_select1_msr + wrmsr + mov eax,ebx + mov ecx,P6_event_select0_msr + wrmsr + FI + + + FI + + + test esp,esp ; NZ ! + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/kdebug.asm b/l4-x86/l4-x/kernel/kdebug.asm new file mode 100644 index 0000000..daa41eb --- /dev/null +++ b/l4-x86/l4-x/kernel/kdebug.asm @@ -0,0 +1,7941 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 02,02,01, 2001 + + +;********************************************************************* +;****** ****** +;****** L4 Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 02.02.01 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc + +include ktype.inc +include adrspace.inc +include tcb.inc +include segs.inc + +include intrifc.inc +include pagconst.inc +include syscalls.inc +include pagmac.inc + IF kernel_family EQ lime_pip +include schedcb.inc +include pnodes.inc + ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86 + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + public kdebug_reset_pc + + + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; System Interface Pointers +; +;---------------------------------------------------------------------------- + +gidt_dope struc + limit dw 0 + base dd 0 +gidt_dope ends + + + align 4 + + dw 0 +gdt_descr gidt_dope <0,0> + + dw 0 +idt_descr gidt_dope <0,0> + + +permissions kdebug_permissions_word <0,0,0> +configuration kdebug_configuration_word <0,0,0> + +kernel_proot_ptr_ptr dd 0 + +phys_kernel_info_page_ptr dd 0 + +irq0_intr dd 0 + +grab_frame dd offset kdebug_grab_frame +kdebug_extension dd 0 + +io_apic_base dd 0 +local_apic_base dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + +ktest_page_present macro reg + + push eax + push ebx + mov eax,reg + sub ebx,ebx ;self + call page_phys_address + pop ebx + pop eax + endm + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + +kdebug_stack_bottom dd 0 + +kdebug_invocation_stamp dd 0 + +kdebug_rdtsc_corrector dd 0,0 + +perf_counter0_value dd 0 +perf_counter1_value dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + +int3_exception_handler dd 0 + + +kdebug_uncacheable_PDE dd 0 + +performance_count_params dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread0 dd 0 +ipc_prot_thread1 dd 0 +ipc_prot_thread2 dd 0 +ipc_prot_thread3 dd 0 +ipc_prot_thread4 dd 0 +ipc_prot_thread5 dd 0 +ipc_prot_thread6 dd 0 +ipc_prot_thread7 dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug cache snapshots +; +;---------------------------------------------------------------------------- + + align 4 + +cache_snapshots_begin dd 0 +cache_snapshots_end dd 0 +current_cache_snapshot dd 0 + +current_cache_snapshot_stamp dd 0 + +typical_cached_data_cycles dd 0 + +dcache_sets equ 128 +dcache_associativity equ 4 +dcache_line_size equ 32 +log2_dcache_line_size equ 5 + +icache_sets equ 128 +icache_associativity equ 4 +icache_line_size equ 32 +log2_icache_line_size equ 5 + + +snapshot_dwords_per_dcache_set equ 8 +log2_snapshot_dwords_per_dcache_set equ 3 +snapshot_bytes_per_dcache_set equ (snapshot_dwords_per_dcache_set*4) +log2_snapshot_bytes_per_dcache_set equ (log2_snapshot_dwords_per_dcache_set+2) + +snapshot_dwords_per_icache_set equ 8 +log2_snapshot_dwords_per_icache_set equ 3 + + + +cache_snapshot struc + dcache dd (dcache_sets*snapshot_dwords_per_dcache_set) dup (?) +cache_snapshot ends + + + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 +kernel_versus_user_perf_mon equ 4 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + +processor_family db 0 +processor_feature_flags dd 0 + + + +;--------------------------------------------------------------------------------- +; +; performance counters +; +;--------------------------------------------------------------------------------- + + +P5_event_select_msr equ 11h +P5_event_counter0_msr equ 12h +P5_event_counter1_msr equ 13h + + + +P5_rd_miss equ 000011b +P5_wr_miss equ 000100b +P5_rw_miss equ 101001b +P5_ex_miss equ 001110b + +P5_d_wback equ 000110b + +P5_rw_tlb equ 000010b +P5_ex_tlb equ 001101b + +P5_a_stall equ 00011111b +P5_w_stall equ 00011001b +P5_r_stall equ 00011010b +P5_x_stall equ 00011011b +P5_agi_stall equ 00011111b + +P5_bus_util equ 00011000b + +P5_pipline_flush equ 010101b + +P5_non_cache_rd equ 011110b +P5_ncache_refs equ 011110b +P5_locked_bus equ 011100b + +P5_mem2pipe equ 001001b +P5_bank_conf equ 001010b + + +P5_instrs_ex equ 010110b +P5_instrs_ex_V equ 010111b + + + + + + +P6_event_select0_msr equ 186h +P6_event_select1_msr equ 187h +P6_event_counter0_msr equ 0C1h +P6_event_counter1_msr equ 0C2h + + + + +;P6_rd_miss equ +P6_wr_miss equ 46h +P6_rw_miss equ 45h +P6_ex_miss equ 81h + +P6_d_wback equ 47h + +;P6_rw_tlb equ +P6_ex_tlb equ 85h + +P6_stalls equ 0A2h + +;P6_L2_rd_miss equ +P6_L2_wr_miss equ 25h +P6_L2_rw_miss equ 24h +P6_L2_ex_miss equ + +P6_L2_d_wback equ 27h + + + +P6_bus_util equ 62h + + +P6_instrs_ex equ 0C0h + + + +;---------------------------------------------------------------------------- +; +; KD thread nickname table +; +;---------------------------------------------------------------------------- + + +thread_nickname_entry struc + + number dd 0 + nickname db 0,0,0,0,0,0 + db 0 + db 0 + +thread_nickname_entry ends + + + +thread_nickname_table db (16*sizeof thread_nickname_entry) dup (0) + + + + + + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; DS phys mem idempotent +; +; kd_init data on stack +; +;---------------------------------------------------------------------------- + + + + IF kernel_type NE lime_pip + strtseg + jmp init_default_kdebug + strt ends + ENDIF + + + icode + + + assume ds:codseg + + +init_default_kdebug: + + pop ebx + + pop [kdebug_extension] + pop eax + call adjust_flat_address + mov [io_apic_base],eax + pop eax + call adjust_flat_address + mov [local_apic_base],eax + pop [phys_kernel_info_page_ptr] + pop eax + call adjust_flat_address + mov [kernel_proot_ptr_ptr],eax + pop [configuration] + pop [permissions] + pop [irq0_intr] + pop eax + IFNZ eax,0 + mov [grab_frame],eax + FI + + push ebx + + call determine_processor_family + + call determine_gidt + + mov al,'a' + call init_kdio + movzx eax,[configuration].start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + call init_kdebug_cacheability_control + call init_cache_snapshots + + + mov eax,offset default_kdebug_exception + + ret + + + + +adjust_flat_address: + + IFB_ eax,virtual_space_size + add eax,PM + FI + ret + + + + + +determine_processor_family: + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + sub edx,edx + and eax,1 SHL id_flag + IFNZ + mov eax,1 + cpuid + + FI + + and ah,0Fh + CORA ah,p6_family + IFB_ ah,p5_family + mov ah,other_family + FI + mov ds:[processor_family],ah + + mov ds:[processor_feature_flags],edx + + ret + + + + + + kdebug_grab_frame: ; kdebug-internal grab frame if NO grab_frame provided + ; MUST be called BEFORE kernel reads main.mem from kernel_info_page + ; -- phys mem assumed -- (does require PM but not PG) + ; + ; EAX : grabbed page frame address + + push edi + + mov edi,ds:[phys_kernel_info_page_ptr] + + mov eax,[edi+reserved_mem1].mem_begin + and eax,-pagesize + IFZ + mov eax,[edi+main_mem].mem_end + and eax,-pagesize + mov [edi+reserved_mem1].mem_begin,eax + mov [edi+reserved_mem1].mem_end,eax + FI + sub eax,pagesize + + IFAE eax,[edi+reserved_mem0].mem_end + CANDAE eax,[edi+dedicated_mem0].mem_end + CANDAE eax,[edi+dedicated_mem1].mem_end + CANDAE eax,[edi+dedicated_mem2].mem_end + CANDAE eax,[edi+dedicated_mem3].mem_end + CANDAE eax,[edi+dedicated_mem4].mem_end + + mov [edi+reserved_mem1].mem_begin,eax + + ELSE_ + ke '-kd mem underflow' + + FI + + pop edi + ret + + + + icod ends + + + + + + +determine_gidt: ;-- can also be invoked after initialization phase ! --------- + + push ds + + IFAE esp,virtual_space_size + push phys_mem + pop ds + FI + + sgdt ds:[gdt_descr] + sidt ds:[idt_descr] + + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp,virtual_space_size + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kd_io_call_tab_phys dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kd_io_call_tab_virt dd kd_outchar+KR ; 0 + dd outstring+KR ; 1 + dd outcstring+KR ; 2 + dd clear_page+KR ; 3 + dd cursor+KR ; 4 + + dd outhex32+KR ; 5 + dd outhex20+KR ; 6 + dd outhex16+KR ; 7 + dd outhex12+KR ; 8 + dd outhex8+KR ; 9 + dd outhex4+KR ; 10 + dd outdec+KR ; 11 + + dd kd_incharety+KR; 12 + dd kd_inchar+KR ; 13 + dd inhex32+KR ; 14 + dd inhex16+KR ; 15 + dd inhex8+KR ; 16 + dd inhex32+KR ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp,virtual_space_size + push phys_mem + pop ds + push phys_mem + pop es + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + mov eax,[ebp+ip_eax] + call [ebx*4+kd_io_call_tab_virt] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + jmp ret_from_kdebug + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + mov eax,[ebp+ip_eax] + call [ebx*4+kd_io_call_tab_phys] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp,virtual_space_size + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + IFDEF field + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + ENDIF + endm + + +;-------------------------------------------------------------------------- +; +; +; Kdebug cacheable/uncacheable +; +; +; PRECONDITION phys mem idempotent +; +;-------------------------------------------------------------------------- + + + icode + + +init_kdebug_cacheability_control: + + call [grab_frame] + mov edi,eax + + add eax,page_present+page_write_permit+global_page+page_cache_disable + mov ds:[kdebug_uncacheable_PDE],eax + + mov ebx,offset dcod_start + and ebx,-pagesize + mov ecx,offset scod_start + add ecx,pagesize-1 + and ecx,-pagesize + + sub eax,eax + DO + IFAE eax,ebx + CANDB eax,ecx + or eax,page_cache_disable + FI + or eax,page_present+page_write_permit+global_page + + mov [edi],eax + + and eax,-pagesize + add edi,4 + add eax,pagesize + cmp eax,MB4 + REPEATB + OD + + ret + + + icod ends + + + + + + +make_kdebug_uncacheable: + + mov bl,breakpoint + call get_exception_handler + IFNZ eax,offset direct_kdebug_exception_handler ; + mov ds:[int3_exception_handler],eax ; ensures that no kernel code is executed + mov eax,offset direct_kdebug_exception_handler; to prevent instr fetches from cacheable + call set_exception_handler ; pages + FI + + mov eax,ds:[kdebug_uncacheable_PDE] + mov edi,PM/MB4*4 + call set_pde_in_all_pdirs + + mov ecx,page_cache_disable + mov esi,PM+MB4 + mov edi,PM+physical_kernel_mem_size + call modify_cacheability_through_all_pdirs + + mov eax,0+page_present+superpage + mov edi,offset kdebug_cached_alias_mem/MB4*4 + call set_pde_in_all_pdirs + + call flush_tlb_including_global_pages + + push ds + push linear_kernel_space + pop ds + + mov esi,esp + call test_cache + mov esi,esp + call test_cache + + pop ds + + mov [typical_cached_data_cycles],eax + + ret + + + + +make_kdebug_and_kernel_cacheable: + + mov bl,breakpoint + call get_exception_handler + IFZ eax,offset direct_kdebug_exception_handler ; + mov eax,ds:[int3_exception_handler] ; resetting to normal INT 3 handling + call set_exception_handler ; reason: see above + FI + + mov eax,0+page_present+page_write_permit+superpage+global_page + mov edi,PM/MB4*4 + call set_pde_in_all_pdirs + + mov ecx,NOT page_cache_disable + mov esi,PM+MB4 + mov edi,-1 + call modify_cacheability_through_all_pdirs + + call flush_tlb_including_global_pages + ret + + + + +make_kernel_uncacheable: + + mov bl,breakpoint + call get_exception_handler + IFZ eax,offset direct_kdebug_exception_handler ; + mov eax,ds:[int3_exception_handler] ; resetting to normal INT 3 handling + call set_exception_handler ; reason: see above + FI + + mov eax,0+page_present+page_write_permit+superpage+global_page+page_cache_disable + mov edi,PM/MB4*4 + call set_pde_in_all_pdirs + + mov ecx,page_cache_disable + mov esi,PM+MB4 + mov edi,-1 + call modify_cacheability_through_all_pdirs + + mov eax,0+page_present+superpage + mov edi,offset kdebug_cached_alias_mem/MB4*4 + call set_pde_in_all_pdirs + + call flush_tlb_including_global_pages + + wbinvd + + ret + + + + +modify_cacheability_through_all_pdirs: ; ECX : mask + ; ESI : start addr (4MB aligned) + ; EDI : end addr (FFFFFFFF = 4G) (4K aligned) + IF kernel_family EQ lime_pip + + push ds + push linear_kernel_space + pop ds + + mov edx,offset task_proot + DO + mov ebx,[edx].proot_ptr + add edx,8 + and ebx,0FFFFFF00h + REPEATZ + + EXITS long + + push esi + + mov eax,esi + shr eax,22 + lea ebx,[ebx+eax*4+PM] + sub esi,MB4 + sub ebx,4 + + DO + add esi,MB4 + EXITC + add ebx,4 + cmp esi,edi + EXITAE + + mov eax,[ebx] + test eax,page_present + REPEATZ + + test ecx,ecx + IFS + and eax,ecx + ELSE_ + or eax,ecx + FI + mov [ebx],eax + + test eax,superpage + REPEATNZ + + IFDEF pdir_space + cmp esi,offset pdir_space + REPEATZ + ENDIF + IFDEF ptab_space + cmp esi,offset ptab_space + REPEATZ + ENDIF + + push ebx + push esi + mov ebx,eax + and ebx,-pagesize + add ebx,PM + DO + mov eax,[ebx] + test eax,page_present + IFNZ + IFDEF shadow_pdir + CANDNZ esi,offset shadow_pdir + ENDIF + test ecx,ecx + IFS + and eax,ecx + ELSE_ + or eax,ecx + FI + mov [ebx],eax + FI + add esi,pagesize + add ebx,4 + cmp esi,edi + EXITAE + test ebx,pagesize-1 + REPEATNZ + OD + pop esi + pop ebx + REPEAT + OD + + pop esi + REPEAT + OD + + pop ds + ret + + + ELSE + + ke '-task_proot' + ret + + ENDIF + + + + + + + + + +set_pde_in_all_pdirs: ; EAX : new PDE, EDI : PDE offset in pdirs + + + IF kernel_family EQ lime_pip + + push ds + push linear_kernel_space + pop ds + + push eax + push edx + push ebx + + mov edx,offset task_proot + DO + mov ebx,[edx].proot_ptr + add edx,8 + and ebx,0FFFFFF00h + REPEATZ + + EXITS + + mov dword ptr [ebx+edi+PM],eax + + REPEAT + OD + + pop ebx + pop edx + pop eax + pop ds + ret + + ELSE + + ke '-task_proot' + ret + + ENDIF + + + + +flush_tlb_including_global_pages: + + push eax + mov eax,cr3 + mov cr3,eax + mov eax,PM + DO + invlpg [eax] + add eax,pagesize + REPEATNC + OD + pop eax + ret + + + + + + + +kdebug_caching_control: + + kd____inchar + kd____outchar + IFZ al,'+' + call make_kdebug_and_kernel_cacheable + kd____disp <' L4 and L4KD are now cached (default).'> + ret + FI + IFZ al,'-' + call make_kernel_uncacheable + kd____disp <' Neither L4 nor L4KD (code+data) are now cached.'> + ret + FI + IFZ al,'*' + call make_kdebug_uncacheable + + ; mov ecx,286 + ; rdmsr + ; btr eax,8 + ; wbinvd + ; wrmsr + + kd____disp <' L4 is now cached, L4KD is not (good for perf tracing).'> + ret + FI + kd____disp <'??'> + ret + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +; direct kdebug exception +; +;---------------------------------------------------------------------------- +; kdebug exception PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- +; direct kdebug exception PRECONDITION: +; +; no stack prep happened +; +;---------------------------------------------------------------------------- + + + + +direct_kdebug_exception_handler: + + + ipre trap1,no_ds_load + + rdtsc + + IFZ ss:[kdebug_stack_bottom+PM],0 + + mov esi,eax + mov edi,edx + + mov ecx,P6_event_select0_msr + rdmsr + btr eax,22 ; disable counters + wrmsr + + mov ecx,cr0 + bts ecx,cr0_cd_bit + mov cr0,ecx + + mov ss:[kdebug_stack_bottom+PM],esp + add ss:[kdebug_rdtsc_corrector+PM],esi + adc ss:[kdebug_rdtsc_corrector+PM+4],edi + + inc ss:[kdebug_invocation_stamp+PM] + + FI + + push breakpoint + push 0 + + + + + +default_kdebug_exception: + + pop ebx ; drop ret address + pop eax ; get exception no + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp,virtual_space_size + push phys_mem + pop ds + + + IFNZ [performance_count_params],0 + + push eax + mov al,[processor_family] + + IFZ al,p5_family + mov ecx,P5_event_counter0_msr + rdmsr + mov [perf_counter0_value],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [perf_counter1_value],eax + + ELIFZ al,p6_family + mov ecx,P6_event_counter0_msr + rdmsr + mov [perf_counter0_value],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [perf_counter1_value],eax + FI + pop eax + FI + + push eax + movzx eax,[configuration].start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3,long + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp,virtual_space_size + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + ktest_page_present ebx + IFNZ + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + mov ebx,offset kdebug_buffer + + pop eax + pop es + pop ds + + ELSE_ + and ebx,NOT PM + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,[ebx+1] + IFNZ al,'*' + cmp al,'#' + IFNZ + cmp al,'/' + FI + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + if precise_cycles + IFAE esp,virtual_space_size + push ds + push linear_kernel_space + pop ds + push ebx + mov ebx,esp + and ebx,-sizeof tcb + cpu___cycles ebx + pop ebx + pop ds + FI + endif + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + call determine_gidt + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + if precise_cycles + IFAE esp,virtual_space_size + push ds + push linear_kernel_space + pop ds + push ebx + mov ebx,esp + and ebx,-sizeof tcb + cpu___cycles ebx + pop ebx + pop ds + FI + endif + + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + IFAE esp,virtual_space_size + CANDZ esp,ss:[kdebug_stack_bottom+PM] + + mov ss:[kdebug_stack_bottom+PM],0 + + mov ecx,cr0 + btr ecx,cr0_cd_bit + mov cr0,ecx + + mov ebx,ss:[performance_count_params+PM] + test ebx,ebx + IFNZ + mov al,ss:[trace_perf_monitoring_mode+PM] + call set_performance_counters + FI + + rdtsc + sub ss:[kdebug_rdtsc_corrector+PM],eax + sbb ss:[kdebug_rdtsc_corrector+PM+4],edx + FI + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[permissions].flags + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call dump_cmd + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'S',long + call thread_switch_prot + ELIFZ al,'i',long + call port_io + ELIFZ al,'o',long + call port_io + ELIFZ al,'C',long + call configure_kdebug + ELIFZ al,'D' + call analyze_data_cache + IF kernel_family NE hazelnut + ELIFZ al,'H' + call halt_current_thread + ENDIF + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + IF random_profiling + ELIFZ al,'F' + call profile_cmd + cmp al,0 + REPEATNZ + ENDIF + ELIFZ al,'^' + call reset_system + ELIFZ al,'y' + CANDNZ [kdebug_extension],0 + call [kdebug_extension] + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + + +configure_kdebug: + + call out_config_help + + DO + kd____disp <13,10,'L4KD config:'> + kd____inchar + kd____outchar + + IFZ al,'R' + call remote_kd_intr + REPEAT + FI + IFZ al,'N' + call enter_thread_nickname + REPEAT + FI + IFZ al,'C' + call kdebug_caching_control + REPEAT + FI + IFZ al,'V' + call set_video_mode + REPEAT + FI + cmp al,'q' + EXITZ + cmp al,'g' + EXITZ + cmp al,27 + EXITZ + + call out_config_help + REPEAT + OD + ret + + + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'L4KD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'L4KD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'k' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'S' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'C' + CANDNZ al,'F' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'g' + CANDNZ al,'<' + CANDNZ al,'>' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz kdebug_reset_pc + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, all / xxxx : find module and rel addr'> + kd____disp <13,10,'b : bkpnt, i/w/a/p/b/r/-: set instr/wr/rdwr/ioport bkpnt/base/restrict/off'> + kd____disp <13,10,'t : tcb, current / ttttt / TTT.ll'> + kd____disp <13,10,'d : b/w/t/p/m/c/T/G/I/S/R : dump byte/word/text/ptab/mapping/cache/Task/Gdt/Idt/Sig0/Redir'> + kd____disp <13,10,'k : kernel data'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx: on/off/trace'> + kd____disp <13,10,'S : monit tswtch */- : trace/off'> + FI + IFNZ [configuration].trace_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx: byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + IF kernel_family NE hazelnut + kd____disp <13,10,'H : halt current thread'> + ENDIF + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'D : data cache analysis'> + IF random_profiling + kd____disp <13,10,'F : profile analysis'> + ENDIF + kd____disp <13,10,'C : configure kdebug'> + kd____disp <13,10,' : id text'> + + ret + + +out_config_help: + + kd____disp <13,10,10,' Configure Kdebug',13,10,10> + kd____disp <13,10,'N : enter thread nickname'> + kd____disp <13,10,'R : remote kdint +/- : on/off'> + kd____disp <13,10,'V : video mode a/c/m/h/1/2/- : auto/cga/mono/hercules/com1/com2/no-com'> + IFAE [processor_family],p6_family,long + kd____disp <13,10,'C : L4/L4KD caching +/-/* : on (default) / off / L4 on, L4KD off (for perf tracing)'> + FI + kd____disp <13,10,'q : quit config mode',13,10> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [configuration].start_port + and eax,0Fh + or eax,ebx + mov [configuration].start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [configuration].start_port + and bl,0Fh + or al,bl + mov [configuration].start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [configuration].start_port,0F0h + or byte ptr [configuration].start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,virtual_space_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + + IF kernel_family NE hazelnut + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + ENDIF + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ ss:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ ss:[breakpoint_thread+PM],0 + cmp ss:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,virtual_space_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp ss:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFAE esp,virtual_space_size,long + CANDNZ ss:[bx_size+PM],0,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + IFB_ esp,virtual_space_size + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + ktest_page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + + call outthread + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + IF kernel_family NE hazelnut + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + ELSE + mov eax,[esi+ressources] + kd____outhex32 + ENDIF + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,byte ptr [esi+fine_state] + IFDEF nwait + test bl,nwait + IFZ + kd____disp <'wait '> + FI + ENDIF + IFDEF nclos + test bl,nclos + IFZ + kd____disp <'clos '> + FI + ENDIF + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + IFDEF nwake + test bl,nwake + ELSE + mov eax,[esi+list_state] + not eax + test eax,is_wakeup + ENDIF + IFZ + show <', wakeup: '>,wakeup + show <'+'>,wakeup+4 + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFDEF max_controlled_prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + ENDIF + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + IFDEF wait_for + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + ENDIF + + kd____disp <6,4,0, 'sndq : '> + IFDEF sndq_root + lea ecx,[esi+sndq_root] + call show_llinks + ELSE + lea ebx,[esi+send_queue_head] + call show_thread_id + ENDIF + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + if precise_cycles + kd____disp <6,5,0, 'cpu cycles: '> + mov eax,[esi+cpu_cycles+4] + kd____outhex32 + mov eax,[esi+cpu_cycles] + kd____outhex32 + else + IFDEF cpu_clock + kd____disp <6,5,0, 'cpu time: '> + mov eax,[esi+cpu_clock+4] + kd____outhex8 + mov eax,[esi+cpu_clock] + kd____outhex32 + ENDIF + endif + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + IF sizeof timeslice eq 1 + mov al,[esi+timeslice] + kd____outhex8 + ELSE + mov eax,[esi+timeslice] + kd____outhex32 + ENDIF + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + IFDEF int_preepmter + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + ENDIF + + IFDEF ext_preempter + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + ENDIF + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + IFDEF soon_wakeup_link + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + ENDIF + IFDEF late_wakeup_link + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + ENDIF + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + IFDEF thread_dr0 + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + ENDIF + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + +outthread: + + push ds + push phys_mem + pop ds + + push eax + push ecx + + mov ecx,offset thread_nickname_table + DO + IFZ eax,ds:[ecx].number + + lea eax,[ecx].nickname + kd____outcstring + + pop ecx + pop eax + pop ds + ret + FI + add ecx,sizeof thread_nickname_entry + cmp ecx,offset thread_nickname_table+sizeof thread_nickname_table + REPEATB + OD + + pop ecx + pop eax + pop ds + + push eax + + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + + and al,lthreads-1 + kd____outhex8 + + pop eax + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFDEF intrq_llink + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + ENDIF + IFAE eax,virtual_space_size + lno___thread eax,eax + kd____outhex16 + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + sub eax,eax + IFAE esp,virtual_space_size + mov eax,PM + FI + + test ss:[eax+permissions].flags,kdebug_dump_regs_enabled + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + mov eax,ss:[eax+kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + sub eax,eax + IFAE esp,virtual_space_size + mov eax,PM + FI + IFZ ebp,[eax+kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; dump cmd +; +;---------------------------------------------------------------------------- + + +dump_cmd: + + kd____inchar + kd____outchar + + mov ah,[permissions].flags + + IFZ al,'d' + mov al,'w' + FI + CORZ al,'b' + CORZ al,'w' + IFZ al,'t' + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + mov dl,al + sub ebx,ebx + mov ecx,linear_kernel_space + lsl ecx,ecx + and ecx,-4 + kd____inhex32 + call display_mem + ret + FI + + mov ecx,ss + IFZ ecx,linear_kernel_space,long + + mov dl,'w' + + IFZ al,'G' + mov eax,ss:[gdt_descr+PM].base + mov ebx,eax + movzx ecx,ss:[gdt_descr+PM].limit + add ecx,32 + call display_mem + ret + FI + + IFZ al,'I' + mov eax,ss:[idt_descr+PM].base + mov ebx,eax + movzx ecx,ss:[idt_descr+PM].limit + add ecx,32 + call display_mem + ret + FI + + IFDEF task_proot + IFZ al,'T' + mov eax,offset task_proot + mov ebx,eax + mov ecx,sizeof task_proot + call display_mem + ret + FI + ENDIF + + IFZ al,'S' + mov edi,[phys_kernel_info_page_ptr] + CANDNZ edi,0 + mov dl,'b' + mov eax,ss:[edi+reserved_mem1+PM].mem_begin + mov ebx,ss:[edi+main_mem+PM].mem_end + shr ebx,log2_pagesize + mov ecx,ebx + sub eax,ebx + and eax,-pagesize + add eax,PM + mov ebx,eax + call display_mem + ret + FI + + IFDEF redirection_table + IFZ al,'R' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + mov ebx,eax + mov ecx,sizeof redirection_table + call display_mem + ret + FI + ENDIF + + FI + + IFZ al,'p' + call display_ptabs + ret + FI + + IFZ al,'m' + call display_mappings + ret + FI + + IFZ al,'c' + call dump_cache + ret + FI + + + ret + + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + + mov [dump_area_base],ebx + mov [dump_area_size],ecx + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + IFAE esp,virtual_space_size + add ebp,KR + FI + DO + mov al,dl + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + IFAE esp,virtual_space_size + add ebp,KR + FI + + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + IFAE esp,virtual_space_size + add ebp,KR + FI + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [permissions].flags,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + IFAE esp,virtual_space_size + add ebp,KR + FI + xchg [dump_area_base],edx + push edx + DO + mov al,'w' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'w' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + IFZ [dump_type],'P' + sub eax,[dump_area_base] + shl eax,5-2 + ELIFZ [dump_type],'C' + sub eax,[dump_area_base] + FI + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'t' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'L4KD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'w' + mov al,'b' + ELIFZ al,'b' + mov al,'t' + ELIFZ al,'t' + mov al,'p' + ELIFZ al,'p' + mov al,'w' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + ;;; lno___task ebx,esp + sub ebx,ebx ; self + call page_phys_address + + IFZ + IFZ [dump_type],'t' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'t' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF pnode_base + + + +display_mappings: + + IFB_ esp,virtual_space_size + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'L4KD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + + ELSE + + +display_mappings: +display_mappings_of: + + ke 'no_pnodes' + + ret + + + ENDIF + + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + + IFB_ esp,virtual_space_size + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + kd____disp <6,2,1,'sys clock : '> + + IFDEF V4_clock_features + IF V4_clock_features + extrn get_clock_usc:near + call get_clock_usc + ELSE + IFDEF system_clock + mov eax,ds:[system_clock] + mov edx,ds:[system_clock+4] + ELSE + sub eax,eax + mov edx,ds:[phys_kernel_info_page_ptr+PM] + IFNZ edx,0 + mov eax,ds:[edx+PM].user_clock + mov edx,ds:[edx+PM].user_clock+4 + FI + ENDIF + ENDIF + ELSE + IFDEF system_clock + mov eax,ds:[system_clock] + mov edx,ds:[system_clock+4] + ELSE + sub eax,eax + mov edx,ds:[phys_kernel_info_page_ptr+PM] + IFNZ edx,0 + mov eax,ds:[edx+PM].user_clock + mov edx,ds:[edx+PM].user_clock+4 + FI + ENDIF + ENDIF + push eax + mov eax,edx + kd____outhex32 + pop eax + kd____outhex32 + + IFDEF present_root + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + ENDIF + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + IFDEF ready_actual + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + ENDIF + IFDEF dispatcher_tcb + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + ENDIF + + IFDEF dispatcher_tcb + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + ENDIF + + IFDEF intrq_llink + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + ENDIF + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + + str bx + and ebx,0000FFF8h + add ebx,ds:[gdt_descr+PM].base + mov ah,byte ptr ds:[ebx+7] + mov al,byte ptr ds:[ebx+4] + shl eax,16 + mov ax,word ptr ds:[ebx+2] ; base of TSS + + mov eax,ds:[eax+4] ; ESP0 + kd____outhex32 + + pop es + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; enter thread nickname +; +;---------------------------------------------------------------------------- + + +enter_thread_nickname: + + push ds + push phys_mem + pop ds + + mov ebp,esp + and ebp,-sizeof tcb + + kd____disp <' t:'> + kd____inhext + test eax,eax + IFZ + lno___thread eax,ebp + call outthread + FI + + mov ecx,offset thread_nickname_table + DO + IFZ [ecx].number,eax + mov [ecx].number,0 + EXIT + FI + add ecx,sizeof thread_nickname_entry + cmp ecx,offset thread_nickname_table+sizeof thread_nickname_table + REPEATB + OD + + mov ecx,offset thread_nickname_table + DO + cmp [ecx].number,0 + EXITZ + add ecx,sizeof thread_nickname_entry + cmp ecx,offset thread_nickname_table+sizeof thread_nickname_table + REPEATB + + kd____disp <' nickname table full ',13,10> + + pop ds + ret + OD + + kd____disp <' = '> + + mov [ecx].number,eax + sub edx,edx + DO + kd____inchar + cmp al,32 + EXITBE + mov [ecx+edx].nickname,al + kd____outchar + inc edx + cmp edx,sizeof nickname + REPEATB + OD + mov [ecx+edx].nickname,0 + IFZ edx,0 + mov [ecx].number,0 + FI + + pop ds + ret + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CORB eax,com0_base ; do not protocol pseudo PFs in comspace + IFA eax,com1_base-1+com_space_size ; otherwise a periodic interrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + FI + + pop es + pop ds + + popad + jmp ss:[page_fault_handler+PM] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread0],eax + mov [ipc_prot_thread1],eax + mov [ipc_prot_thread2],eax + mov [ipc_prot_thread3],eax + mov [ipc_prot_thread4],eax + mov [ipc_prot_thread5],eax + mov [ipc_prot_thread6],eax + mov [ipc_prot_thread7],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + test eax,eax + IFNZ + xchg [ipc_prot_thread0],eax + xchg [ipc_prot_thread1],eax + xchg [ipc_prot_thread2],eax + xchg [ipc_prot_thread3],eax + xchg [ipc_prot_thread4],eax + xchg [ipc_prot_thread5],eax + xchg [ipc_prot_thread6],eax + mov [ipc_prot_thread7],eax + ELSE_ + xchg [ipc_prot_thread7],eax + xchg [ipc_prot_thread6],eax + xchg [ipc_prot_thread5],eax + xchg [ipc_prot_thread4],eax + xchg [ipc_prot_thread3],eax + xchg [ipc_prot_thread2],eax + xchg [ipc_prot_thread1],eax + mov [ipc_prot_thread0],eax + FI + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + sub ecx,ecx + IFB_ ebp,virtual_space_size + mov ecx,ebp + and cl,011b + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + ELSE_ + mov al,0 + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + DO + cmp [ipc_prot_thread0+PM],0 + EXITZ + cmp [ipc_prot_thread0+PM],eax + EXITZ + cmp [ipc_prot_thread1+PM],eax + EXITZ + cmp [ipc_prot_thread2+PM],eax + EXITZ + cmp [ipc_prot_thread3+PM],eax + EXITZ + cmp [ipc_prot_thread4+PM],eax + EXITZ + cmp [ipc_prot_thread5+PM],eax + EXITZ + cmp [ipc_prot_thread6+PM],eax + EXITZ + cmp [ipc_prot_thread7+PM],eax + OD + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + + popad + add esp,4 + jmp ss:[ipc_handler+PM] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + call outthread + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + ELSE_ kd____disp <' -'> + kd____outhex8 + kd____disp <'- '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + call outthread + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + + CORZ al,debug_exception + CORZ al,breakpoint + movzx ecx,[idt_descr].limit + shr ecx,3 + IFA al,cl + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + sub edx,edx + IFAE esp,virtual_space_size + mov edx,PM + FI + + + mov al,ss:[edx+monitored_exception] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,ss:[edx+monitored_ec_min] + movzx ecx,ss:[edx+monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop es + pop ds + + popad + + IFAE esp,virtual_space_size + + CORB ss:[monitored_exception+PM],8 + IFA ss:[monitored_exception+PM],14 + IFNZ ss:[monitored_exception+PM],17 + add esp,4 + FI + FI + jmp ss:[monitored_exception_handler+PM] + FI + + CORB [monitored_exception],8 + IFA [monitored_exception],14 + IFNZ [monitored_exception],17 + add esp,4 + FI + FI + jmp [monitored_exception_handler] + + + + + + +;---------------------------------------------------------------------------- +; +; monitor thread switch +; +;---------------------------------------------------------------------------- + + +thread_switch_prot: + + IFDEF ts_prot + + IFB_ esp,virtual_space_size + ret + FI + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inchar + + IFZ al,'*' + kd____outchar + or ss:[ebp+ressources],mask ts_prot + ret + FI + + IFZ al,'-' + kd____outchar + mov eax,ebp + DO + and ss:[eax+ressources],NOT mask ts_prot + mov eax,ss:[eax+present_llink].succ + cmp eax,ebp + REPEATNZ + DO + ret + FI + + ENDIF + + mov al,'?' + kd____outchar + ret + + + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp,virtual_space_size + + kd____outchar + IFZ [timer_intr_handler],0 + mov ebx,[irq0_intr] + add ebx,8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov ebx,[irq0_intr] + add ebx,8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop es + pop ds + + popad + add esp,4 + FI + + jmp ss:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + add edx,ds:[local_apic_base+PM] + IFZ bh,'o' + mov ds:[edx],eax + ELSE_ + mov eax,ds:[edx] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov ebx,ds:[io_apic_base+PM] + mov byte ptr ds:[ebx+0],dl + IFZ bh,'o' + mov ds:[ebx+10h],eax + ELSE_ + mov eax,ds:[ebx+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + test ebx,ebx + IFZ + mov edx,cr3 + and edx,-pagesize + ELSE_ + load__proot edx,ebx + FI + + IFAE eax,shared_table_base + CANDBE eax,shared_table_base-1+shared_table_size + mov edx,ds:[kernel_proot_ptr_ptr+PM] + mov edx,ds:[edx] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + IFAE esp,virtual_space_size + and eax,NOT PM + add eax,KR + FI + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + IFAE esp,virtual_space_size + add ebx,ss:[idt_descr+PM].base + ELSE_ + add ebx,ss:[idt_descr].base + FI + ret + + + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +;-------------------------------------------------------------------------- +; +; random-profiling analysis +; +;-------------------------------------------------------------------------- +;-------------------------------------------------------------------------- + + if random_profiling + + extrn profiling_space_begin:dword + extrn profiling_space_size:abs + + + + +profile_cmd: + + IFB_ esp,virtual_space_size + kd____disp <'-'> + ret + FI + + kd____disp <6,lines-1,columns-58,' d/a/0 : profiling dump / analysis / set to 0',6,lines-1,8> + + kd____inchar + kd____outchar + + + mov edi,ds:[profiling_space_begin] + add edi,PM + mov ecx,profiling_space_size + + + IFZ al,'d' + mov eax,edi + mov ebx,edi + mov dl,'P' + call display_mem + ret + FI + + + IFZ al,'0' + push es + push linear_kernel_space + pop es + + shr ecx,2 + cld + sub eax,eax + rep stosd + + pop es + ret + FI + + + IFZ al,'a',long + + push ds + push es + + push linear_kernel_space + pop ds + push ds + pop es + + mov esi,edi + mov edi,ds:[current_cache_snapshot+PM] + + push ecx + push edi + + mov ecx,sizeof cache_snapshot/4 + sub eax,eax + cld + rep stosd + + pop edi + pop ecx + + kd____disp <' skip profile lines accessed lessequal than: '> + kd____inhex32 + mov edx,eax + + mov ebx,esi + DO + mov eax,ds:[esi] + and eax,pagesize-1 + IFG eax,edx + + push ecx + push esi + + mov eax,esi + sub eax,ebx + shr eax,2 + and eax,icache_sets-1 + shl eax,log2_snapshot_dwords_per_icache_set + lea eax,[eax*4+edi] + + mov ecx,ds:[esi] + and ecx,-pagesize + sub esi,ebx + shl esi,log2_icache_line_size-2 + and esi,pagesize-1 + or esi,ecx + + mov ecx,snapshot_dwords_per_icache_set + DO + IFZ dword ptr ds:[eax],0 + mov dword ptr ds:[eax],esi + EXIT + FI + add eax,4 + dec ecx + REPEATNZ + OD + + pop esi + pop ecx + FI + add esi,4 + sub ecx,4 + REPEATNZ + OD + + pop es + pop ds + + mov eax,edi + mov ebx,eax + mov ecx,sizeof cache_snapshot + mov dl,'C' + call display_mem + + ret + + FI + + + kd____disp <'??'> + + ret + + + + + + + endif + + + +;-------------------------------------------------------------------------- +;-------------------------------------------------------------------------- +; +; data cache analysis +; +;-------------------------------------------------------------------------- +; +; PRECONDITION: phys mem idempotent +; +;-------------------------------------------------------------------------- + + + icode + + +init_cache_snapshots: + + pushad + + DO + cmp [configuration].trace_pages,0 + EXITZ long + + call [grab_frame] + mov ebx,eax + mov edi,eax + mov ecx,pagesize + + cmp [configuration].trace_pages,1 + EXITZ + + call [grab_frame] + IFB_ eax,edi + + DO + sub ebx,eax + EXITC + cmp ebx,pagesize + EXITNZ + + add ecx,ebx + mov ebx,eax + mov edi,eax + + movzx eax,[configuration].trace_pages + shl eax,log2_pagesize + cmp ecx,eax + EXITAE + + call [grab_frame] + REPEAT + OD + + ELSE_ + DO + sub eax,ebx + cmp eax,pagesize + EXITNZ + + add ecx,eax + add ebx,eax + + movzx eax,[configuration].trace_pages + shl eax,log2_pagesize + cmp ecx,eax + EXITAE + + call [grab_frame] + REPEAT + OD + FI + + + + mov eax,edi + add eax,PM + mov [cache_snapshots_begin],eax + mov [current_cache_snapshot],eax + add eax,ecx + mov [cache_snapshots_end],eax + + shr ecx,2 + mov eax,-1 + cld + rep stosd + + OD + + popad + ret + + + icod ends + + + + + +dump_cache: + + CORB esp,virtual_space_size + IFZ [cache_snapshots_end],0 + kd____disp <'-'> + ret + FI + + mov eax,[kdebug_invocation_stamp] + IFNZ eax,[current_cache_snapshot_stamp] + + mov [current_cache_snapshot_stamp],eax + + mov edi,[current_cache_snapshot] + add edi,sizeof cache_snapshot + IFAE edi,[cache_snapshots_end] + mov edi,[cache_snapshots_begin] + FI + mov [current_cache_snapshot],edi + + call dump_data_cache_snapshot + + FI + + mov cl,0 + DO + mov eax,[current_cache_snapshot] + mov edi,eax + mov ch,cl + mov cl,0 + DO + cmp cl,ch + EXITAE + IFBE edi,[cache_snapshots_begin] + mov edi,[cache_snapshots_end] + FI + sub edi,sizeof cache_snapshot + cmp edi,[current_cache_snapshot] + EXITZ + + inc cl + mov eax,edi + REPEAT + OD + + push ecx + mov ebx,eax + mov ecx,sizeof cache_snapshot + mov dl,'w' + + call display_mem + + pop ecx + + cmp al,'<' + IFZ + inc cl + REPEAT + FI + cmp al,'>' + IFZ + cmp cl,0 + REPEATZ + dec cl + REPEAT + FI + OD + + ret + + + +dump_data_cache_snapshot: + + push ds + push es + + mov edi,[current_cache_snapshot] + + mov edx,[typical_cached_data_cycles] + mov eax,edx + shr eax,1 + add edx,eax + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ecx,sizeof cache_snapshot/4 + mov eax,-1 + cld + push edi + rep stosd + pop edi + + mov ecx,ds:[phys_kernel_info_page_ptr] + mov ecx,[ecx+main_mem].mem_end + + pushad + call make_kernel_uncacheable + popad + + mov eax,cr0 + btr eax,cr0_cd_bit + mov cr0,eax + + mov esi,esp + call test_cache + + + mov esi,PM + add ecx,PM + DO + call test_cache + + IFB_ eax,200h + + mov eax,esi + shr eax,log2_dcache_line_size + and eax,dcache_sets-1 + shl eax,log2_snapshot_bytes_per_dcache_set + add eax,edi + + sub ebx,ebx + DO + IFZ dword ptr ds:[ebx*4+eax],-1 + sub esi,PM + mov dword ptr ds:[ebx*4+eax],esi + add esi,PM + EXIT + FI + inc ebx + cmp ebx,dcache_associativity + REPEATB + ke 'dcache_set_overflow??' + OD + + ELIFB eax,400h + ke 'hit L2?' + + FI + + add esi,dcache_line_size + cmp esi,ecx + REPEATB + OD + + pushad + call make_kdebug_uncacheable + popad + mov eax,cr0 + bts eax,cr0_cd_bit + mov cr0,eax + wbinvd + + pop es + pop ds + + ret + + + +analyze_data_cache: + + IFB_ esp,virtual_space_size + kd____disp <'-'> + ret + FI + + kd____disp <'disabled'> + ret + + push ds + push linear_kernel_space + pop ds + + ; call make_kernel_uncacheable + + mov eax,cr0 + btr eax,cr0_cd_bit + mov cr0,eax + + mov esi,esp + call test_cache + + mov eax,cr0 + bts eax,cr0_cd_bit + mov cr0,eax + + mov esi,esp + call test_cache + + push eax + + mov esi,PM+32 + call test_cache + + pop ebx + + ke 'cread' + +; call make_kdebug_uncacheable + + pop ds + ret + + + + +test_cache: ; ESI : cache addr + + push ebx + push ecx + push edx + push esi + push edi + + or esi,PM + and esi,-32 + cld + + mov eax,offset test_cache_in_cached_alias + add eax,offset kdebug_cached_alias_mem-PM + call eax + + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + +test_cache_in_cached_alias: + + cpuid + rdtsc + mov edi,eax + sub eax,eax + cpuid + + mov ecx,32 + rep lodsb + + sub eax,eax + cpuid + rdtsc + sub eax,edi + + ret + + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + IFZ cl,'/' + mov al,82h + FI + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + IFZ al,80h + push eax + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + kd____disp <', thread='> + pop eax + shr eax,8 + call outthread + ret + FI + + IFZ al,81h + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + kd____disp <', thread='> + pop eax + shr eax,8 + call outthread + ret + FI + + IFZ al,82h + kd____disp <' '> + shr eax,8 + call outthread + kd____disp <' '> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' '> + mov eax,ebx + call outthread + ret + FI + + kd____disp <'???'> + ret + + + + +display_thread_event: + + shr eax,8 + call outthread + + kd____disp <' '> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' '> + mov eax,ebx + call outthread + + ret + + + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [configuration].trace_pages,0,long + + call [grab_frame] + mov ebx,eax + mov ecx,KB4 + DO + call [grab_frame] + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[configuration].trace_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + mov dword ptr [edi+trace_entry_type],80h + mov dword ptr [edi+trace_entry_string],'-4L ' + mov byte ptr [edi+trace_entry_string],8 + mov dword ptr [edi+trace_entry_string+4],'RATS' + mov dword ptr [edi+trace_entry_string+8],'T' + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + add edi,sizeof trace_buffer_entry + mov [trace_buffer_in_pointer],edi + sub ecx,sizeof trace_buffer_entry + + shr ecx,2 + sub eax,eax + cld + rep stosd + + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ ,,long + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + + mov al,[processor_family+PM] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P5_event_select_msr + mov eax,ebx + wrmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + mov ebx,eax + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P6_event_select0_msr + mov eax,ebx + wrmsr + FI + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov eax,[trace_buffer_in_pointer] + mov ebx,[eax+trace_entry_timestamp] + or ebx,[eax+trace_entry_timestamp+4] + IFZ + sub eax,[trace_buffer_begin] + CANDZ eax,sizeof trace_buffer_entry + ret + FI + + + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + call display_page_fault + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + kd____disp <' no trace buffer',13,10> + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + call display_page_fault + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer+KR + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer+KR + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt [processor_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + EXITZ + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + + push ecx + push edi + mov edi,ds:[phys_kernel_info_page_ptr] + IFNZ edi,0 + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div ds:[edi].cpu_clock_freq + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + FI + pop edi + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + + + + + + + +set_performance_tracing: + + mov al,[processor_family] + IFNZ al,p5_family + CANDNZ al,p6_family + kd____disp <' not supported by this processor',13,10> + sub eax,eax ; Z! + ret + FI + + + kd____clear_page + call show_trace_perf_monitoring_mode + + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user, / : kernel/user',13,10,10> + + mov al,[processor_family] + IFZ al,p5_family,long + + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + ELIFZ al,p6_family,long + + kd____disp <'1 : L1 Dcache Misses (rd/wback)',13,10> + kd____disp <'2 : L2 Cache Misses (rd/wback)',13,10> + kd____disp <'i : Icache/ITLB Misses',13,10> + kd____disp <'I : Instructions/stalls',13,10> + kd____disp <'b : Bus Utilization/Instructions',13,10> + kd____disp <'# : enter performance-counter selectors',13,10> + FI + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov ah,[processor_family] + IFZ ah,p5_family + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + ELIFZ ah,p6_family + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + wrmsr + mov ecx,P6_event_counter1_msr + wrmsr + FI + ret + FI + + CORZ al,'&' + CORZ al,'/' + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + ELIFZ al,'/' + mov al,kernel_versus_user_perf_mon + ELIFZ al,'&' + mov al,kernel_versus_user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + mov ah,[processor_family] + IFZ ah,p5_family,long + + sub ebx,ebx + IFZ al,'i' + mov ebx,P5_instrs_ex + (P5_instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,P5_rw_miss + (P5_ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,P5_rw_tlb + (P5_ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,P5_r_stall + (P5_w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,P5_agi_stall + (P5_bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,P5_bus_util + (P5_instrs_ex SHL 16) + FI + + mov [performance_count_params],ebx + + + ELIFZ ah,p6_family,long + + sub ebx,ebx + + IFZ al,'1' + mov ebx,P6_rw_miss + (P6_d_wback SHL 16) + FI + IFZ al,'2' + mov ebx,P6_L2_rw_miss + (P6_L2_d_wback SHL 16) + FI + IFZ al,'i' + mov ebx,P6_ex_miss + (P6_ex_tlb SHL 16) + FI + IFZ al,'I' + mov ebx,P6_instrs_ex + (P6_stalls SHL 16) + FI + IFZ al,'b' + mov ebx,P6_bus_util + (P6_instrs_ex SHL 16) + FI + IFZ al,'#' + kd____disp <' PerfC0:'> + kd____inhex16 + mov ebx,eax + IFNZ [trace_perf_monitoring_mode],kernel_versus_user_perf_mon + kd____disp <' PerfC1:'> + kd____inhex16 + shl eax,16 + add ebx,eax + FI + FI + + mov [performance_count_params],ebx + + + FI + + sub eax,eax + mov [perf_counter0_value],eax + mov [perf_counter1_value],eax + + + test esp,esp ; NZ ! + ret + + + + + + + + +set_performance_counters: + + push eax + push ecx + push ebx + + + IFZ [processor_family],p5_family + push eax + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + mov ecx,P5_event_counter0_msr + mov eax,[perf_counter0_value] + wrmsr + mov ecx,P5_event_counter1_msr + mov eax,[perf_counter1_value] + wrmsr + pop eax + + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,P5_event_select_msr + wrmsr + + ELIFAE [processor_family],p6_family,long + + push eax + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + mov eax,[perf_counter0_value] + wrmsr + mov ecx,P6_event_counter1_msr + mov eax,[perf_counter1_value] + wrmsr + pop eax + + IFZ al,kernel_versus_user_perf_mon + + and ebx,0000FFFFh + mov ecx,ebx + or ebx,10b SHL 16 + or ecx,01b SHL 16 + bts ebx,22 ; enable counters + + ELSE_ + + mov ecx,ebx + shr ecx,16 + and ebx,0000FFFFh + + bts ebx,22 ; enable counters + + IFZ al,kernel_perf_mon + mov al,10b + ELIFZ al,user_perf_mon + mov al,01b + ELSE_ + mov al,11b + FI + shl eax,16 + or ebx,eax + or ecx,eax + FI + + mov eax,ecx + mov ecx,P6_event_select1_msr + wrmsr + mov eax,ebx + mov ecx,P6_event_select0_msr + wrmsr + FI + + pop ebx + pop ecx + pop eax + ret + + + + +read_performance_counters: + + push ecx + + mov al,[processor_family] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov ebx,eax + mov ecx,P5_event_counter1_msr + rdmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov ebx,eax + mov ecx,P6_event_counter1_msr + rdmsr + FI + xchg eax,ebx + + pop ecx + ret + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELIFZ al,kernel_versus_user_perf_mon + kd____disp <'Kernel/User'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + +;--------------------------------------------------------------------------- +;--------------------------------------------------------------------------- +;--------------------------------------------------------------------------- + + + +;--------------------------------------------------------------------------- +; +; RESET +; +;--------------------------------------------------------------------------- + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h + + + +inrtc macro rtcport + + mov al,rtcport + out rtc_address,al + jmp $+2 + in al,rtc_data + endm + + +outrt macro rtcport + + push eax + mov al,rtcport + out rtc_address,al + jmp $+2 + pop eax + out rtc_data,al + endm + + + +kdebug_reset_pc: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/kdiopc.asm b/l4-x86/l4-x/kernel/kdiopc.asm new file mode 100644 index 0000000..6b5e3b2 --- /dev/null +++ b/l4-x86/l4-x/kernel/kdiopc.asm @@ -0,0 +1,1371 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 15,12,00, 27 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 15.12.00 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn kdebug_reset_pc:near + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include segs.inc +.list + + +ok_for x86 + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp kdebug_reset_pc + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-x/kernel/kernel.asm b/l4-x86/l4-x/kernel/kernel.asm new file mode 100644 index 0000000..8cc299f --- /dev/null +++ b/l4-x86/l4-x/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '24.08.99' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-X Kernel (x86), Copyright (C) IBM 1997 & University of Karlsruhe 1999',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/ktest.asm b/l4-x86/l4-x/kernel/ktest.asm new file mode 100644 index 0000000..359565b --- /dev/null +++ b/l4-x86/l4-x/kernel/ktest.asm @@ -0,0 +1,1144 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 24,03,00, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.03.00 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include msg.inc +include segs.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86 + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' +; +; +; +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; +; mov esi,MB1 +; mov ecx,1024 +; DO +; mov eax,[esi] +; mov eax,[esi+28] +; add esi,32 +; dec ecx +; REPEATNZ +; OD +; +; rdtsc +; sub eax,ebx +; sub eax,12 +; add eax,511 +; shr eax,10 +; push eax +; +; +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; kd____disp <13,10,'RAM cache-line read: '> +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + ke '*1' + call pf_1024 + ke '*2' + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,1000h + ; cmp byte ptr ds:[ebx],0 + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 1' + ; + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,MB16 + ; and ebx,-pagesize + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 2' + ; + + + if random_sampling + bts dword ptr gs:[7*4],0 + bts dword ptr gs:[7*4],2 + IFNC + mov dword ptr gs:[0],0 + FI + endif + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + if random_sampling + btr dword ptr gs:[7*4],0 + endif + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc__4K : '> +; +; mov [ping_snd_msg+msg_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [ping_snd_msg+msg_size_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [ping_snd_msg+msg_w3].str_len,KB4 +; mov [ping_snd_msg+msg_w3].str_addr,MB1 +; mov [ping_rcv_msg+msg_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [ping_rcv_msg+msg_size_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [ping_rcv_msg+msg_w3].buf_size,KB4 +; mov [ping_rcv_msg+msg_w3].buf_addr,MB1 +; +; mov [pong_snd_msg+msg_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [pong_snd_msg+msg_size_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [pong_snd_msg+msg_w3].str_len,KB4 +; mov [pong_snd_msg+msg_w3].str_addr,MB1+KB4 +; mov [pong_rcv_msg+msg_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [pong_rcv_msg+msg_size_dope],(2 SHL md_mwords) + (1 SHL md_strings) +; mov [pong_rcv_msg+msg_w3].buf_size,KB4 +; mov [pong_rcv_msg+msg_w3].buf_addr,MB1+KB4 +; +; mov eax,MB2 +; mov eax,dword ptr [eax] +; +; call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + + + call exit_ktest + +; mov eax,offset $ +; and eax,-KB4 +; add eax,12*4 +; mov ecx,0C0000010h +; int 32h +; ke 'CDon' +; +; mov eax,offset $ +; and eax,-KB4 +; add eax,12*4 +; mov ecx,0C0000000h +; int 32h +; ke 'CDoff' +; + + mov eax,2 + cpuid + + if random_sampling + mov eax,dword ptr gs:[0] + mov ebx,dword ptr gs:[4] + mov ecx,dword ptr gs:[8] + mov edx,dword ptr gs:[12] + mov esi,dword ptr gs:[16] + mov edi,dword ptr gs:[20] + mov ebp,dword ptr gs:[24] + endif + + if fast_myself + + push sampling_space + pop gs + + mov eax,dword ptr gs:[9*4] + shr eax,10 + and eax,3FFFh + dec eax + + endif + + + ke 'done' + +; extern kpage_get_clock_usc:near +; DO +; call kpage_get_clock_usc +; ke 'get_clock' +; REPEAT +; OD + + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma1_task +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + ; mov edx,ecx + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + mov eax,3 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + ;------------------- for translate test only: + ; or byte ptr ds:[MB4],0 + ;---------------------------------------- + + clign 16 + DO + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count mem2pipe,cnt_event,bank_conf,cnt_event +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 +; P_count r_stall,cnt_event_PL3,w_stall,cnt_event_PL3 + rdtsc + push eax + + clign 16 + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/l4kd.asm b/l4-x86/l4-x/kernel/l4kd.asm new file mode 100644 index 0000000..09ee0d9 --- /dev/null +++ b/l4-x86/l4-x/kernel/l4kd.asm @@ -0,0 +1,82 @@ +.386p + NAME l4kd + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 9900 +kerneltxt EQU '15.12.00' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4KD Kernel Debugger (x86), Copyright (C) University of Karlsruhe 2000',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +strt segment para public use32 'code' + org 1100h +strt ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/memctr.asm b/l4-x86/l4-x/kernel/memctr.asm new file mode 100644 index 0000000..612e11f --- /dev/null +++ b/l4-x86/l4-x/kernel/memctr.asm @@ -0,0 +1,521 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include ktype.inc +include adrspace.inc +.nolist +include cpucb.inc +include segs.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86 + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + load__proot ebx,<((sigma0_task AND mask task_no) SHR task_no)> + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-x/kernel/pagctr.asm b/l4-x86/l4-x/kernel/pagctr.asm new file mode 100644 index 0000000..3c36810 --- /dev/null +++ b/l4-x86/l4-x/kernel/pagctr.asm @@ -0,0 +1,1204 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 01,09,00, 117 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.11.1001 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include ktype.inc +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include segs.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov ecx,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov ecx,page_present+page_write_permit+global_page + ;;if random_sampling OR fast_myself + ;; or ecx,page_user_permit + ;;endif + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov ecx,page_present+page_write_permit + ;;if random_sampling OR fast_myself + ;; or ecx,page_user_permit + ;;endif + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov ecx,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov ecx,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov ecx,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_proot + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + mov [edi+4],ecx + add edi,8 + cmp edi,offset proot_end_marker + REPEATB + OD + dec ecx + mov [edi],ecx + mov [edi+4],ecx + + + mov ds:[kernel_proot],edx + mov ds:[kernel_proot+4],edx + mov ds:[empty_proot],ebx + mov ds:[empty_proot+4],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov ecx,page_present+page_write_permit+global_page + if random_sampling OR fast_myself + or ecx,page_user_permit + endif + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; ECX access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push eax + push edi + push ebp + + and eax,-pagesize + and ecx,pagesize-1 + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test ebx,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + or ebx,ecx + or ebx,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + or eax,ecx + mov [ebx],eax + + sub edx,ebp + pop ebp + pop edi + pop eax + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; EXC access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + and eax,-MB4 + and ecx,pagesize-1 + + or eax,ecx + or eax,superpage + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 48 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + and edx,-pagesize + or edx,page_present+page_write_permit+global_page + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/pagfault.asm b/l4-x86/l4-x/kernel/pagfault.asm new file mode 100644 index 0000000..e5afedc --- /dev/null +++ b/l4-x86/l4-x/kernel/pagfault.asm @@ -0,0 +1,807 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 04,07,00, 9165, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 04.07.00 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86 + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_cs+4],phys_mem_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + IFNZ [ebp+fine_state],locked_running + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + push 0 + push phys_mem_exec + push offset ipcret + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + + test [ebp+ressources],in_partner_space + jnz partner_space_fault + + + call push_ipc_state + + IFNZ + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + test__page_present edx + CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin + CANDBE eax,offset ipc_critical_region_end + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + mov ah,byte ptr ds:[gdt+(linear_space AND -8)+7] + mov al,byte ptr ds:[gdt+(linear_space AND -8)+4] + shl eax,16 + xor eax,edx + shr eax,22 + mov cl,ch + shr eax,cl + + mov esi,ebp + IFNZ + mov esi,[ebp+com_partner] + FI + lno___task esi,esi + load__proot esi,esi + add esi,PM + + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + pop esi + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; partner-space write fault (msg copy small -> large, in large as +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +partner_space_fault: + + + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__proot eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + push edx + + mov dl,page_present + IFZ al,80h + mov dl,page_present+page_write_permit + FI + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + mov dh,cl + test cl,page_present + IFNZ + test cl,superpage + CANDZ + and ecx,-pagesize + xptab eax,eax + and dh,byte ptr ss:[(eax*4)+ecx+PM] + FI + and dh,dl + IFZ dh,dl + and byte ptr ss:[esp+iret_eflags+5*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+5*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+5*4],4 + + pop edx + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/pagmap.asm b/l4-x86/l4-x/kernel/pagmap.asm new file mode 100644 index 0000000..c1323d4 --- /dev/null +++ b/l4-x86/l4-x/kernel/pagmap.asm @@ -0,0 +1,1965 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 25,03,00, 46 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.03.00 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86 + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_ + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage special ext: set/reset PCD bits +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page + jmp short do_fpage + FI + push offset unmap_write_page + jmp short do_fpage + FI + + bt ecx,30 + IFNC + test ch,page_write_permit + IFNZ + push offset flush_page + jmp short do_fpage + FI + push offset flush_write_page + jmp short do_fpage + FI + + test ch,page_cache_disable + IFZ + push offset set_page_cacheable + ELSE_ + push offset set_page_uncacheable + FI + jmp short do_fpage + + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + ;; and ebx,[ebp+map_mask] + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + push edx + + mov edx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,edx + mov bl,[edx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize;;;;;;;;0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + pop ebx + xc z,unmap_in_own_address_space + + pop edx + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + test ebx,1 + IFNZ + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + ELSE_ + push edx + mov ebx,edx + and edx,(pagesize-1) AND -4 + shr ebx,log2_pagesize + shl edx,log2_pagesize-2 + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ebx,(pagesize-1) AND -4 + shl ebx,2*log2_pagesize-4 + add edx,ebx + invlpg [edx] + pop edx + FI + + + cmp edx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp edx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + pop ebx + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + + + test ebx,1 + IFZ + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -4 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -4 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + FI + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; set page cacheable/uncacheable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + +set_page_cacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT (page_cache_disable+page_write_through) + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + +set_page_uncacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + or byte ptr [esi],page_cache_disable+page_write_through + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + lno___task edx,ebp + load__proot edx,edx + add edx,PM + + mov ecx,cr3 + IFAE , + lno___task ecx,esp + load__proot ecx,ecx + FI + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-x/kernel/proj.err b/l4-x86/l4-x/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-x/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-x/kernel/sgmctr.asm b/l4-x86/l4-x/kernel/sgmctr.asm new file mode 100644 index 0000000..8c78d11 --- /dev/null +++ b/l4-x86/l4-x/kernel/sgmctr.asm @@ -0,0 +1,265 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 01,09,00, 20 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 01.09.00 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +.list + + +ok_for x86 + + + + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS phys_mem_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6,phys_mem_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + + descriptor xr32, dpl0, PM, <256*MB> ; special for kdebug_alias ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + + if random_sampling OR fast_myself + descriptor rw32, dpl3, 44, 44 ; 38 : sampling space + endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-x/kernel/sigma0.asm b/l4-x86/l4-x/kernel/sigma0.asm new file mode 100644 index 0000000..3dc61dd --- /dev/null +++ b/l4-x86/l4-x/kernel/sigma0.asm @@ -0,0 +1,770 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-x/kernel/start.asm b/l4-x86/l4-x/kernel/start.asm new file mode 100644 index 0000000..0ddb173 --- /dev/null +++ b/l4-x86/l4-x/kernel/start.asm @@ -0,0 +1,407 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 15,12,00, 33 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 15.12.00 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + extrn grab_frame:near + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86 + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + if V4_clock_features + + public kpage_get_clock_usc + extrn get_clock_usc:near + + + kpage_get_clock_usc: + jmp get_clock_usc ; 10D0 ; usc jmp table + db 0,0,0 + dd 0,0 + + endif + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + + call init_memctr + + + mov edi,offset physical_kernel_info_page + + push offset grab_frame + push irq0_intr + push dword ptr cs:[edi+kdebug_permissions] + push dword ptr cs:[edi+kdebug_configuration] + push offset kernel_proot + push edi + push offset local_apic + push offset io_apic + push 0 ; kdebug_extension_proc + + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + + if random_sampling OR fast_myself + + extrn init_random_sampling:near + + call init_random_sampling + + endif + + + + + if precise_cycles + + ke 'measuring kernel' + + else + test ds:[physical_kernel_info_page].kdebug_configuration.flags,startup_kdebug + IFNZ + mov eax,2 + cpuid + + ke 'debug' + FI + endif + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/startpc.asm b/l4-x86/l4-x/kernel/startpc.asm new file mode 100644 index 0000000..d2bd63e --- /dev/null +++ b/l4-x86/l4-x/kernel/startpc.asm @@ -0,0 +1,1312 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include segs.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + +;; mov al,0C1h ; prio := 8..15,3..7,0,1 + mov al,0C7h ; prio := 0,1,8..15,3..7 + out pic1_ocw2,al ; + ;; KB must have low prio because + ;; intr may arrive during paging + ;; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + ; Select status register A from RTC + + mov al,rtc_reg_a + out rtc_address,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + + ; Wait for UIP (update in progress) flag to disappear + + DO + in al,rtc_data + and al,80h + REPEATNZ + OD + + ; Wait for UIP flag to appear again. This indicates + ; that a second has passed + + DO + in al,rtc_data + and al,80h + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + push 3 + push 0 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-x/kernel/tables.asm b/l4-x86/l4-x/kernel/tables.asm new file mode 100644 index 0000000..998acfc --- /dev/null +++ b/l4-x86/l4-x/kernel/tables.asm @@ -0,0 +1,21 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include ktype.inc +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/tcbman.asm b/l4-x86/l4-x/kernel/tcbman.asm new file mode 100644 index 0000000..f184117 --- /dev/null +++ b/l4-x86/l4-x/kernel/tcbman.asm @@ -0,0 +1,737 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 26,06,00, 9143 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 26.06.00 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + extrn sigma_1_installed:byte + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include ktype.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include segs.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86 + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,(max_lthread_no SHL lthread_no) + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + cmp ebx,-1 + IFNZ + xchg ebx,[ebp+int_preempter] + ELSE_ + mov ebx,[ebp+int_preempter] + FI + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret + + mov dword ptr [esi+4],linear_space + mov dword ptr [esi+8],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; FI + mov [ebp+pager],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + ELSE_ + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + mov dword ptr [ebx+ip_es+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/x.asm b/l4-x86/l4-x/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-x/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernel/y.asm b/l4-x86/l4-x/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-x/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-x/kernel/yoonseva.asm b/l4-x86/l4-x/kernel/yoonseva.asm new file mode 100644 index 0000000..dd5d27f --- /dev/null +++ b/l4-x86/l4-x/kernel/yoonseva.asm @@ -0,0 +1,337 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include ktype.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include segs.inc +include intrifc.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),phys_mem_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-x/kernifc/adrspace.inc b/l4-x86/l4-x/kernifc/adrspace.inc new file mode 100644 index 0000000..48f3fde --- /dev/null +++ b/l4-x86/l4-x/kernifc/adrspace.inc @@ -0,0 +1,218 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ((64+64)*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ((88-64-4)*MB) + + kdebug_cached_alias_size equ ( 4*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + kdebug_cached_alias_mem db kdebug_cached_alias_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com_space_size dup (?) + com1_space db com_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + + + +PM equ offset physical_kernel_memory + +KR equ 0 + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + + + + + + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00BF3000h-(max_ptabs*(chapters_per_page+4))-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd tasks*dwords_per_task_proot dup (?) ; | + proot_end_marker dd dwords_per_task_proot dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + + dd (kernel_r_tables_size - offset kernel_resident_tables) + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd 0,0 + kernel_proot dd 0,0 + sigma0_proot dd 0,0 + +special_proots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) diff --git a/l4-x86/l4-x/kernifc/contents b/l4-x86/l4-x/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-x/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-x/kernifc/cpucb.inc b/l4-x86/l4-x/kernifc/cpucb.inc new file mode 100644 index 0000000..4b3149c --- /dev/null +++ b/l4-x86/l4-x/kernifc/cpucb.inc @@ -0,0 +1,7 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/l4-x/kernifc/cpucb5.inc b/l4-x86/l4-x/kernifc/cpucb5.inc new file mode 100644 index 0000000..3af256a --- /dev/null +++ b/l4-x86/l4-x/kernifc/cpucb5.inc @@ -0,0 +1,308 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + if random_sampling OR fast_myself + + sampled_total dd 0 + + sampled dd 6 dup (0) + + sampl_flags dd 0 + + sampl_block equ sampled_total + sampl_block_len equ (8*4+16) + + endif + + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + if precise_cycles + last_rdtsc_value dd 0 ; tss_ss2 + else + dd 0 ; tss_ss2 + endif + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +cpu___cycles macro old_tcb + local xx + if precise_cycles + push eax + push edx + rdtsc + mov edx,ds:[last_rdtsc_value] + mov ds:[last_rdtsc_value],eax + sub eax,edx + add [&old_tcb&+cpu_cycles],eax + jnc xx + inc [&old_tcb&+cpu_cycles+4] + xx: + pop edx + pop eax + endif +endm + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + cpu___cycles &src_tcb + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + if random_sampling OR fast_myself + mov ebp,sampling_space + endif + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + diff --git a/l4-x86/l4-x/kernifc/intrifc.inc b/l4-x86/l4-x/kernifc/intrifc.inc new file mode 100644 index 0000000..40b97c6 --- /dev/null +++ b/l4-x86/l4-x/kernifc/intrifc.inc @@ -0,0 +1,287 @@ +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + + + +int_pm_stack struc + + ip_es dd 0 + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + push es + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-x/kernifc/ktype.inc b/l4-x86/l4-x/kernifc/ktype.inc new file mode 100644 index 0000000..324e43d --- /dev/null +++ b/l4-x86/l4-x/kernifc/ktype.inc @@ -0,0 +1,37 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ x86 + +subtitle L4/x86 Version X + +kernel_family = lime_pip + +kernel_type = x86 + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + +redirection = 0 +prio_sensitive_donation_on_send = 1 +precise_cycles = 0 +random_sampling = 1 +random_profiling = 1 ; = 1 REQUIRES random_sampling = 1 +fast_myself = 1 +V4_clock_features = 0 + + ENDIF + + + + + + diff --git a/l4-x86/l4-x/kernifc/lbmac.inc b/l4-x86/l4-x/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-x/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-x/kernifc/pagcb.inc b/l4-x86/l4-x/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-x/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-x/kernifc/pagmac.inc b/l4-x86/l4-x/kernifc/pagmac.inc new file mode 100644 index 0000000..6fdb993 --- /dev/null +++ b/l4-x86/l4-x/kernifc/pagmac.inc @@ -0,0 +1,82 @@ + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +x86_proot struc + + switch_ptr dd 0 + proot_ptr dd 0 + +x86_proot ends + +x86_prootx struc + + dd 0 + small_as db 0 + db 0,0,0 + +x86_prootx ends + + +load__proot macro reg,task_no + + mov reg,ds:[(task_no*8)+task_proot+4] + IFIDN , + mov al,0 + ELSEIFIDN , + mov bl,0 + ELSEIFIDN , + mov cl,0 + ELSEIFIDN , + mov dl,0 + ELSE + and reg,0FFFFFF00h + ENDIF + endm + + +store_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + mov ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + +store_inactive_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot],reg + mov ds:[(task_no*8)+task_proot+4],0 + endm + + +chnge_proot macro reg,task_no + + test byte ptr ds:[(task_no*8)+task_proot+3],80h + IFZ + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + + diff --git a/l4-x86/l4-x/kernifc/pnodes.inc b/l4-x86/l4-x/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-x/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-x/kernifc/proj.err b/l4-x86/l4-x/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-x/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-x/kernifc/schedcb.inc b/l4-x86/l4-x/kernifc/schedcb.inc new file mode 100644 index 0000000..881b5ae --- /dev/null +++ b/l4-x86/l4-x/kernifc/schedcb.inc @@ -0,0 +1,347 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + diff --git a/l4-x86/l4-x/kernifc/schedcb2.inc b/l4-x86/l4-x/kernifc/schedcb2.inc new file mode 100644 index 0000000..ea96dda --- /dev/null +++ b/l4-x86/l4-x/kernifc/schedcb2.inc @@ -0,0 +1,48 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + if V4_clock_features + next_timer_int dd 0 + next_clock_tick dd 0 + next_random_sampling_event dd 0 + next_wakeup_event dd 0 + next_wakeup_precision db 0 + else + system_clock dd 0,0 + endif + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +ticklength equ 2000 + +clock_tick_precision equ 5 +random_sampling_precision equ 5 + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + + diff --git a/l4-x86/l4-x/kernifc/segs.inc b/l4-x86/l4-x/kernifc/segs.inc new file mode 100644 index 0000000..8b601a8 --- /dev/null +++ b/l4-x86/l4-x/kernifc/segs.inc @@ -0,0 +1,23 @@ + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +linear_kernel_space equ 0008h + +linear_space equ (0010h+3) +linear_space_exec equ (0018h+3) + +phys_mem_exec equ 0020h +phys_mem equ 0028h + +cpu0_tss equ 0030h + + sampling_space equ (0038h+3) + + + diff --git a/l4-x86/l4-x/kernifc/small-as.inc b/l4-x86/l4-x/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-x/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-x/kernifc/tcb.inc b/l4-x86/l4-x/kernifc/tcb.inc new file mode 100644 index 0000000..4bf03f4 --- /dev/null +++ b/l4-x86/l4-x/kernifc/tcb.inc @@ -0,0 +1,292 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + if V4_clock_features + instant_wakeup_link dd 0 + else + dd 0 + endif + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + if precise_cycles + cpu_cycles dd 0,0 + else + cpu_clock dd 0,0 + endif + + com_partner dd 0 + waddr dd 0 + wakeup dd 0,0 + + myself dd 0 + if V4_clock_features + wakeup_precision db 0 + db 0,0,0 + else + dd 0 + endif + waiting_for dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + pager dd 0 + ext_preempter dd 0 + int_preempter dd 0 + thread_dr6 db 0 + state_sp db 0 + clan_depth db 0 + db 0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record ts_prot:1,rfree:2,in_partner_space:1,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + + if V4_clock_features +liste_state_bits record zpres:1,zfree:1,zpolled:1,zpoll:1,zmwake:1,zswake:1,ziwake:1,zready:1 + else +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + endif + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake + if V4_clock_features +is_instant_wakeup equ mask ziwake + endif +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_proot/(dwords_per_task_proot*4) GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_proot)/(dwords_per_task_proot*4) - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-x/make/l4.rsp b/l4-x86/l4-x/make/l4.rsp new file mode 100644 index 0000000..a83dd90 --- /dev/null +++ b/l4-x86/l4-x/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-x/make/make-l4 b/l4-x86/l4-x/make/make-l4 new file mode 100644 index 0000000..f321d9a --- /dev/null +++ b/l4-x86/l4-x/make/make-l4 @@ -0,0 +1,141 @@ + +i={\liedtke\l4xinfra\} +p={\liedtke\l4-x\kernel\;\liedtke\l4-x\kernifc\;\liedtke\l4-x\userifc\} +q={\liedtke\l4-x\hazelkd\} +a=D:\liedtke\l4-x\x86^\ +b=D:\liedtke\l4-x\hazelkd^\ +all_includes_x86= $(p)ktype.inc $(p)adrspace.inc $(p)tcb.inc $(p)kdinit.inc $(p)segs.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(i)l4pre.inc $(i)l4const.inc $(i)l4kd.inc $(i)pagconst.inc $(i)apic.inc +all_includes_hnd= $(q)ktype.inc $(q)adrspace.inc $(q)tcb.inc $(q)kdinit.inc $(q)segs.inc $(q)intrifc.inc $(q)pagmac.inc $(p)uid.inc $(p)kpage.inc $(i)l4pre.inc $(i)l4const.inc $(i)l4kd.inc $(i)pagconst.inc + + +$(a)adrsman.obj : $(all_includes_x86) $(p)adrsman.asm + cd \liedtke\l4-x\x86 + ml @..\make\ml-x86.rsp ..\kernel\adrsman.asm + +$(a)cpuctr.obj : $(all_includes_x86) $(p)cpuctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\cpuctr.asm + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\dispatch.asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\emuctr.asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\intctr.asm + +$(a)ipcman.obj : $(all_includes_x86) $(p)ipcman.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\ipcman.asm + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\kdebug.asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\kdiopc.asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\kernel.asm + +$(a)ktest.obj : $(all_includes_x86) $(p)ktest.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\ktest.asm + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\memctr.asm + +$(a)pagctr.obj : $(all_includes_x86) $(p)pagctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\pagctr.asm + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\pagfault.asm + +$(a)pagmap.obj : $(all_includes_x86) $(p)pagmap.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\pagmap.asm + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\sgmctr.asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\sigma0.asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\start.asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\startpc.asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\tcbman.asm + +$(a)yoonseva.obj : $(all_includes_x86) $(p)yoonseva.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\yoonseva.asm + + + + +$(b)kdebug.obj : $(all_includes_hnd) $(p)kdebug.asm + @cd \liedtke\l4-x\hazelkd + @ml @..\make\ml-hn.rsp ..\kernel\kdebug.asm + +$(b)kdiopc.obj : $(all_includes_hnd) $(p)kdiopc.asm + @cd \liedtke\l4-x\hazelkd + @ml @..\make\ml-hn.rsp ..\kernel\kdiopc.asm + +$(b)l4kd.obj : $(p)l4kd.asm + @cd \liedtke\l4-x\hazelkd + @ml @..\make\ml-hn.rsp ..\kernel\l4kd.asm + +$(b)kdebug.exe : $(b)l4kd.obj $(b)kdebug.obj $(b)kdiopc.obj + @cd \liedtke\l4-x\hazelkd + @link l4kd kdebug kdiopc,kdebug.exe,kdebug.map; + + + + + +$(a)l4.exe : $(b)kdebug.exe +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-x\x86 + @link /nologo @..\make\l4.rsp + pause + + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \liedtke\l4-x\x86 + @ml @..\make\ml-x86.rsp ..\kernel\boot.asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-x\x86 + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-x/make/make-l4.bak b/l4-x86/l4-x/make/make-l4.bak new file mode 100644 index 0000000..1d9a115 --- /dev/null +++ b/l4-x86/l4-x/make/make-l4.bak @@ -0,0 +1,114 @@ + +p={\liedtke\l4-x\kernel\;\liedtke\l4-x\kernifc\;\liedtke\l4-x\userifc\} +a=c:\liedtke\l4-x\x86^\ +all_includes_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_x86) $(p)adrsman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 adrsman asm + +$(a)cpuctr.obj : $(all_includes_x86) $(p)cpuctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 cpuctr asm + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman.obj : $(all_includes_x86) $(p)ipcman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 ipcman asm + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 kernel asm + +$(a)ktest.obj : $(all_includes_x86) $(p)ktest.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 ktest asm + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr.obj : $(all_includes_x86) $(p)pagctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagctr asm + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap.obj : $(all_includes_x86) $(p)pagmap.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 pagmap asm + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 tcbman asm + +$(a)yoonseva.obj : $(all_includes_x86) $(p)yoonseva.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-x\x86 + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \liedtke\l4-x\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-x\x86 + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-x/make/ml-hn.rsp b/l4-x86/l4-x/make/ml-hn.rsp new file mode 100644 index 0000000..64fa90a --- /dev/null +++ b/l4-x86/l4-x/make/ml-hn.rsp @@ -0,0 +1 @@ +/Dtarget=x86 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\..\l4xinfra /I../hazelkd /I..\userifc \ No newline at end of file diff --git a/l4-x86/l4-x/make/ml-x86.rsp b/l4-x86/l4-x/make/ml-x86.rsp new file mode 100644 index 0000000..5a181dd --- /dev/null +++ b/l4-x86/l4-x/make/ml-x86.rsp @@ -0,0 +1,2 @@ +/Dtarget=x86 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\..\l4xinfra /I..\kernifc /I..\userifc + diff --git a/l4-x86/l4-x/make/old-ml-hn.bat b/l4-x86/l4-x/make/old-ml-hn.bat new file mode 100755 index 0000000..91c466e --- /dev/null +++ b/l4-x86/l4-x/make/old-ml-hn.bat @@ -0,0 +1,2 @@ +echo on +ml @..\make\ml-hn.rsp %1 \ No newline at end of file diff --git a/l4-x86/l4-x/make/old-ml-x86.bat b/l4-x86/l4-x/make/old-ml-x86.bat new file mode 100755 index 0000000..37080f7 --- /dev/null +++ b/l4-x86/l4-x/make/old-ml-x86.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=x86 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-x/make/proj.err b/l4-x86/l4-x/make/proj.err new file mode 100644 index 0000000..3828282 --- /dev/null +++ b/l4-x86/l4-x/make/proj.err @@ -0,0 +1,18 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +LINK : warning L4021: no stack segment +LINK : warning L4038: program has no starting address + Assembling: ..\kernel\start.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + +Loading NMAKE diff --git a/l4-x86/l4-x/userifc/contents b/l4-x86/l4-x/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-x/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-x/userifc/kpage.inc b/l4-x86/l4-x/userifc/kpage.inc new file mode 100644 index 0000000..b83a80f --- /dev/null +++ b/l4-x86/l4-x/userifc/kpage.inc @@ -0,0 +1,121 @@ +current_kpage_version equ 3 + + + + + + + +kdebug_permissions_word struc + max_task db 0 + flags db 0 + dw 0 +kdebug_permissions_word ends + +kdebug_configuration_word struc + trace_pages db 0 + flags db 0 + start_port dw 0 +kdebug_configuration_word ends + + + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_configuration kdebug_configuration_word + kdebug_permissions kdebug_permissions_word + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + usc_jmp_table db 16 dup (0) + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-x/userifc/msg.inc b/l4-x86/l4-x/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-x/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-x/userifc/scmac.inc b/l4-x86/l4-x/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-x/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-x/userifc/syscalls.inc b/l4-x86/l4-x/userifc/syscalls.inc new file mode 100644 index 0000000..ff0f980 --- /dev/null +++ b/l4-x86/l4-x/userifc/syscalls.inc @@ -0,0 +1,25 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 \ No newline at end of file diff --git a/l4-x86/l4-x/userifc/uid.inc b/l4-x86/l4-x/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-x/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-y-0/c-bind/new/compiler.h b/l4-x86/l4-y-0/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-0/c-bind/new/idt.h b/l4-x86/l4-y-0/c-bind/new/idt.h new file mode 100644 index 0000000..6c42904 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/new/ipc-trent.c b/l4-x86/l4-y-0/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-0/c-bind/new/ipc.h b/l4-x86/l4-y-0/c-bind/new/ipc.h new file mode 100644 index 0000000..62f787a --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-0/c-bind/new/kdebug.h b/l4-x86/l4-y-0/c-bind/new/kdebug.h new file mode 100644 index 0000000..95ab7a5 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-0/c-bind/new/kernel.h b/l4-x86/l4-y-0/c-bind/new/kernel.h new file mode 100644 index 0000000..632586f --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-0/c-bind/new/syscalls.h b/l4-x86/l4-y-0/c-bind/new/syscalls.h new file mode 100644 index 0000000..30e4c81 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/new/test.c b/l4-x86/l4-y-0/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-y-0/c-bind/new/types.h b/l4-x86/l4-y-0/c-bind/new/types.h new file mode 100644 index 0000000..b51fc86 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-0/c-bind/new/x-compiler.h b/l4-x86/l4-y-0/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-0/c-bind/new/x-idt.h b/l4-x86/l4-y-0/c-bind/new/x-idt.h new file mode 100644 index 0000000..2ef9070 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/new/x-ipc.h b/l4-x86/l4-y-0/c-bind/new/x-ipc.h new file mode 100644 index 0000000..dbbf553 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-0/c-bind/new/x-kdebug.h b/l4-x86/l4-y-0/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..89c8e69 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-0/c-bind/new/x-kernel.h b/l4-x86/l4-y-0/c-bind/new/x-kernel.h new file mode 100644 index 0000000..53faf40 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-0/c-bind/new/x-lid.c b/l4-x86/l4-y-0/c-bind/new/x-lid.c new file mode 100644 index 0000000..cf19088 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-y-0/c-bind/new/x-syscalls.h b/l4-x86/l4-y-0/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..f60201c --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/new/x-types.h b/l4-x86/l4-y-0/c-bind/new/x-types.h new file mode 100644 index 0000000..e6cb467 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-0/c-bind/orig/compiler.h b/l4-x86/l4-y-0/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-0/c-bind/orig/idt.h b/l4-x86/l4-y-0/c-bind/orig/idt.h new file mode 100644 index 0000000..6c42904 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:49 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/orig/ipc-trent.c b/l4-x86/l4-y-0/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-0/c-bind/orig/ipc.h b/l4-x86/l4-y-0/c-bind/orig/ipc.h new file mode 100644 index 0000000..aa72f8f --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-0/c-bind/orig/kdebug.h b/l4-x86/l4-y-0/c-bind/orig/kdebug.h new file mode 100644 index 0000000..e83bd0f --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-0/c-bind/orig/kernel.h b/l4-x86/l4-y-0/c-bind/orig/kernel.h new file mode 100644 index 0000000..657b337 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-0/c-bind/orig/syscalls.h b/l4-x86/l4-y-0/c-bind/orig/syscalls.h new file mode 100644 index 0000000..5661437 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/orig/types.h b/l4-x86/l4-y-0/c-bind/orig/types.h new file mode 100644 index 0000000..c4f6c15 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-0/c-bind/provisional/compiler.h b/l4-x86/l4-y-0/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-0/c-bind/provisional/idl.m4 b/l4-x86/l4-y-0/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-y-0/c-bind/provisional/idt.h b/l4-x86/l4-y-0/c-bind/provisional/idt.h new file mode 100644 index 0000000..8245cc2 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/provisional/ipc-trent.c b/l4-x86/l4-y-0/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-0/c-bind/provisional/ipc.h b/l4-x86/l4-y-0/c-bind/provisional/ipc.h new file mode 100644 index 0000000..fcb3cde --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-0/c-bind/provisional/kdebug.h b/l4-x86/l4-y-0/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..e83bd0f --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-0/c-bind/provisional/kernel.h b/l4-x86/l4-y-0/c-bind/provisional/kernel.h new file mode 100644 index 0000000..657b337 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-0/c-bind/provisional/syscalls.h b/l4-x86/l4-y-0/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..5661437 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-0/c-bind/provisional/types.h b/l4-x86/l4-y-0/c-bind/provisional/types.h new file mode 100644 index 0000000..c4f6c15 --- /dev/null +++ b/l4-x86/l4-y-0/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:50 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-0/kernel/adrsman.asm b/l4-x86/l4-y-0/kernel/adrsman.asm new file mode 100644 index 0000000..6685758 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/adrsman.asm @@ -0,0 +1,954 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 08, 08, 99, 9025 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 08.08.99 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86,pIII + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+KR + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + lno___task eax,ebp ; + load__proot eax,eax ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + lno___task edi,ebx ; + ; + call detach_associated_small_space ; + ; + load__proot edi,edi ; + ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + mov ecx,[(ecx*8)+task_proot].switch_ptr + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax ; + lea___tcb ebp,eax ; + ; + IFZ [edi*8+task_proot].proot_ptr,0 ; + mov edi,[edi*8+task_proot].switch_ptr ; + sub edi,ds:[empty_proot] ; + ELSE_ ; + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + push eax + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + pop eax + + lno___task ebp + store_proot eax,ebp + FI + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + + ret + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + + lno___task ebp,esi + lea edi,[ebp*8+task_proot] + + movzx eax,ah + movzx ecx,[edi].small_as + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*2)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*2)+small_associated_task],bp + FI + mov ecx,eax + mov [edi].small_as,al + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + mov [edi].switch_ptr,ecx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push eax + push edi + + movzx edi,[(ecx*2)+small_associated_task] + test edi,edi + IFNZ + mov word ptr [(ecx*2)+small_associated_task],0 + + call flush_small_pde_block_in_all_pdirs + + lea ecx,[(edi*8)+task_proot] + + mov eax,cr3 + mov cr3,eax + + mov eax,[ecx].proot_ptr + mov al,0 + mov [ecx].switch_ptr,eax + mov [ecx].proot_ptr,eax + FI + + lno___task eax,esp + IFZ eax,edi + call make_own_address_space_large + FI + + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; detach associated small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push ecx + + movzx ecx,[edi*8+task_proot].small_as + test ecx,ecx + IFNZ + call detach_small_space + FI + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; EDI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[edi].switch_ptr + mov edi,ds:[kernel_proot] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + lno___task edi,esp + + lea edi,[(edi*8)+task_proot] + mov eax,[edi].proot_ptr + mov al,0 + mov [edi].switch_ptr,eax + + mov edi,eax + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + mov fs,eax + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + mov edx,offset task_proot + DO + mov ebp,[edx].proot_ptr + add edx,8 + and ebp,0FFFFFF00h + REPEATZ + + EXITS + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + lno___task eax,esi + mov eax,[eax*8+task_proot].switch_ptr + + test eax,eax + IFNS + mov al,0 + ret + FI + + rol eax,8 + xchg al,ah + shr eax,22-16 + sub al,(offset small_virtual_spaces SHR 22) AND 0FFh + add al,al + add al,ds:[small_space_size_DIV_MB4] + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/atrace.asm b/l4-x86/l4-y-0/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-y-0/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-0/kernel/boot.asm b/l4-x86/l4-y-0/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-y-0/kernel/contents b/l4-x86/l4-y-0/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-y-0/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/cpuctr.asm b/l4-x86/l4-y-0/kernel/cpuctr.asm new file mode 100644 index 0000000..0e9f099 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/cpuctr.asm @@ -0,0 +1,1237 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 20,09,99, 69, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.09.99 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for pIII + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + push eax + and ah,0Fh + IFZ ah,6 + CANDB al,30h + and al,0Fh + CANDB al,3 + btr edx,sysenter_present_bit + FI + pop eax + IF kernel_relocation EQ 0 + btr edx,sysenter_present_bit + ENDIF + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+KR + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + ;;; DO + ;;; rdtsc + ;;; mov ebx,eax + ;;; rdtsc + ;;; sub eax,ebx + ;;; mov esi,eax + ;;; + ;;; rdtsc + ;;; mov ebx,eax + ;;; mov ecx,175h + ;;; rdmsr + ;;; rdtsc + ;;; sub eax,ebx + ;;; sub eax,esi + ;;; mov edi,eax + ;;; + ;;; rdtsc + ;;; mov ebx,eax + ;;; mov ecx,175h + ;;; wrmsr + ;;; rdtsc + ;;; sub eax,ebx + ;;; sub eax,esi + ;;; + ;;; ke 'sysenter_esp_msr' + ;;; + ;;; REPEAT + ;;; OD + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int+KR + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler+KR + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + + switch_thread con,ebx + + shr ebp,task_no + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + push eax + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + pop eax + + mov esi,ebp + shr ebp,task_no + + push ds + switch_space ; switch space may load user_linear space into ds + pop ds + + mov ebp,esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret + + +deallocate_ressources: + + push eax + + test [edi+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + mov eax,ebp + shr eax,task_no + mov eax,[(eax*8)+task_proot-(offset tcb_space SHR (task_no-3))] + CORA eax, + IFZ ds:[cpu_cr3],eax + + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd + push offset reallocate_ressources_by_ret + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],kernel_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+KR + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/dispatch.asm b/l4-x86/l4-y-0/kernel/dispatch.asm new file mode 100644 index 0000000..4984403 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/dispatch.asm @@ -0,0 +1,1419 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.DISPATCH, 20,09,99, 9090, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.09.99 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86,pIII + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc+KR + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc+KR + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + klign 16 + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret+KR + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret+KR + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + ELIFZ ebx,[esi+int_preempter] + add dl,20h + ELIFZ ebx,[esi+ext_preempter] + add dl,30h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + FI + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFB_ ah,max_small_spaces + call attach_small_space + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov ebx,[esi+ext_preempter] + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + clign 4 + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + clign 16 + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/emuctr.asm b/l4-x86/l4-y-0/kernel/emuctr.asm new file mode 100644 index 0000000..56e93ae --- /dev/null +++ b/l4-x86/l4-y-0/kernel/emuctr.asm @@ -0,0 +1,511 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pIII + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler+KR + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + clign 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/idecode.asm b/l4-x86/l4-y-0/kernel/idecode.asm new file mode 100644 index 0000000..6a3760f --- /dev/null +++ b/l4-x86/l4-y-0/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],phys_mem_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-0/kernel/intctr.asm b/l4-x86/l4-y-0/kernel/intctr.asm new file mode 100644 index 0000000..d4deeb0 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/intctr.asm @@ -0,0 +1,563 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 24,02,00, 9057 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.02.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86,pIII + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler+KR + db dpl3 + dd offset initial_debug_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler+KR + db dpl3 + dd offset overflow_handler+KR + db dpl3 + dd offset bound_check_handler+KR + db dpl3 + dd offset invalid_opcode_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler+KR + db dpl0 + dd offset stack_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler+KR + db dpl0 + dd offset alignment_check_handler+KR + db dpl0 + dd offset machine_check_exception+KR + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,kernel_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection,long ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt,long + ; data segment + mov ecx,linear_space ; + CORNZ [esp+ip_ds],ecx ; + mov edx,es ; + IFNZ edx,ecx ; + test byte ptr ss:[esp+ip_cs],11b + IFNZ ; + mov [esp+ip_ds],ecx; do not update DS + FI ; if within kernel ! + mov es,ecx ; (DS might be kernel seg) + ipost ; + FI ; + + + + IFZ ebx,linear_space AND -4 ;;;;;; linear_space !! not _exec + CANDA [esp+ip_eip],PM ;;;;;; provisional, only for SYSEXIT + + pop ds + popad + + add esp,4+3*4 + + mov ebp,esp + push ecx + push edx + mov ecx,esp + mov edx,offset exc_sysexit+KR + db 0Fh,35h ; sysexit + + exc_sysexit: + pop edx + pop ecx + + mov ss:[ebp+iret_cs],linear_space_exec + lss esp,fword ptr ss:[esp+iret_esp] + jmp dword ptr cs:[ebp] + + FI + + + + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + lno___task edi,esp + test byte ptr ss:[edi*8+task_proot+3].switch_ptr,80h + CANDNZ + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/ipcman.asm b/l4-x86/l4-y-0/kernel/ipcman.asm new file mode 100644 index 0000000..a16dce0 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/ipcman.asm @@ -0,0 +1,3605 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 24,02,00, 9176, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.02.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+KR + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + shr ebp,task_no + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+KR + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + + push eax + push ebx + + cmp eax,virtual_space_size-MB4 + jae receive_only_sc + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + jmp short ipc_body + + + + + + +;-------------------------------------------------- + + +ipc_sysenter: + + mov esp,ss:[cpu_esp0] + + push linear_space + push ecx + and eax,NOT 2 + push eax + push linear_space_exec + push edx + + mov ebx,esp + and ebx,-sizeof tcb + + mov eax,[ecx+2*4] + push eax + mov edx,[ecx+4+2*4] + push edx + mov edx,[ecx+8+2*4] + push edx + mov ecx,[ecx+12+2*4] + + + cmp eax,virtual_space_size-MB4 + jae receive_only_sysenter + + +ipc_body: + + mov edx,linear_kernel_space + mov ds,edx + + + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + mov [ebx+waiting_for],esi + and al,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + ; + and ebp,mask task_no ; + mov edx,ebx ; + ; + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + mov edx,[edx+ebp+redirection_table] ; + ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + and ebp,mask thread_no + + mov [ebx+mword2],edi + add ebp,offset tcb_space + + mov edi,[ebx+myself] + ;REDIR: and al,(NOT ipc_control_mask)+deceit+map_msg + + mov edx,[ebp+myself] + xor edi,esi + + test edi,mask chief_no + xc nz,to_chief,long + + cmp esi,edx + jnz ipc_dest_not_existent + + test al,deceit + xc nz,propagate_pre,long + + mov dl,[ebp+fine_state] + + + and dl,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + xc nz,pending_or_auto_propagating,long + FI + + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + + mov edx,[ebx+rcv_descriptor] + + mov [ebp+fine_state],running + cmp edx,virtual_space_size + + IF____xc ae,send_only,long + + ELSE__ + + test [ebx+list_state],is_polled + xc nz,perhaps_fetch_next,long + + mov dl,byte ptr ds:[ebx+rcv_descriptor] + and dl,nclos + + test ecx,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + +;;;;; switch_thread ipc,edi + + mov cl,[edi+ressources] + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + shr ebp,task_no + mov esi,[edi+myself] + + test al,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + + +;;;;;;;;;;;; switch_space + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + cmp byte ptr ds:[gdt+linear_space/8*8+7],0 + mov cr3,ebp + mov ebp,linear_space + IFZ + mov ds,ebp + pop ebp + iretd + FI + FI + mov ebp,00CCF300h + FI + + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + + mov ds:[gdt+linear_space_exec/8*8+4],ebp + mov ebp,linear_space + + mov es,ebp + +;; mov fs,ebp + +;; mov gs,ebp + + mov ds,ebp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pop ebp + test byte ptr ss:[esp+8],10b + IFZ + + mov ebp,edx + mov edx,offset ipc_sysexit+KR + mov ecx,esp + sysexit + + ipc_sysexit: + lss esp,ss:[esp+3*4] + mov edx,ebp + jmp fword ptr ss:[esp] + + FI + + iretd + + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z,long + + mov esi,[edi+virtual_sender] + xret ,long + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret+KR + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + mov edi,[esp+iret_esp+3*4] ; must be read from user space, + sub edx,edx + + mov [ebx+propagatee_tcb],edx + mov edi,es:[edi] ; potentially small space + + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + mov [ebx+virtual_sender],edi + + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + test esi,mask task_no + IFZ + lea___tcb esi,edi + + test__page_writable esi + IFNC + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + CANDZ dl,closed_wait + CANDZ [ebx+myself],edi + + mov [ebx+propagatee_tcb],esi + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + xret ,long + FI + + + ;REDIR begin -------------------------------- + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + test edx,mask chief_no ; ; + xret z,long ; + ; + mov edx,[ebx+myself] ; + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; + ; + and ebp,mask task_no ; + mov esi,edi ; + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + pop ebp ; + pop ecx ; + xret ,long ; + OD ; + pop ebp ; + pop ecx ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + ;REDIR ends ----------------------------------- + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret+KR + + and ecx,0FFFFFF0Fh + mov edi,ecx + and edi,0FF000000h + add ecx,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + mov edx,(locked_running SHL 8) + (locked_waiting AND 0FFh) + + mov [ebx+fine_state],dh + mov [ebp+fine_state],dl + + and al,ipc_control_mask + mov esi,[esp+4+4] + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + IFNZ + mov bl,al + mov eax,es:[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + ;; mov [ebx+com_partner],ebp + + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + ;;; mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w3 + nop + + mov eax,[eax*8+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w3] + + mov edi,[edx+32] + lea edi,[edx+msg_w3] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressource ebx,com_used + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + nop + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+KR + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w3 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + IFB_ eax,ecx + mov ecx,eax + FI + IFB_ ebx,ecx + mov ecx,ebx + FI + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + + + if 0 ;----------------------------------------- + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w3-2*4] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w3-2*4] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + + push eax + push ebx + + mov eax,[edi+buf_addr] + mov [edi+str_len],ecx + mov [edi+str_addr],eax + + mov esi,[esi+str_addr] + mov edi,eax + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + + + endif ;-------------------------------------- + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +XHEAD prepare_small_string_source + + shl eax,16 + + lea edx,[esi+ecx] + sass__32 cmp,edx,MB4 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + mov eax,[eax*8+task_proot].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + align 16 + + +XHEAD perhaps_fetch_next + + test edx,nclos + xret z,long + + + +fetch_next: + + add dl,locked_closed_waiting + mov [ebx+fine_state],dl + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+KR + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+KR + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only_sc: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + + + +receive_only_sysenter: + + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret+KR + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret+KR + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll+KR + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret+KR + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret+KR + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll+KR + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret+KR + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret+KR + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+KR + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],sysenter_present_bit + IFNC + ke '-processor does not support fast system calls' + FI + + mov ecx,sysenter_cs_msr + mov eax,kernel_exec + sub edx,edx + wrmsr + + mov ecx,sysenter_eip_msr + mov eax,offset ipc_sysenter+KR + sub edx,edx + wrmsr + + mov ecx,sysenter_esp_msr + mov eax,ds:[cpu_esp0] + sub edx,edx + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/kdebug.asm b/l4-x86/l4-y-0/kernel/kdebug.asm new file mode 100644 index 0000000..ffea153 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/kdebug.asm @@ -0,0 +1,5671 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 07,10,99, 77 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 07.10.99 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_proot +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86,pIII + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar+KR ; 0 + dd outstring+KR ; 1 + dd outcstring+KR ; 2 + dd clear_page+KR ; 3 + dd cursor+KR ; 4 + + dd outhex32+KR ; 5 + dd outhex20+KR ; 6 + dd outhex16+KR ; 7 + dd outhex12+KR ; 8 + dd outhex8+KR ; 9 + dd outhex4+KR ; 10 + dd outdec+KR ; 11 + + dd kd_incharety+KR; 12 + dd kd_inchar+KR ; 13 + dd inhex32+KR ; 14 + dd inhex16+KR ; 15 + dd inhex8+KR ; 16 + dd inhex32+KR ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + + ELIFA ebx,PM + sub ebx,KR + FI + + mov ax,ds:[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,ds:[ebx+1] + add ebx,4 + FI + + mov al,ds:[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_proot + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler+KR + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ ss:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ ss:[breakpoint_thread+PM],0 + cmp ss:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp ss:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ ss:[bx_size+PM],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + push ds + push phys_mem + pop ds + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + pop ds + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + push ds + push phys_mem + pop ds + mov eax,[kdebug_esp] + pop ds + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + push ds + push phys_mem + pop ds + cmp ebp,[kdebug_esp] + pop ds + IFZ + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_proot + ELIFZ al,'t' + mov eax,offset task_proot + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword+KR + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir+KR + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault+KR + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov ebx,cr3 ; ensures that kdebug can run even if current + push ebx ; current address space has not sufficient + mov ebx,ss:[kernel_proot] ; memory mapped for kdebug + mov cr3,ebx ; + + mov eax,cr2 + and eax,-pagesize + + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ebx + mov cr3,ebx + pop ds + popad + jmp ss:[page_fault_handler+PM] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc+KR + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop ds + + popad + add esp,4 + jmp ss:[ipc_handler+PM] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor+KR + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,ss:[monitored_exception+PM] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,ss:[monitored_ec_min+PM] + movzx ecx,ss:[monitored_ec_max+PM] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop ds + + popad + + CORB ss:[monitored_exception+PM],8 + IFA ss:[monitored_exception+PM],14 + IFNZ ss:[monitored_exception+PM],17 + add esp,4 + FI + FI + + jmp ss:[monitored_exception_handler+PM] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler+KR + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop ds + + popad + add esp,4 + FI + + jmp ss:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_proot + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__proot edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0 + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov [trace_buffer_in_pointer],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + shr ecx,2 + sub eax,eax + cld + rep stosd + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + mov ecx,event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,event_select_msr + mov eax,ebx + wrmsr + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + IFAE esp,virtual_space_size + call open_trace_buffer + CANDNC + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + FI + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +event_select_msr equ 11h +event_counter0_msr equ 12h +event_counter1_msr equ 13h + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 00011111b +w_stall equ 00011001b +r_stall equ 00011010b +x_stall equ 00011011b +agi_stall equ 00011111b + +bus_util equ 00011000b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + + +set_performance_tracing: + + kd____clear_page + call show_trace_perf_monitoring_mode + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + sub ebx,ebx + IFZ al,'i' + mov ebx,instrs_ex + (instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,rw_miss + (ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,rw_tlb + (ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,r_stall + (w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,agi_stall + (bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,bus_util + (instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,event_select_msr + wrmsr + mov ecx,event_counter0_msr + wrmsr + mov ecx,event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,event_select_msr + wrmsr + FI + + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/kdiopc.asm b/l4-x86/l4-y-0/kernel/kdiopc.asm new file mode 100644 index 0000000..277000a --- /dev/null +++ b/l4-x86/l4-y-0/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86,pIII + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/kernel.asm b/l4-x86/l4-y-0/kernel/kernel.asm new file mode 100644 index 0000000..1b9dc61 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '24.08.99' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-X Nucleus (PIII), Copyright (C) IBM 1997 & University of Karlsruhe 1999',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/ktest.asm b/l4-x86/l4-y-0/kernel/ktest.asm new file mode 100644 index 0000000..df2c9eb --- /dev/null +++ b/l4-x86/l4-y-0/kernel/ktest.asm @@ -0,0 +1,1066 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 02,09,97, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 02.09.97 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for pIII + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' +; +; +; +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; +; mov esi,MB1 +; mov ecx,1024 +; DO +; mov eax,[esi] +; mov eax,[esi+28] +; add esi,32 +; dec ecx +; REPEATNZ +; OD +; +; rdtsc +; sub eax,ebx +; sub eax,12 +; add eax,511 +; shr eax,10 +; push eax +; +; +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; kd____disp <13,10,'RAM cache-line read: '> +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,1000h + ; cmp byte ptr ds:[ebx],0 + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 1' + ; + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,MB16 + ; and ebx,-pagesize + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 2' + ; + + + + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma1_task +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + ipc_syscall + ;; int ipc + test al,al + EXITNZ long + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + ipc_syscall + ;; int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + ipc_syscall + ;; int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + ; mov edx,ecx + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + ipc_syscall + ;; int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + mov eax,3 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + ;------------------- for translate test only: + ; or byte ptr ds:[MB4],0 + ;---------------------------------------- + + clign 16 + DO + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + ipc_syscall + ;; int ipc + test al,al + EXITNZ long + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + ipc_syscall + ;; int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + ipc_syscall + ;; int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + ipc_syscall + ;; int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count mem2pipe,cnt_event,bank_conf,cnt_event +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 +; P_count r_stall,cnt_event_PL3,w_stall,cnt_event_PL3 + rdtsc + push eax + + clign 16 + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/memctr.asm b/l4-x86/l4-y-0/kernel/memctr.asm new file mode 100644 index 0000000..87f5abb --- /dev/null +++ b/l4-x86/l4-y-0/kernel/memctr.asm @@ -0,0 +1,519 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + load__proot ebx,<((sigma0_task AND mask task_no) SHR task_no)> + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/pagctr.asm b/l4-x86/l4-y-0/kernel/pagctr.asm new file mode 100644 index 0000000..a42453b --- /dev/null +++ b/l4-x86/l4-y-0/kernel/pagctr.asm @@ -0,0 +1,1203 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 21,09,99, 117 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 21.09.99 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + bt ds:[pre_paging_cpu_feature_flags],global_pages_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_global_pages_bit + mov cr4,eax + FI + + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_proot + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + mov [edi+4],ecx + add edi,8 + cmp edi,offset proot_end_marker + REPEATB + OD + dec ecx + mov [edi],ecx + mov [edi+4],ecx + + + mov ds:[kernel_proot],edx + mov ds:[kernel_proot+4],edx + mov ds:[empty_proot],ebx + mov ds:[empty_proot+4],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov al,cl + or al,page_user_permit ; due to sysexit !!! + IFAE esi,begin_of_shared_space + CANDB esi,end_of_shared_space + or eax,global_page + FI + mov [ebx],eax + + and eax,-pagesize + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + or al,page_user_permit ; due to sysexit !!! + IFAE esi,begin_of_shared_space + CANDB esi,end_of_shared_space + or eax,global_page + FI + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit+page_user_permit ; user_permit due to sysexit !!! + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + or edx,page_present+page_write_permit+page_user_permit+global_page + mov [ecx],edx ; user_permit due to sysexit !!! + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/pagfault.asm b/l4-x86/l4-y-0/kernel/pagfault.asm new file mode 100644 index 0000000..725fc69 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/pagfault.asm @@ -0,0 +1,753 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 11,03,99, 9163, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86,pIII + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler+KR + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_cs+4],kernel_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + IFNZ [ebp+fine_state],locked_running + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + push 2 ; --- sysenter + push kernel_exec + push offset ipcret+KR + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + call push_ipc_state + + IFNZ + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + test__page_present edx + CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin + CANDBE eax,offset ipc_critical_region_end + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + mov ah,byte ptr ds:[gdt+(linear_space AND -8)+7] + mov al,byte ptr ds:[gdt+(linear_space AND -8)+4] + shl eax,16 + xor eax,edx + shr eax,22 + mov cl,ch + shr eax,cl + + mov esi,ebp + IFNZ + mov esi,[ebp+com_partner] + FI + lno___task esi,esi + load__proot esi,esi + add esi,PM + + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + mov ebp,edi + pop esi + REPEAT + OD + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__proot eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/pagmap.asm b/l4-x86/l4-y-0/kernel/pagmap.asm new file mode 100644 index 0000000..193c9ab --- /dev/null +++ b/l4-x86/l4-y-0/kernel/pagmap.asm @@ -0,0 +1,1889 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 20,09,99, 44 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.09.99 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86,pIII + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+KR + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_+KR + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+KR + jmp short do_fpage + FI + push offset unmap_write_page+KR + jmp short do_fpage + FI + + test ch,page_write_permit + IFNZ + push offset flush_page+KR + jmp short do_fpage + FI + push offset flush_write_page+KR + jmp short do_fpage + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page+KR + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IFAE , + lno___task ebp,esp + load__proot ebp,ebp + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,ebx + mov bl,[ebx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + xc z,unmap_in_own_address_space + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + ; xchg ebp,[esp] + ; mov byte ptr [ebp+tlb_flush_indicator],2 + ; xchg ebp,[esp] + + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + + + mov ebx,[eax].pte_ptr + cmp ebx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp ebx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + + + +; xchg ebp,[esp] +; mov byte ptr [ebp+tlb_flush_indicator],2 +; xchg ebp,[esp] +; xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + lno___task edx,ebp + load__proot edx,edx + add edx,PM + + mov ecx,cr3 + IFAE , + lno___task ecx,esp + load__proot ecx,ecx + FI + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+KR + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-0/kernel/proj.err b/l4-x86/l4-y-0/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-y-0/kernel/sgmctr.asm b/l4-x86/l4-y-0/kernel/sgmctr.asm new file mode 100644 index 0000000..125511f --- /dev/null +++ b/l4-x86/l4-y-0/kernel/sgmctr.asm @@ -0,0 +1,265 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 15.09.99 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include kpage.inc +.list + + +ok_for pIII + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS phys_mem_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6+KR,kernel_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + add ds:[logical_info_page].kdebug_exception,KR + add dword ptr ss:[esp],KR + + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + IF KR EQ 0 + descriptor xr32, dpl0, PM, + ELSE + descriptor xr32, dpl0, 0, ; 08 : kernel_exec + ENDIF + descriptor rw32, dpl0, 0, ; 10 : linear_kernel_space + + descriptor rw32, dpl3, 0, user_space_size ; 18 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 20 : linear space + + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-y-0/kernel/sigma0.asm b/l4-x86/l4-y-0/kernel/sigma0.asm new file mode 100644 index 0000000..7c1a0e0 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/sigma0.asm @@ -0,0 +1,769 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-y-0/kernel/start.asm b/l4-x86/l4-y-0/kernel/start.asm new file mode 100644 index 0000000..faeea07 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/start.asm @@ -0,0 +1,354 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86,pIII + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/startpc.asm b/l4-x86/l4-y-0/kernel/startpc.asm new file mode 100644 index 0000000..dfea546 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/startpc.asm @@ -0,0 +1,1288 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure+KR + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher+KR + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int+KR + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + inrtc rtc_seconds + mov ah,al + DO + inrtc rtc_seconds + cmp ah,al + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-y-0/kernel/tables.asm b/l4-x86/l4-y-0/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/tcbman.asm b/l4-x86/l4-y-0/kernel/tcbman.asm new file mode 100644 index 0000000..b39d627 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/tcbman.asm @@ -0,0 +1,732 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 16,03,99, 9141 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + extrn sigma_1_installed:byte + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for pIII + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc+KR + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + cmp ebx,-1 + IFNZ + xchg ebx,[ebp+int_preempter] + ELSE_ + mov ebx,[ebp+int_preempter] + FI + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret+KR + + mov dword ptr [esi+4],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; FI + mov [ebp+pager],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + ELSE_ + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret+KR + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/x.asm b/l4-x86/l4-y-0/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernel/y.asm b/l4-x86/l4-y-0/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-y-0/kernel/yoonseva.asm b/l4-x86/l4-y-0/kernel/yoonseva.asm new file mode 100644 index 0000000..ef1ed69 --- /dev/null +++ b/l4-x86/l4-y-0/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),kernel_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/adrspac5.inc b/l4-x86/l4-y-0/kernifc/adrspac5.inc new file mode 100644 index 0000000..0f8686b --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/adrspac5.inc @@ -0,0 +1,208 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ( 64*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ( 88*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + +begin_of_shared_space equ (offset small_virtual_spaces) +end_of_shared_space equ (offset kernel_resident_tables+kernel_resident_tab_size) + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00B63000h-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd tasks*dwords_per_task_proot dup (?) ; | + proot_end_marker dd dwords_per_task_proot dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd 0,0 + kernel_proot dd 0,0 + sigma0_proot dd 0,0 + +special_proots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) + + +kernel_relocation equ PM + +KR equ kernel_relocation diff --git a/l4-x86/l4-y-0/kernifc/adrspace.inc b/l4-x86/l4-y-0/kernifc/adrspace.inc new file mode 100644 index 0000000..ac74968 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ pIII + +subtitle L4/PIII Version X + +kernel_type = pIII + +kernel_char = '6' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-y-0/kernifc/apic.inc b/l4-x86/l4-y-0/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/contents b/l4-x86/l4-y-0/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/cpucb.inc b/l4-x86/l4-y-0/kernifc/cpucb.inc new file mode 100644 index 0000000..7b90165 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/cpucb.inc @@ -0,0 +1,7 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) OR (kernel_type EQ pIII) + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/l4-y-0/kernifc/cpucb5.inc b/l4-x86/l4-y-0/kernifc/cpucb5.inc new file mode 100644 index 0000000..aa375be --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/cpucb5.inc @@ -0,0 +1,299 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + +;---------------------------------------------------------------------------- +; +; machine specific registers +; +;---------------------------------------------------------------------------- + + +sysenter_cs_msr equ 174h +sysenter_esp_msr equ 175h +sysenter_eip_msr equ 176h + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +sysenter_present_bit equ 11 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y-0/kernifc/intrifc.inc b/l4-x86/l4-y-0/kernifc/intrifc.inc new file mode 100644 index 0000000..c9101d5 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/intrifc.inc @@ -0,0 +1,323 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/kpage.inc b/l4-x86/l4-y-0/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-y-0/kernifc/l4const.inc b/l4-x86/l4-y-0/kernifc/l4const.inc new file mode 100644 index 0000000..3d6f3c7 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/l4const.inc @@ -0,0 +1,95 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +kernel_exec equ 0008h +linear_kernel_space equ 0010h + +linear_space equ (0018h+3) +linear_space_exec equ (0020h+3) + +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/l4kd.inc b/l4-x86/l4-y-0/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-y-0/kernifc/l4pre.inc b/l4-x86/l4-y-0/kernifc/l4pre.inc new file mode 100644 index 0000000..244ac38 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/l4pre.inc @@ -0,0 +1,887 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxhl equ ax +ebxhl equ bx +ecxhl equ cx +edxhl equ dx +esihl equ si +edihl equ di +ebphl equ bp +eaxl equ al +ebxl equ bl +ecxl equ cl +edxl equ dl +eaxh equ ah +ebxh equ bh +ecxh equ ch +edxh equ dh +axl equ al +bxl equ bl +cxl equ cl +dxl equ dl +axh equ ah +bxh equ bh +cxh equ ch +dxh equ dh + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + +clign macro alignment,off + +ifb +aax=($-modstart) AND (alignment-1) +else +aax=($-modstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +klign macro alignment,off + +ifb +aax=($-kmodstart) AND (alignment-1) +else +aax=($-kmodstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + +sysenter macro +db 0Fh,34h +endm + + +sysexit macro +db 0Fh,35h +endm + + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-y-0/kernifc/lbmac.inc b/l4-x86/l4-y-0/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-y-0/kernifc/pagcb.inc b/l4-x86/l4-y-0/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-y-0/kernifc/pagconst.inc b/l4-x86/l4-y-0/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-y-0/kernifc/pagmac.inc b/l4-x86/l4-y-0/kernifc/pagmac.inc new file mode 100644 index 0000000..bcb4b50 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/pagmac.inc @@ -0,0 +1,123 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +x86_proot struc + + switch_ptr dd 0 + proot_ptr dd 0 + +x86_proot ends + +x86_prootx struc + + dd 0 + small_as db 0 + db 0,0,0 + +x86_prootx ends + + +load__proot macro reg,task_no + + mov reg,ds:[(task_no*8)+task_proot+4] + IFIDN , + mov al,0 + ELSEIFIDN , + mov bl,0 + ELSEIFIDN , + mov cl,0 + ELSEIFIDN , + mov dl,0 + ELSE + and reg,0FFFFFF00h + ENDIF + endm + + +store_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + mov ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + +store_inactive_proot macro reg,task_no + + mov ds:[(task_no*8)+task_proot],reg + mov ds:[(task_no*8)+task_proot+4],0 + endm + + +chnge_proot macro reg,task_no + + test byte ptr ds:[(task_no*8)+task_proot+3],80h + IFZ + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot].proot_ptr,reg + endm + + + diff --git a/l4-x86/l4-y-0/kernifc/perfmon.inc b/l4-x86/l4-y-0/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-y-0/kernifc/pnodes.inc b/l4-x86/l4-y-0/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-y-0/kernifc/proj.err b/l4-x86/l4-y-0/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-y-0/kernifc/schedcb.inc b/l4-x86/l4-y-0/kernifc/schedcb.inc new file mode 100644 index 0000000..8f80035 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-y-0/kernifc/schedcb2.inc b/l4-x86/l4-y-0/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-y-0/kernifc/small-as.inc b/l4-x86/l4-y-0/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-y-0/kernifc/tcb.inc b/l4-x86/l4-y-0/kernifc/tcb.inc new file mode 100644 index 0000000..5579288 --- /dev/null +++ b/l4-x86/l4-y-0/kernifc/tcb.inc @@ -0,0 +1,275 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + pager dd 0 + dd 0 + + com_partner dd 0 + waddr dd 0 + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + + + myself dd 0 + dd 0 + waiting_for dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + ext_preempter dd 0 + dd 0 + int_preempter dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:4,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_proot/(dwords_per_task_proot*4) GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_proot)/(dwords_per_task_proot*4) - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-y-0/make/l4.rsp b/l4-x86/l4-y-0/make/l4.rsp new file mode 100644 index 0000000..4ceee3c --- /dev/null +++ b/l4-x86/l4-y-0/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-y-0/make/make-l4 b/l4-x86/l4-y-0/make/make-l4 new file mode 100644 index 0000000..b19c083 --- /dev/null +++ b/l4-x86/l4-y-0/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-y\kernel\;\liedtke\l4-y\kernifc\;\liedtke\l4-y\userifc\} +a=d:\liedtke\l4-y\PIII^\ +all_includes_PIII= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_PIII) $(p)adrsman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII adrsman asm + +$(a)cpuctr.obj : $(all_includes_PIII) $(p)cpuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII cpuctr asm + +$(a)dispatch.obj : $(all_includes_PIII) $(p)dispatch.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII dispatch asm + +$(a)emuctr.obj : $(all_includes_PIII) $(p)emuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII emuctr asm + +$(a)intctr.obj : $(all_includes_PIII) $(p)intctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII intctr asm + +$(a)ipcman.obj : $(all_includes_PIII) $(p)ipcman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ipcman asm + +$(a)kdebug.obj : $(all_includes_PIII) $(p)kdebug.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdebug asm + +$(a)kdiopc.obj : $(all_includes_PIII) $(p)kdiopc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kernel asm + +$(a)ktest.obj : $(all_includes_PIII) $(p)ktest.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ktest asm + +$(a)memctr.obj : $(all_includes_PIII) $(p)memctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII memctr asm + +$(a)pagctr.obj : $(all_includes_PIII) $(p)pagctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagctr asm + +$(a)pagfault.obj : $(all_includes_PIII) $(p)pagfault.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagfault asm + +$(a)pagmap.obj : $(all_includes_PIII) $(p)pagmap.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagmap asm + +$(a)sgmctr.obj : $(all_includes_PIII) $(p)sgmctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sgmctr asm + +$(a)sigma0.obj : $(all_includes_PIII) $(p)sigma0.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sigma0 asm + +$(a)start.obj : $(all_includes_PIII) $(p)start.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII start asm + +$(a)startpc.obj : $(all_includes_PIII) $(p)startpc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII startpc asm + +$(a)tcbman.obj : $(all_includes_PIII) $(p)tcbman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII tcbman asm + +$(a)yoonseva.obj : $(all_includes_PIII) $(p)yoonseva.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-y\PIII + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_PIII) $(p)boot.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-y\PIII + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-0/make/ml-piii.bat b/l4-x86/l4-y-0/make/ml-piii.bat new file mode 100755 index 0000000..2eff3bb --- /dev/null +++ b/l4-x86/l4-y-0/make/ml-piii.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=pIII /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-y-0/make/proj.err b/l4-x86/l4-y-0/make/proj.err new file mode 100644 index 0000000..5ff5cc4 --- /dev/null +++ b/l4-x86/l4-y-0/make/proj.err @@ -0,0 +1,11 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\cpuctr.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-y-0/userifc/contents b/l4-x86/l4-y-0/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-y-0/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-0/userifc/msg.inc b/l4-x86/l4-y-0/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-y-0/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-y-0/userifc/scmac.inc b/l4-x86/l4-y-0/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-y-0/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-y-0/userifc/syscalls.inc b/l4-x86/l4-y-0/userifc/syscalls.inc new file mode 100644 index 0000000..009a5ce --- /dev/null +++ b/l4-x86/l4-y-0/userifc/syscalls.inc @@ -0,0 +1,47 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 + + +ipc_syscall macro + + push ecx + push edx + push ebx + push eax + + mov eax,3246h + + push linear_space_exec + push $+5+5+2+2 + + mov edx,$+5+2+2 + mov ecx,esp + + sysenter + + ;;add esp,2*4 + add esp,6*4 + endm \ No newline at end of file diff --git a/l4-x86/l4-y-0/userifc/uid.inc b/l4-x86/l4-y-0/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-y-0/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/compiler.h b/l4-x86/l4-y-new-segs/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/new/idt.h b/l4-x86/l4-y-new-segs/c-bind/new/idt.h new file mode 100644 index 0000000..fefc4ba --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/ipc-trent.c b/l4-x86/l4-y-new-segs/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/ipc.h b/l4-x86/l4-y-new-segs/c-bind/new/ipc.h new file mode 100644 index 0000000..1b83d4c --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/new/kdebug.h b/l4-x86/l4-y-new-segs/c-bind/new/kdebug.h new file mode 100644 index 0000000..580951e --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/new/kernel.h b/l4-x86/l4-y-new-segs/c-bind/new/kernel.h new file mode 100644 index 0000000..f56ece6 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/new/syscalls.h b/l4-x86/l4-y-new-segs/c-bind/new/syscalls.h new file mode 100644 index 0000000..8bdbbde --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/test.c b/l4-x86/l4-y-new-segs/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/types.h b/l4-x86/l4-y-new-segs/c-bind/new/types.h new file mode 100644 index 0000000..d5c349a --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-compiler.h b/l4-x86/l4-y-new-segs/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-idt.h b/l4-x86/l4-y-new-segs/c-bind/new/x-idt.h new file mode 100644 index 0000000..2e44256 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-ipc.h b/l4-x86/l4-y-new-segs/c-bind/new/x-ipc.h new file mode 100644 index 0000000..c8c96e0 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-kdebug.h b/l4-x86/l4-y-new-segs/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..2f8300c --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-kernel.h b/l4-x86/l4-y-new-segs/c-bind/new/x-kernel.h new file mode 100644 index 0000000..506ac56 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-lid.c b/l4-x86/l4-y-new-segs/c-bind/new/x-lid.c new file mode 100644 index 0000000..99a8534 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-syscalls.h b/l4-x86/l4-y-new-segs/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..c01da48 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/new/x-types.h b/l4-x86/l4-y-new-segs/c-bind/new/x-types.h new file mode 100644 index 0000000..a3bd00f --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/compiler.h b/l4-x86/l4-y-new-segs/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/idt.h b/l4-x86/l4-y-new-segs/c-bind/orig/idt.h new file mode 100644 index 0000000..fefc4ba --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/ipc-trent.c b/l4-x86/l4-y-new-segs/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/ipc.h b/l4-x86/l4-y-new-segs/c-bind/orig/ipc.h new file mode 100644 index 0000000..1b83d4c --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/kdebug.h b/l4-x86/l4-y-new-segs/c-bind/orig/kdebug.h new file mode 100644 index 0000000..580951e --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/kernel.h b/l4-x86/l4-y-new-segs/c-bind/orig/kernel.h new file mode 100644 index 0000000..f56ece6 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/syscalls.h b/l4-x86/l4-y-new-segs/c-bind/orig/syscalls.h new file mode 100644 index 0000000..8bdbbde --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/orig/types.h b/l4-x86/l4-y-new-segs/c-bind/orig/types.h new file mode 100644 index 0000000..d5c349a --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/compiler.h b/l4-x86/l4-y-new-segs/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/idl.m4 b/l4-x86/l4-y-new-segs/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/idt.h b/l4-x86/l4-y-new-segs/c-bind/provisional/idt.h new file mode 100644 index 0000000..fefc4ba --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/ipc-trent.c b/l4-x86/l4-y-new-segs/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/ipc.h b/l4-x86/l4-y-new-segs/c-bind/provisional/ipc.h new file mode 100644 index 0000000..e5641fc --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/kdebug.h b/l4-x86/l4-y-new-segs/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..580951e --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/kernel.h b/l4-x86/l4-y-new-segs/c-bind/provisional/kernel.h new file mode 100644 index 0000000..f56ece6 --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/syscalls.h b/l4-x86/l4-y-new-segs/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..8bdbbde --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-new-segs/c-bind/provisional/types.h b/l4-x86/l4-y-new-segs/c-bind/provisional/types.h new file mode 100644 index 0000000..d5c349a --- /dev/null +++ b/l4-x86/l4-y-new-segs/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:51 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-new-segs/kernel/adrsman.asm b/l4-x86/l4-y-new-segs/kernel/adrsman.asm new file mode 100644 index 0000000..02b9eea --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/adrsman.asm @@ -0,0 +1,1053 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 10,04,00, 9026 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.10.00 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public create_kernel_including_task + public set_address_space_data_for_all_threads + public set_proot_for_all_threads + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86,pIII + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+KR + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + mov eax,[ebp+thread_proot] ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + sub edi,edi ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + test edi,edi ; + IFZ ; + mov edi,[ebp+thread_proot] + call detach_associated_small_space + FI ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + ; + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,[(ecx*4)+task_root] + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_root eax,ebx + + add esp,3*4 + mov ds,[ebp+thread_seg] + mov es,[ebp+thread_seg] + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_root esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax + lea___tcb ebp,eax ; + + mov edi,[edi*4+task_root] + sub edi,ds:[empty_proot] + CORC + IFAE edi,KB4 + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + lno___task ecx,ebp + store_root eax,ecx + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + FI + + ret + + + + icod ends + + + + + + + +;---------------------------------------------------------------------------- +; +; set address space / small space data for all threads +; +;---------------------------------------------------------------------------- +; set address space PRECONDITION: +; +; EAX task pdir +; EBX as base +; ECX as size +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set small space PRECONDITION: +; +; EAX as number +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set proot PRECONDITION: +; +; EAX proot address +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread_proot set in all threads of task +; +; CR2, CPU_CR3, and user_space segements updated if own task +; +;---------------------------------------------------------------------------- + + +set_address_space_data_for_all_threads: + + push edx + push esi + push edi + push ebp + + lno___task edi,ebp + mov ds:[(edi*4)+task_root],eax + + mov edx,flat_seg + + IFA ebx,0,long + + push ebx + + mov edi,ebx + rol edi,8 + bswap edi + and edi,0FF0000FFh + or edi,000C0F300h + + mov edx,ecx + shr edx,log2_pagesize + dec edx + mov esi,edx + and edx,000F0000h + and esi,0000FFFFh + or edi,edx + + mov edx,ebx + shl edx,16 + or esi,edx + + sub ebx,offset small_virtual_spaces + shr ebx,22 + shl ebx,4 + lea edx,[ebx+flat_seg] ; thread's new user space segment + + lea ebx,[ebx+gdt+flat_seg/8*8] + mov ds:[ebx],esi + mov ds:[ebx+4],edi + add edi,0000FB00h-0000F300h + mov ds:[ebx+8],esi + mov ds:[ebx+8+4],edi + + pop ebx + + FI + + and ebp,-(lthreads*sizeof tcb) + mov esi,lthreads + DO + test__page_writable ebp + IFNC + mov [ebp+thread_proot],eax + mov [ebp+as_base],ebx + mov [ebp+as_size],ecx + mov [ebp+thread_seg],edx + + add ebp,sizeof tcb + dec esi + REPEATNZ + ELSE_ + and ebp,-pagesize + add ebp,pagesize + sub esi,pagesize/sizeof tcb + REPEATA + FI + OD + + pop ebp + + mov edi,ebp + xor edi,esp + test edi,mask task_no + IFZ + mov ds:[cpu_cr3],eax + mov cr3,eax + mov es,edx + mov fs,edx + mov gs,edx + FI + + pop edi + pop esi + pop edx + ret + + + + + +set_small_space_data_for_all_threads: + + push ebx + push ecx + mov ebx,eax + + mov eax,[ebp+thread_proot] + mov ecx,virtual_space_size + shl ebx,22 + IFNZ + add ebx,offset small_virtual_spaces + movzx ecx,ds:[small_space_size_div_MB4] + shl ecx,22 + FI + call set_address_space_data_for_all_threads + + mov eax,ebx + pop ecx + pop ebx + ret + + + +set_proot_for_all_threads: + + push ebx + push ecx + + mov ebx,[ebp+as_base] + mov ecx,[ebp+as_size] + call set_address_space_data_for_all_threads + + pop ecx + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; EBP a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + movzx eax,ah + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + CANDNZ eax,ecx + + call detach_associated_small_space + + test eax,eax + IFNZ + movzx ecx,[(eax*2)+small_associated_task] + test ecx,ecx + IFNZ + push ebp + mov ebp,ecx + shl ebp,task_no + lea___tcb ebp,ebp + call detach_small_space + pop ebp + FI + FI + FI + + lno___task ecx,ebp + mov [(eax*2)+small_associated_task],cx + + call set_small_space_data_for_all_threads + + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space / detach associated small space +; +;---------------------------------------------------------------------------- +; detach associated small space PRECONDITION: +; +; EBP tcb of task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; detach small space PRECONDITION: +; +; EBP tcb of task +; ECX small space no +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push eax + push ecx + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + lno___task eax,ebp + call detach_small_space + FI + + pop ecx + pop eax + ret + + + +detach_small_space: + + push eax + + IFZ ax,word ptr [(ecx*2)+small_associated_task] + + mov word ptr [(ecx*2)+small_associated_task],0 + + sub eax,eax + call set_small_space_data_for_all_threads + + call flush_small_pde_block_in_all_pdirs + + mov eax,cr3 + mov cr3,eax + + ELSE_ + ke 'detach_err' + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; make own address space large +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + + + +make_own_address_space_large: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + call set_small_space_data_for_all_threads + + pop ebp + ret + + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + sub edx,edx + DO + cmp edx,tasks + EXITAE + + mov ebp,[(edx*4)+task_root] + inc edx + test ebp,pagesize-1 + REPEATNZ + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + mov eax,[esi+as_base] + test eax,eax + IFNZ + sub eax,offset small_virtual_spaces + shr eax,22 + add al,al + add al,ds:[small_space_size_DIV_MB4] + FI + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/atrace.asm b/l4-x86/l4-y-new-segs/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/boot.asm b/l4-x86/l4-y-new-segs/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-y-new-segs/kernel/contents b/l4-x86/l4-y-new-segs/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/cpuctr.asm b/l4-x86/l4-y-new-segs/kernel/cpuctr.asm new file mode 100644 index 0000000..bd16138 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/cpuctr.asm @@ -0,0 +1,1213 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 10,04,00, 71, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.04.00 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86,pIII + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + push eax + and ah,0Fh + IFZ ah,6 + CANDB al,30h + and al,0Fh + CANDB al,3 + btr edx,sysenter_present_bit + FI + pop eax + IF kernel_relocation EQ 0 + btr edx,sysenter_present_bit + ENDIF + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + shr al,4 + CORA al,p6_family + IFB_ al,p5_family + mov al,other_family + FI + mov ds:[cpu_family],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+KR + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int+KR + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov dword ptr ds:[local_apic+apic_timer_init+KR],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler+KR + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + +switch_context: + + switch_thread con,ebx + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + mov esi,[ebp+thread_proot] + IFNZ esi,ds:[cpu_cr3] + mov ds:[cpu_cr3],esi + mov dword ptr ds:[tlb_invalidated],esi + mov cr3,esi + FI + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBP+ressources] ressources used by actual thread +; +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_con: + push offset switch_thread_con_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_int: + push offset switch_thread_int_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret+KR + + +deallocate_ressources: + + push eax + + test ss:[ebp+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and ss:[ebp+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [ebp+ressources],mask com_used + IFNZ + sub eax,eax + mov ss:[pdir+(com0_base SHR 20)],eax + mov ss:[pdir+(com0_base SHR 20)+4],eax + mov ss:[pdir+(com1_base SHR 20)],eax + mov ss:[pdir+(com1_base SHR 20)+4],eax + + CORNZ ss:[ebx+ebp+as_base],0 + mov eax,ss:[ebx+ebp+thread_proot] + IFZ ss:[cpu_cr3],eax + mov eax,cr3 + mov cr3,eax + FI + + and ss:[ebp+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test ss:[ebp+ressources],mask dr_used+mask in_partner_space + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [ebp+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd+KR + push offset reallocate_ressources_by_ret+KR + + ke 'so_nicht' + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + push eax + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + pop eax + FI + + test al,mask in_partner_space + IFNZ + mov eax,[ebp+com_partner] + mov eax,ss:[eax+thread_proot] + IFNZ eax,ss:[cpu_cr3] + mov ss:[cpu_cr3],eax + mov cr3,eax + FI + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret+KR + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd+KR + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],kernel_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+KR + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/dispatch.asm b/l4-x86/l4-y-new-segs/kernel/dispatch.asm new file mode 100644 index 0000000..6d3eea2 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/dispatch.asm @@ -0,0 +1,1408 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 03,02,00, 9090, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.02.00 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86,pIII + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc+KR + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc+KR + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret+KR + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret+KR + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFBE ah,2*max_small_spaces-1 + push ebp + mov ebp,esi + call attach_small_space + pop ebp + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/emuctr.asm b/l4-x86/l4-y-new-segs/kernel/emuctr.asm new file mode 100644 index 0000000..9c006ce --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/emuctr.asm @@ -0,0 +1,511 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler+KR + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + ;; push user_space + ;; pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + ;; push user_space + ;; pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return+KR + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + align 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/idecode.asm b/l4-x86/l4-y-new-segs/kernel/idecode.asm new file mode 100644 index 0000000..c62cff7 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],kernel_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/intctr.asm b/l4-x86/l4-y-new-segs/kernel/intctr.asm new file mode 100644 index 0000000..1eb1006 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/intctr.asm @@ -0,0 +1,545 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 20,03,00, 59 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.03.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86,pIII + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler+KR + db dpl3 + dd offset initial_debug_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler+KR + db dpl3 + dd offset overflow_handler+KR + db dpl3 + dd offset bound_check_handler+KR + db dpl3 + dd offset invalid_opcode_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler+KR + db dpl0 + dd offset stack_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler+KR + db dpl0 + dd offset alignment_check_handler+KR + db dpl0 + dd offset machine_check_exception+KR + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS user_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,kernel_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + push es + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: user_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + ; mov ecx,user_space ; + ; CORNZ [esp+ip_ds],ecx ; + ; mov edx,es ; + ; IFNZ edx,ecx ; + ; test byte ptr ss:[esp+ip_cs],11b + ; IFNZ ; + ; mov [esp+ip_ds],ecx; do not update DS + ; mov [esp+ip_es],ecx; do not update ES + ; ; if within kernel ! + ; ipost ; (DS might be kernel seg) + ; FI ; + ; FI ; + + + IFBE word ptr ss:[esp+ip_ds],3 + mov ecx,[ebp+thread_seg] + mov [esp+ip_ds],ecx + ipost + FI + IFBE word ptr ss:[esp+ip_es],3 + mov ecx,[ebp+thread_seg] + mov [esp+ip_es],ecx + ipost + FI + + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + CANDNZ [ebp+as_base],0 + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/ipcman.asm b/l4-x86/l4-y-new-segs/kernel/ipcman.asm new file mode 100644 index 0000000..60310fd --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/ipcman.asm @@ -0,0 +1,3584 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 15,04,00, 9580, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 17.04.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb +; public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + public ipcman_sysexit_to_user_instruction + public ipc_exit + + public kernel_ipc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + +ipc_kernel_stack struc + + ipc_edx dd 0 + ipc_ebx dd 0 + ipc_eax dd 0 + ipc_esp dd 0 + +ipc_kernel_stack ends + + +ipc_user_stack struc + + ipc_user_eip dd 0 + ipc_user_cs dd 0 + ipc_user_rcv_descriptor dd 0 + ipc_user_timeouts dd 0 + +ipc_user_stack ends + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + +delete_from_sndq_ss macro + + mov eax,ss:[ebp+sndq_llink].succ + mov ecx,ss:[ebp+sndq_llink].pred + + mov ss:[eax].pred,ecx + mov ss:[ecx].succ,eax + + IFZ eax,ecx + and ss:[eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push es + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+KR + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + switch_space + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+KR + jmp switch_context + FI + FI + + jmp switch_from_intr + + + + align 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + align 16 + + + +;---------------------------------------------------------------------------- +; +; INT 30h IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + kcod ends + + +ipc_sc: + + call kernel_ipc + + mov ebp,esp + and ebp,-sizeof tcb + + mov ds,[ebp+thread_seg] + mov es,[ebp+thread_seg] + + iretd + + + + + + + + kcode + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +; EIP +; CS +; rcv descriptor +; I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + ;kernel_ds + + mov ss:[esp+ipc_eax],offset receive_timeout_ret+KR + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ss:[system_clock_low] + mov ss:[ebp+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test ss:[ebp+list_state],cl + xret nz,long + + linsr_ss ebp,ecx,edi,cl + xret ,long + FI + + + push ds + push linear_kernel_space + pop ds + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebp + pop eax + pop ds + xret ,long + + + align 4 + + + +send_ok_ret: + + sub eax,eax + jmp ipc_exit + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + push linear_kernel_space + pop ds + + add ebx,ebp + xchg ebx,ebp + + test esp,esp + xc nz,ipc_long_ss + + xchg ebx,ebp + sub ebx,ebp + xret ,long + + + +XHEAD ipc_long_ss + + ;kernel_ds + + mov [ebx+fine_state],locked_running + mov [ebp+fine_state],locked_waiting + + and eax,ipc_control_mask + mov esi,[esp+ipc_eax] + + mov edx,[ebx+as_base] + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + + and esi,NOT (deceit+map_msg) + IFNZ + mov edi,[esi+edx+msg_dope] + and edi,0FFFFFF00h + or eax,edi + FI + + + mov edi,[ebp+rcv_descriptor] + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add eax,ipc_cut + and edi,NOT (deceit+map_msg) + + CANDNZ ,,long + + sub eax,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + + lea eax,[(ecx*4)+esi+msg_w3] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_mwords_source,long + + add esi,edx + + lea eax,[(ecx*4)+edi+msg_w3] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_mwords_dest,long + + add edi,[ebp+as_base] + + xc ns,mwords_through_com_space,long + + sti + + mov edx,[edi+msg_size_dope] + shr edx,md_mwords + cmp ecx,edx + xc a,shorten_mwords,long + + mov edx,edi + sub ecx,2 + IFA + push esi + add esi,offset msg_w3 + add edi,offset msg_w3 + + push ds + pop es + cld + rep movsd + pop esi + FI + pop eax + pop ebx + + test eax,mask md_strings + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressources ebx,com_used,in_partner_space + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + + FI + + test eax,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+ipc_ebx+2*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+ipc_ebx+2*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+KR + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + align 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edx + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + +XHEAD address_space_overflow_mwords_source + ke 'mw_source_ovfl' + xret ,long + +XHEAD address_space_overflow_mwords_dest + ke 'mw_dest_overfl' + xret ,long + + + +;XHEAD prepare_small_source +; +; lea edx,[ecx*4+esi] +; +; sass__32 cmp,edx,MB4-offset msg_w3 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; and eax,0FFFFFF00h +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long +; + + + + + + copy_long: + + ;; push es + ;; push ds + ;; pop es + ;; mov eax,ecx + ;; and ecx,-8 + ;; and eax,8-1 + ;; cld + ;; rep movsd + ;; mov ecx,eax + ;; pop es + ;; ret + ;; + ;; DO + ;; mov eax,[esi] + ;; mov ebx,[edi+32] + ;; mov ebx,[esi+4] + ;; mov [edi],eax + ;; mov [edi+4],ebx + ;; mov eax,[esi+8] + ;; mov ebx,[esi+12] + ;; mov [edi+8],eax + ;; mov [edi+12],ebx + ;; mov eax,[esi+16] + ;; mov ebx,[esi+20] + ;; mov [edi+16],eax + ;; mov [edi+20],ebx + ;; mov eax,[esi+24] + ;; mov ebx,[esi+28] + ;; mov [edi+24],eax + ;; mov [edi+28],ebx + ;; add esi,32 + ;; add edi,32 + ;; sub ecx,8 + ;; cmp ecx,8 + ;; REPEATA + ;; OD + ;; ret + + + + +XHEAD mwords_through_com_space + + mov eax,[ebp+thread_proot] + IFNZ eax,ds:[cpu_cr3] + + mark__ressource ebx,com_used + + mov edx,[ebx+thread_proot] + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + + add edi,com0_base + + cmp ds:[tlb_invalidated],0 + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + + ELSE_ + + mark__ressource ebx,in_partner_space + + FI + + xret ,long + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + cmp eax,ecx + cmovb ecx,eax + cmp ebx,ecx + cmovb ecx,ebx + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + lea eax,[esi+ecx] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_str_source,long + add esi,[ebx+as_base] + + lea eax,[edi+ecx] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_str_dest,long + add edi,[ebp+as_base] + + IFNS + mov edx,[ebp+thread_proot] + IFNZ edx,ds:[cpu_cr3] ;; + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + FI + + push ds + pop es + cld + rep movsb ; as fast as movsd + + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + +XHEAD address_space_overflow_str_source + ke 'str_source_ovfl' + xret ,long + +XHEAD address_space_overflow_str_dest + ke 'str_dest_overfl' + xret ,long + + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +;XHEAD prepare_small_string_source +; +; shl eax,16 +; +; lea edx,[esi+ecx] +; sass__32 cmp,edx,MB4 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; mov al,0 +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long + + + + + + + align 16 + + + +fetch_next: + + ;kernel_ds + + push linear_kernel_space + pop ds + add ebx,ebp + xchg ebx,ebp + + mov [ebx+fine_state],locked_waiting + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+KR + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + jmp ipc_exit + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + ke '??' + jmp ipc_exit + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + ke '??' ;REDIR ends -------------------------- + jmp ipc_exit + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,ss:[ebx+ebp+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebp + test edi,mask task_no + EXITZ + + ke 'kernel_ds' + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + ;kernel_ds + + test ebx,ebx + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,ss:[ebp+virtual_sender] + xret z,long + FI + + + mov edi,ss:[ebx+ebp+myself] + DO + test ss:[ebx+ebp+coarse_state],auto_propagating + EXITZ + + add ebx,sizeof tcb + push ebp + add ebp,ebx + test__page_writable ebp + pop ebp + EXITC + + mov dl,ss:[ebx+ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp ss:[ebx+ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,ss:[ebx+ebp+myself] + test al,deceit + IFNZ + mov esi,ss:[ebp+propagatee_tcb] + CANDNZ esi,0 + mov ss:[esi+waiting_for],edi + ELSE_ + mov ss:[ebp+waiting_for],edi + FI + + xret ,long + OD + + ;'kernel_ds' + push linear_kernel_space + pop ds + add ebx,ebp + xchg ebx,ebp + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+KR + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + + + + + + + + +ret_from_poll: + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ss:[ebp+com_partner] + sub ebx,ebp + + mov eax,ss:[esp+ipc_eax] + mov ecx,ss:[ebp+timeouts] + mov esi,ss:[ebp+waiting_for] + + IFZ ss:[ebp+fine_state],locked_running + + mov ss:[ebp+fine_state],running + and ss:[ebx+ebp+fine_state],nclos + or ss:[ebx+ebp+fine_state],closed_wait+nwake + + jmp ipc_restart + + FI + + test ss:[ebp+fine_state],npoll + IFZ + delete_from_sndq_ss + mov [ebp+fine_state],running + FI + + +send_timeout_ret: + + add esp,sizeof ipc_kernel_stack-2*4 + sub eax,eax + mov al,ipc_timeout+ipc_s + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + ;kernel_ds + push linear_kernel_space + pop ds + mov ebx,ebp + + pop edx + pop eax + + mov ebp,[ebx+rcv_descriptor] + + cmp ebp,virtual_space_size + jae w_err + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret+KR + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + push eax + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + jmp ipc_exit + + + + align 16 + + +received_ok_ret: + + popad + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + push ds + push es + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + pop es + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret+KR + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + ke '??' + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll+KR + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +;ipcman_rerun_thread: +; +; pushad +; +; mov al,[ebp+fine_state] +; and al,NOT nwake +; +; CORZ al, +; IFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; IFAE [ebp+waiting_for],intr_sources +; mov [ebp+fine_state],running +; FI +; +; ELIFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; +; ELIFZ al, +; ELIFZ al, +; sub ecx,4 +; mov dword ptr [ecx],offset ret_from_poll+KR +; +; ELIFZ al, +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELIFZ al, +; mov al,[ebp+coarse_state] +; and al,nblocked+ndead +; CANDZ al,ndead +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELSE_ +; ke 'ill_mess_rerun' +; FI +; +; mov [esp+6*4],ecx +; mov [esp+2*4],ebp +; popad +; ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+KR + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],sysenter_present_bit + IFNC + ke '-processor does not support fast system calls' + FI + + mov ecx,sysenter_cs_msr + mov eax,kernel_exec + sub edx,edx + wrmsr + + mov ecx,sysenter_eip_msr + mov eax,offset ipc_sysenter+KR + sub edx,edx + wrmsr + + mov ecx,sysenter_esp_msr + mov eax,offset cpu_esp0 + sub edx,edx + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/kdebug.asm b/l4-x86/l4-y-new-segs/kernel/kdebug.asm new file mode 100644 index 0000000..4ebf655 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/kdebug.asm @@ -0,0 +1,5885 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 11,04,00, 80 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 11.04.00 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_root +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86,pIII + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + +processor_family db 0 + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar+KR ; 0 + dd outstring+KR ; 1 + dd outcstring+KR ; 2 + dd clear_page+KR ; 3 + dd cursor+KR ; 4 + + dd outhex32+KR ; 5 + dd outhex20+KR ; 6 + dd outhex16+KR ; 7 + dd outhex12+KR ; 8 + dd outhex8+KR ; 9 + dd outhex4+KR ; 10 + dd outdec+KR ; 11 + + dd kd_incharety+KR; 12 + dd kd_inchar+KR ; 13 + dd inhex32+KR ; 14 + dd inhex16+KR ; 15 + dd inhex8+KR ; 16 + dd inhex32+KR ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3,long + mov ebx,[ebp+ip_eip] + + IFAE [ebp+ip_cs],flat_seg + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + + mov edi,esp + and edi,-sizeof tcb + mov ds,ss:[edi+thread_seg] + + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + + ELIFA ebx,PM + sub ebx,KR + FI + + mov ax,ds:[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,ds:[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_root + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler+KR + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ ss:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ ss:[breakpoint_thread+PM],0 + cmp ss:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp ss:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ ss:[bx_size+PM],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + mov eax,[esi+waddr] + IFAE eax,offset small_virtual_spaces + kd____disp <6,4,60,' waddr : '> + kd____outhex32 + ELSE_ + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + FI + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + mov eax,[esi+as_base] + test eax,eax + IFNZ + kd____disp <6,0,39, 'smallspace:'> + kd____outhex32 + kd____disp <' size='> + mov eax,[esi+as_size] + shr eax,20 + kd____outdec + kd____disp <'MB'> + FI + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + push ds + push phys_mem + pop ds + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + pop ds + IFZ + mov al,0 + ret + FI + + IFZ esi,ebp + push ds + push phys_mem + pop ds + mov eax,[kdebug_esp] + pop ds + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + push ds + push phys_mem + pop ds + cmp ebp,[kdebug_esp] + pop ds + IFZ + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_root + ELIFZ al,'t' + mov eax,offset task_root + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword+KR + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__root eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir+KR + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_root + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault+KR + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov ebx,cr3 ; ensures that kdebug can run even if current + push ebx ; current address space has not sufficient + mov ebx,ss:[kernel_proot] ; memory mapped for kdebug + mov cr3,ebx ; + mov eax,cr2 + and eax,-pagesize + IFAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip+4] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ebx + mov cr3,ebx + pop es + pop ds + + popad + jmp ss:[page_fault_handler+PM] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc+KR + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + + popad + add esp,4 + jmp ss:[ipc_handler+PM] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor+KR + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,ss:[monitored_exception+PM] + mov ebp,esp + DO + + IFZ al,general_protection + CANDA ss:[ebp+ip_cs],flat_seg + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,ss:[monitored_ec_min+PM] + movzx ecx,ss:[monitored_ec_max+PM] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop es + pop ds + + popad + + CORB ss:[monitored_exception+PM],8 + IFA ss:[monitored_exception+PM],14 + IFNZ ss:[monitored_exception+PM],17 + add esp,4 + FI + FI + + jmp ss:[monitored_exception_handler+PM] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler+KR + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop es + pop ds + + popad + add esp,4 + FI + + jmp ss:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_root + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__root edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0,long + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + mov dword ptr [edi+trace_entry_type],80h + mov dword ptr [edi+trace_entry_string],'-4L ' + mov byte ptr [edi+trace_entry_string],8 + mov dword ptr [edi+trace_entry_string+4],'RATS' + mov dword ptr [edi+trace_entry_string+8],'T' + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + add edi,sizeof trace_buffer_entry + mov [trace_buffer_in_pointer],edi + sub ecx,sizeof trace_buffer_entry + + shr ecx,2 + sub eax,eax + cld + rep stosd + + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ ,,long + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + + mov al,[processor_family+PM] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P5_event_select_msr + mov eax,ebx + wrmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + mov ebx,eax + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P6_event_select0_msr + mov eax,ebx + wrmsr + FI + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov eax,[trace_buffer_in_pointer] + mov ebx,[eax+trace_entry_timestamp] + or ebx,[eax+trace_entry_timestamp+4] + IFZ + sub eax,[trace_buffer_begin] + CANDZ eax,sizeof trace_buffer_entry + ret + FI + + + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + kd____disp <' no trace buffer',13,10> + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer+KR + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer+KR + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + EXITZ + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +P5_event_select_msr equ 11h +P5_event_counter0_msr equ 12h +P5_event_counter1_msr equ 13h + + + +P5_rd_miss equ 000011b +P5_wr_miss equ 000100b +P5_rw_miss equ 101001b +P5_ex_miss equ 001110b + +P5_d_wback equ 000110b + +P5_rw_tlb equ 000010b +P5_ex_tlb equ 001101b + +P5_a_stall equ 00011111b +P5_w_stall equ 00011001b +P5_r_stall equ 00011010b +P5_x_stall equ 00011011b +P5_agi_stall equ 00011111b + +P5_bus_util equ 00011000b + +P5_pipline_flush equ 010101b + +P5_non_cache_rd equ 011110b +P5_ncache_refs equ 011110b +P5_locked_bus equ 011100b + +P5_mem2pipe equ 001001b +P5_bank_conf equ 001010b + + +P5_instrs_ex equ 010110b +P5_instrs_ex_V equ 010111b + + + + + + +P6_event_select0_msr equ 186h +P6_event_select1_msr equ 187h +P6_event_counter0_msr equ 0C1h +P6_event_counter1_msr equ 0C2h + + + + +;P6_rd_miss equ +P6_wr_miss equ 46h +P6_rw_miss equ 45h +P6_ex_miss equ 81h + +P6_d_wback equ 47h + +;P6_rw_tlb equ +P6_ex_tlb equ 85h + +P6_stalls equ 0A2h + +;P6_L2_rd_miss equ +P6_L2_wr_miss equ 25h +P6_L2_rw_miss equ 24h +P6_L2_ex_miss equ + +P6_L2_d_wback equ 27h + + + +P6_bus_util equ 62h + + +P6_instrs_ex equ 0C0h + + + + + + + +set_performance_tracing: + + push ds + push linear_kernel_space + pop ds + mov al,ds:[cpu_family] + pop ds + mov [processor_family],al + + IFNZ al,p5_family + CANDNZ al,p6_family + kd____disp <' not supported by this processor',13,10> + sub eax,eax ; Z! + ret + FI + + + kd____clear_page + call show_trace_perf_monitoring_mode + + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + + mov al,[processor_family] + IFZ al,p5_family,long + + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + ELIFZ al,p6_family,long + + kd____disp <'1 : L1 Dcache Misses (rd/wback)',13,10> + kd____disp <'2 : L2 Cache Misses (rd/wback)',13,10> + kd____disp <'i : Icache/ITLB Misses',13,10> + kd____disp <'I : Instructions/stalls',13,10> + kd____disp <'b : Bus Utilization/Instructions',13,10> + kd____disp <'x : uuee0/uuee1',13,10> + FI + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + mov ah,[processor_family] + IFZ ah,p5_family,long + + sub ebx,ebx + IFZ al,'i' + mov ebx,P5_instrs_ex + (P5_instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,P5_rw_miss + (P5_ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,P5_rw_tlb + (P5_ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,P5_r_stall + (P5_w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,P5_agi_stall + (P5_bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,P5_bus_util + (P5_instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + mov ecx,P5_event_counter0_msr + wrmsr + mov ecx,P5_event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,P5_event_select_msr + wrmsr + FI + + + ELIFZ ah,p6_family,long + + sub ebx,ebx + sub ecx,ecx + + IFZ al,'1' + mov bl,P6_rw_miss + mov cl,P6_d_wback + FI + IFZ al,'2' + mov bl,P6_L2_rw_miss + mov cl,P6_L2_d_wback + FI + IFZ al,'i' + mov bl,P6_ex_miss + mov cl,P6_ex_tlb + FI + IFZ al,'I' + mov bl,P6_instrs_ex + mov cl,P6_stalls + FI + IFZ al,'b' + mov bl,P6_bus_util + mov cl,P6_instrs_ex + FI + IFZ al,'x' + kd____disp <6,11,5,' PerfCnt0: '> + kd____inhex16 + movzx ebx,ax + kd____disp <' PerfCnt1: '> + kd____inhex16 + movzx ecx,ax + FI + + test ebx,ebx + IFNZ + push ecx + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + wrmsr + mov ecx,P6_event_counter1_msr + wrmsr + pop ecx + + bts ebx,22 ; enable counters + + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,10b + ELIFZ al,user_perf_mon + mov al,01b + ELSE_ + mov al,11b + FI + shl eax,16 + or ebx,eax + or ecx,eax + + mov eax,ecx + mov ecx,P6_event_select1_msr + wrmsr + mov eax,ebx + mov ecx,P6_event_select0_msr + wrmsr + FI + + + FI + + + test esp,esp ; NZ ! + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/kdiopc.asm b/l4-x86/l4-y-new-segs/kernel/kdiopc.asm new file mode 100644 index 0000000..277000a --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86,pIII + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/kernel.asm b/l4-x86/l4-y-new-segs/kernel/kernel.asm new file mode 100644 index 0000000..7f0d1e2 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '04.04.00' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-Y Nucleus (PIII), Copyright (C) IBM 1997 & University of Karlsruhe 2000',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/ktest.asm b/l4-x86/l4-y-new-segs/kernel/ktest.asm new file mode 100644 index 0000000..3a37478 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/ktest.asm @@ -0,0 +1,755 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 03,04,00, 16 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.04.00 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86,pIII + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+2*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + +kernel_info_page equ 1000h + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + ipc___syscall + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + ; kd____disp <13,10,10,'PageFault: '> + ; call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,10,'ipc_8 : '> + ke '*start' + call ping_short_1000 + ke '*stop' + + if 0 + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_16 : '> + mov eax,4 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc_128 : '> + mov eax,32 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc_512 : '> + mov eax,128 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc__4K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB4 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB4 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB4 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB4 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,MB2 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_16K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB16 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB16 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB16 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB16 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_64K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB64 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB64 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB64 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB64 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + endif + + call exit_ktest + + + mov eax,2 + cpuid + + ke 'done' + + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + + REPEAT + OD + + + + + + +ping_short_1000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + + mov [counter],1000 + + mov [cycles],0 + + rdtsc + push eax + clign 16 + + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + +display_time_and_cycles: + + sub edx,edx + div ebx + + push eax + + mov ebx,1000000000 + mul ebx + mov ebx,ds:[kernel_info_page].cpu_clock_freq + div ebx + + sub edx,edx + mov ebx,1000 + div ebx + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + sub edx,edx + mov ebx,10 + div ebx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + kd____disp <' us, '> + + pop eax + + IFB_ eax,100000 + kd____disp <' '> + FI + IFB_ eax,10000 + kd____disp <' '> + FI + IFB_ eax,1000 + kd____disp <' '> + FI + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + kd____disp <' cycles'> + + + ret + + + + + + +ping_1000: + + mov [ping_snd_msg+msg_dope],eax + mov [ping_snd_msg+msg_size_dope],eax + mov [ping_rcv_msg+msg_dope],eax + mov [ping_rcv_msg+msg_size_dope],eax + mov [pong_snd_msg+msg_dope],eax + mov [pong_snd_msg+msg_size_dope],eax + mov [pong_rcv_msg+msg_dope],eax + mov [pong_rcv_msg+msg_size_dope],eax + + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + + mov [counter],1000 + + rdtsc + push eax + clign 16 + + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ long + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + + if pong_thread ne sigma1_task + + mov eax,(pong_thread-sigma1_task)/(sizeof tcb) + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + ipc___syscall + REPEAT + OD + + endif + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + ipc___syscall + + + mov eax,-1 + + + DO + clign 16 + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + + + align 16 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + rdtsc + push eax + + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + rdtsc + pop ebx + sub eax,ebx + mov ebx,127 + + call display_time_and_cycles + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/memctr.asm b/l4-x86/l4-y-new-segs/kernel/memctr.asm new file mode 100644 index 0000000..8bf83f6 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/memctr.asm @@ -0,0 +1,515 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + mov ebx,ds:[sigma0_proot] + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/pagctr.asm b/l4-x86/l4-y-new-segs/kernel/pagctr.asm new file mode 100644 index 0000000..7eed1a1 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/pagctr.asm @@ -0,0 +1,1187 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 14,04,00, 516 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 14.04.00 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn kernel_ipc:near + extrn set_proot_for_all_threads:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_root + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + add edi,4 + cmp edi,offset task_root+tasks*4 + REPEATB + OD + + + mov ds:[kernel_proot],edx + mov ds:[empty_proot],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 48 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + + push ebp + mov ebp,edx + call set_proot_for_all_threads + pop ebp + + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman init called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + + call kernel_ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + + call kernel_ipc + + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + + call kernel_ipc + + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/pagfault.asm b/l4-x86/l4-y-new-segs/kernel/pagfault.asm new file mode 100644 index 0000000..5ac47a3 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/pagfault.asm @@ -0,0 +1,844 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 15,04,00, 9565, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 15.04.00 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn kernel_ipc:near + extrn ipc_exit:near + extrn ipcman_sysexit_to_user_instruction:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86,pIII + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler+KR + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_eip+4],PM + xc ae,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + test [ebp+fine_state],nlock + IFNZ + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + call kernel_ipc + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + + test [ebp+ressources],in_partner_space + jnz partner_space_fault + + + call push_ipc_state + + IFNZ + push edx + push ebp + push ds + + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + mov ebp,32*4+map_msg + + call kernel_ipc + + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + ;; test__page_present edx + ;; CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,offset small_virtual_spaces+small_virtual_spaces_size + jb small_space_com_write_fault + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin+KR + CANDBE eax,offset ipc_critical_region_end+KR + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDX faulting virtual address (may be rel to large space) +; +; EAX,EBX,ECX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + + mov cl,ds:[log2_small_space_size_DIV_MB4] + mov ch,cl + + xpdir eax,edx + + mov edi,[ebp+as_base] + xor edi,edx + shr edi,22 + shr edi,cl + + mov cl,32-22 + sub cl,ch + + test edi,edi + IFZ + shl edx,cl + shr edx,cl + mov esi,ebp + ELSE_ + mov esi,[ebp+com_partner] + FI + + mov edi,ds:[cpu_cr3] + lea edi,[(eax*4)+edi+PM] + test byte ptr [edi],page_present + xret nz,long + + + mov esi,[esi+thread_proot] + add esi,PM + + mov eax,edx + shl eax,cl + shr eax,cl + xpdir eax,eax + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS user_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + + mov esi,[ebp+com_partner] ; com partner is tcb address + + mov edi,[ebp+waddr] + + mark__ressource ebp,com_used + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + pop esi + REPEAT + OD + + + + + + +small_space_com_write_fault: + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,[esi+as_base] + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + +;---------------------------------------------------------------------------- +; +; partner-space write fault (msg copy small -> large, in large as +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +partner_space_fault: + + + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__root eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + +.erre KR ge PM + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + IFZ eax,offset ipcman_sysexit_to_user_instruction+KR + + mov [esp+iret_eip+4+4],offset ipc_exit + mov [esp+iret_cs+4+4],kernel_exec + btr [esp+iret_eflags+4+4],i_flag + mov eax,[esp+iret_esp+4+4] + mov [esp+iret_esp+4+4+4],eax + + pop eax + xret ,long + FI + + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/pagmap.asm b/l4-x86/l4-y-new-segs/kernel/pagmap.asm new file mode 100644 index 0000000..c6652f6 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/pagmap.asm @@ -0,0 +1,1964 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 25,03,00, 46 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.03.00 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86,pIII + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+KR + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_+KR + jmp do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage special ext: set/reset PCD bits +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+KR + jmp short do_fpage + FI + push offset unmap_write_page+KR + jmp short do_fpage + FI + + bt ecx,30 + IFNC + test ch,page_write_permit + IFNZ + push offset flush_page+KR + jmp short do_fpage + FI + push offset flush_write_page+KR + jmp short do_fpage + FI + + test ch,page_cache_disable + IFZ + push offset set_page_cacheable+KR + ELSE_ + push offset set_page_uncacheable+KR + FI + jmp short do_fpage + + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page+KR + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,esp + and ebp,-sizeof tcb + + cmp [ebp+as_base],0 + mov ebp,[ebp+thread_proot] + IFZ + mov ebp,cr3 + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + ;; and ebx,[ebp+map_mask] + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + push edx + + mov edx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,edx + mov bl,[edx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize;;;;;;;;0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + pop ebx + xc z,unmap_in_own_address_space + + pop edx + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + test ebx,1 + IFNZ + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + ELSE_ + push edx + mov ebx,edx + and edx,(pagesize-1) AND -4 + shr ebx,log2_pagesize + shl edx,log2_pagesize-2 + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ebx,(pagesize-1) AND -4 + shl ebx,2*log2_pagesize-4 + add edx,ebx + invlpg [edx] + pop edx + FI + + + cmp edx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp edx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + pop ebx + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + + + test ebx,1 + IFZ + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -4 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -4 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + FI + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; set page cacheable/uncacheable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + +set_page_cacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT (page_cache_disable+page_write_through) + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + +set_page_uncacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + or byte ptr [esi],page_cache_disable+page_write_through + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + mov edx,[ebp+thread_proot] + add edx,PM + + mov ecx,esp + and ecx,-sizeof tcb + mov ecx,[ebp+thread_proot] + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+KR + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + mov ecx,ds:[sigma0_proot] + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/proj.err b/l4-x86/l4-y-new-segs/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-y-new-segs/kernel/sgmctr.asm b/l4-x86/l4-y-new-segs/kernel/sgmctr.asm new file mode 100644 index 0000000..b6e124f --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/sgmctr.asm @@ -0,0 +1,270 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 16,04,00, 520 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.04.00 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS kernel_exec +; DS user_space +; ES user_space +; FS user_space +; GS user_space +; SS user_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6+KR,kernel_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + add ds:[logical_info_page].kdebug_exception,KR + add dword ptr ss:[esp],KR + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + IF KR EQ 0 + descriptor xr32, dpl0, PM, + ELSE + descriptor xr32, dpl0, 0, ; 08 : kernel_exec + ENDIF + descriptor rw32, dpl0, 0, ; 10 : linear_kernel_space + + descriptor rw32, dpl3, 0, user_space_size ; 18 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 20 : linear space + + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + +;; descriptor ldtseg, dpl0, offset ldt_space, 2*8 ; 40 : flat ldt + + descriptor rw32, dpl3, 0, user_space_size ; 49 : flat user space + descriptor xr32, dpl3, 0, user_space_size ; 20 : flat user space exec + + +end_of_initial_gdt equ $ + + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-y-new-segs/kernel/sigma0.asm b/l4-x86/l4-y-new-segs/kernel/sigma0.asm new file mode 100644 index 0000000..23b9b8f --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/sigma0.asm @@ -0,0 +1,767 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + ; CORZ al,dedicated_mem + ; CORZ al,ah + ; IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + ; FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-y-new-segs/kernel/start.asm b/l4-x86/l4-y-new-segs/kernel/start.asm new file mode 100644 index 0000000..a202a24 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/start.asm @@ -0,0 +1,357 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86,pIII + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + mov eax,2 + cpuid + + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/startpc.asm b/l4-x86/l4-y-new-segs/kernel/startpc.asm new file mode 100644 index 0000000..0bb7bcd --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/startpc.asm @@ -0,0 +1,1308 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure+KR + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher+KR + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int+KR + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + ; Select status register A from RTC + + mov al,rtc_reg_a + out rtc_address,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + + ; Wait for UIP (update in progress) flag to disappear + + DO + in al,rtc_data + and al,80h + REPEATNZ + OD + + ; Wait for UIP flag to appear again. This indicates + ; that a second has passed + + DO + in al,rtc_data + and al,80h + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-y-new-segs/kernel/tables.asm b/l4-x86/l4-y-new-segs/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/tcbman.asm b/l4-x86/l4-y-new-segs/kernel/tcbman.asm new file mode 100644 index 0000000..f26adf8 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/tcbman.asm @@ -0,0 +1,751 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 10,04,00, 9143 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.04.00 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc+KR + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret+KR + + mov ebx,[ebp+thread_seg] + mov dword ptr [esi+4],ebx + mov dword ptr [esi+8],ebx + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + + mov [ebp+pager],esi + + lno___task esi,ebp + load__root esi,esi + mov [ebp+thread_proot],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + + mov esi,[eax+as_base] + mov [ebp+as_base],esi + mov esi,[eax+as_size] + mov [ebp+as_size],esi + mov esi,[eax+thread_seg] + mov [ebp+thread_seg],esi + + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + + ELSE_ + mov [ebp+as_base],0 + mov [ebp+as_size],virtual_space_size + mov [ebp+thread_seg],flat_seg + + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret+KR + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov eax,[ebp+thread_seg] + mov dword ptr [ebx+ip_ds+4],eax + mov dword ptr [ebx+ip_es+4],eax + add eax,8 + mov dword ptr [ebx+ip_cs+4],eax + + pop eax + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov ecx,[ebp+thread_seg] + mov dword ptr [ebx+ip_ss+4],ecx + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + + + + + + icode + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/x.asm b/l4-x86/l4-y-new-segs/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernel/y.asm b/l4-x86/l4-y-new-segs/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-y-new-segs/kernel/yoonseva.asm b/l4-x86/l4-y-new-segs/kernel/yoonseva.asm new file mode 100644 index 0000000..ef1ed69 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),kernel_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/adrspac6.inc b/l4-x86/l4-y-new-segs/kernifc/adrspac6.inc new file mode 100644 index 0000000..4958212 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/adrspac6.inc @@ -0,0 +1,205 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ((64+64)*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ((88-64)*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + + reserved_space_2_size equ (4*MB-(64+8)*KB+64*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00BF3000h-(max_ptabs*(chapters_per_page+4))-4*KB4-KB256-KB64 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + +;; db 100h-8 dup (?) + gdt dd (64*KB/4) dup (?) +;; db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_root dd tasks dup (?) ; | + xxroot_end_marker dd 1 dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + + dd (kernel_r_tables_size - offset kernel_resident_tables) + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_roots struc + + db offset task_root dup (?) + + empty_proot dd 0 + kernel_proot dd 0 + sigma0_proot dd 0 + +special_roots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) + + + +kernel_relocation equ PM + +KR equ kernel_relocation diff --git a/l4-x86/l4-y-new-segs/kernifc/adrspace.inc b/l4-x86/l4-y-new-segs/kernifc/adrspace.inc new file mode 100644 index 0000000..f04d40a --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ PIII + +subtitle L4/PIII Version Y + +kernel_type = pIII + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac6.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-y-new-segs/kernifc/apic.inc b/l4-x86/l4-y-new-segs/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/contents b/l4-x86/l4-y-new-segs/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/cpucb.inc b/l4-x86/l4-y-new-segs/kernifc/cpucb.inc new file mode 100644 index 0000000..f539fad --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/cpucb.inc @@ -0,0 +1,12 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + IF (kernel_type EQ pIII) + +include cpucb6.inc + + ENDIF + diff --git a/l4-x86/l4-y-new-segs/kernifc/cpucb5.inc b/l4-x86/l4-y-new-segs/kernifc/cpucb5.inc new file mode 100644 index 0000000..ffa596e --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/cpucb5.inc @@ -0,0 +1,293 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y-new-segs/kernifc/cpucb6.inc b/l4-x86/l4-y-new-segs/kernifc/cpucb6.inc new file mode 100644 index 0000000..3241e8f --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/cpucb6.inc @@ -0,0 +1,299 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination tcb +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDX, EDI scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov eax,[ebp+thread_seg] + + IFZ eax,flat_seg + mov edi,[ebp+thread_proot] + CANDNZ edi,ds:[cpu_cr3] + mov ds:[cpu_cr3],edi + mov dword ptr ds:[tlb_invalidated],edi + mov cr3,edi + FI + mov ds,eax + mov es,eax + + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + +;---------------------------------------------------------------------------- +; +; machine specific registers +; +;---------------------------------------------------------------------------- + + +sysenter_cs_msr equ 174h +sysenter_esp_msr equ 175h +sysenter_eip_msr equ 176h + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +sysenter_present_bit equ 11 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y-new-segs/kernifc/intrifc.inc b/l4-x86/l4-y-new-segs/kernifc/intrifc.inc new file mode 100644 index 0000000..57cbb23 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/intrifc.inc @@ -0,0 +1,327 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_es dd 0 + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + push es + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + mov ebp,esp + and ebp,-sizeof tcb + mov sg1,[ebp+thread_seg] + ENDIF + IFNB + mov sg2,[ebp+thread_seg] + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/kpage.inc b/l4-x86/l4-y-new-segs/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-y-new-segs/kernifc/l4const.inc b/l4-x86/l4-y-new-segs/kernifc/l4const.inc new file mode 100644 index 0000000..1fcee11 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/l4const.inc @@ -0,0 +1,108 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +kernel_exec equ 0008h +linear_kernel_space equ 0010h + +;linear_space equ (0018h+3) +;linear_space_exec equ (0020h+3) + +phys_mem equ 0028h + +cpu0_tss equ 0030h + +flat_seg equ (0040h+3) + +max_seg equ sizeof gdt/8-8 + + + + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h + +p5_family equ 5 +p6_family equ 6 + +other_family equ 0 + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/l4kd.inc b/l4-x86/l4-y-new-segs/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-y-new-segs/kernifc/l4pre.inc b/l4-x86/l4-y-new-segs/kernifc/l4pre.inc new file mode 100644 index 0000000..a9736aa --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/l4pre.inc @@ -0,0 +1,818 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + + +cmovx macro cc,d,s +db 0Fh,&cc,0C0h+&d&code*8+&s&code +endm + + +cmovb macro d,s +cmovx 42h,d,s +endm + + +cmovs macro d,s +cmovx 48h,d,s +endm + + + +sysenter macro + db 0Fh,34h + endm + + +sysexit macro + db 0Fh,35h + endm + + + + +clign macro alignment + local xx + jmp short xx + align alignment + xx: +endm + + + + + + + + + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-y-new-segs/kernifc/lbmac.inc b/l4-x86/l4-y-new-segs/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-y-new-segs/kernifc/pagcb.inc b/l4-x86/l4-y-new-segs/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/kernifc/pagconst.inc b/l4-x86/l4-y-new-segs/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-y-new-segs/kernifc/pagmac.inc b/l4-x86/l4-y-new-segs/kernifc/pagmac.inc new file mode 100644 index 0000000..6674bce --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/pagmac.inc @@ -0,0 +1,86 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + + +load__root macro reg,task_no + + mov reg,ds:[(task_no*4)+task_root] + endm + + +store_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + +store_inactive_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + + + + diff --git a/l4-x86/l4-y-new-segs/kernifc/perfmon.inc b/l4-x86/l4-y-new-segs/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-y-new-segs/kernifc/pnodes.inc b/l4-x86/l4-y-new-segs/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-y-new-segs/kernifc/proj.err b/l4-x86/l4-y-new-segs/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-y-new-segs/kernifc/schedcb.inc b/l4-x86/l4-y-new-segs/kernifc/schedcb.inc new file mode 100644 index 0000000..77ee56b --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/schedcb.inc @@ -0,0 +1,470 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +linsr_ss macro tcb,temp,list,listmask + + or ss:[tcb+list_state],listmask + mov temp,tcb + xchg temp,ss:[dispatcher_tcb+list] + mov ss:[tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-y-new-segs/kernifc/schedcb2.inc b/l4-x86/l4-y-new-segs/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-y-new-segs/kernifc/small-as.inc b/l4-x86/l4-y-new-segs/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-y-new-segs/kernifc/tcb.inc b/l4-x86/l4-y-new-segs/kernifc/tcb.inc new file mode 100644 index 0000000..bf32939 --- /dev/null +++ b/l4-x86/l4-y-new-segs/kernifc/tcb.inc @@ -0,0 +1,275 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + com_partner dd 0 + thread_proot dd 0 + + thread_seg dd 0 + dd 0 + as_base dd 0 + as_size dd 0 + + + myself dd 0 + waiting_for dd 0 + waddr dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + pager dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:3,in_partner_space:1,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_root/4 GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_root)/4 - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-y-new-segs/make/l4.rsp b/l4-x86/l4-y-new-segs/make/l4.rsp new file mode 100644 index 0000000..a83dd90 --- /dev/null +++ b/l4-x86/l4-y-new-segs/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-y-new-segs/make/make-l4 b/l4-x86/l4-y-new-segs/make/make-l4 new file mode 100644 index 0000000..42c5d76 --- /dev/null +++ b/l4-x86/l4-y-new-segs/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-y\kernel\;\liedtke\l4-y\kernifc\;\liedtke\l4-y\userifc\} +a=d:\liedtke\l4-y\PIII^\ +all_includes_PIII= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac6.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb6.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_PIII) $(p)adrsman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII adrsman asm + +$(a)cpuctr.obj : $(all_includes_PIII) $(p)cpuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII cpuctr asm + +$(a)dispatch.obj : $(all_includes_PIII) $(p)dispatch.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII dispatch asm + +$(a)emuctr.obj : $(all_includes_PIII) $(p)emuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII emuctr asm + +$(a)intctr.obj : $(all_includes_PIII) $(p)intctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII intctr asm + +$(a)ipcman.obj : $(all_includes_PIII) $(p)ipcman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ipcman asm + +$(a)kdebug.obj : $(all_includes_PIII) $(p)kdebug.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdebug asm + +$(a)kdiopc.obj : $(all_includes_PIII) $(p)kdiopc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kernel asm + +$(a)ktest.obj : $(all_includes_PIII) $(p)ktest.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ktest asm + +$(a)memctr.obj : $(all_includes_PIII) $(p)memctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII memctr asm + +$(a)pagctr.obj : $(all_includes_PIII) $(p)pagctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagctr asm + +$(a)pagfault.obj : $(all_includes_PIII) $(p)pagfault.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagfault asm + +$(a)pagmap.obj : $(all_includes_PIII) $(p)pagmap.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagmap asm + +$(a)sgmctr.obj : $(all_includes_PIII) $(p)sgmctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sgmctr asm + +$(a)sigma0.obj : $(all_includes_PIII) $(p)sigma0.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sigma0 asm + +$(a)start.obj : $(all_includes_PIII) $(p)start.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII start asm + +$(a)startpc.obj : $(all_includes_PIII) $(p)startpc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII startpc asm + +$(a)tcbman.obj : $(all_includes_PIII) $(p)tcbman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII tcbman asm + +$(a)yoonseva.obj : $(all_includes_PIII) $(p)yoonseva.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-y\PIII + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_PIII) $(p)boot.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-y\PIII + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/make/ml-piii.bat b/l4-x86/l4-y-new-segs/make/ml-piii.bat new file mode 100755 index 0000000..2eff3bb --- /dev/null +++ b/l4-x86/l4-y-new-segs/make/ml-piii.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=pIII /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-y-new-segs/make/proj.err b/l4-x86/l4-y-new-segs/make/proj.err new file mode 100644 index 0000000..437bc39 --- /dev/null +++ b/l4-x86/l4-y-new-segs/make/proj.err @@ -0,0 +1,11 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\ipcman.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-y-new-segs/userifc/contents b/l4-x86/l4-y-new-segs/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-y-new-segs/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/userifc/msg.inc b/l4-x86/l4-y-new-segs/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-y-new-segs/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-y-new-segs/userifc/scmac.inc b/l4-x86/l4-y-new-segs/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-y-new-segs/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-y-new-segs/userifc/syscalls.inc b/l4-x86/l4-y-new-segs/userifc/syscalls.inc new file mode 100644 index 0000000..a34e3a8 --- /dev/null +++ b/l4-x86/l4-y-new-segs/userifc/syscalls.inc @@ -0,0 +1,35 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 + + +ipc___syscall macro + push ecx + push ebp + push cs + push offset $+5+2+2 + mov ecx,esp + sysenter + endm diff --git a/l4-x86/l4-y-new-segs/userifc/uid.inc b/l4-x86/l4-y-new-segs/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-y-new-segs/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/compiler.h b/l4-x86/l4-y-still-int30/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/new/idt.h b/l4-x86/l4-y-still-int30/c-bind/new/idt.h new file mode 100644 index 0000000..c123fc2 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/ipc-trent.c b/l4-x86/l4-y-still-int30/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/ipc.h b/l4-x86/l4-y-still-int30/c-bind/new/ipc.h new file mode 100644 index 0000000..4ac1d0d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/new/kdebug.h b/l4-x86/l4-y-still-int30/c-bind/new/kdebug.h new file mode 100644 index 0000000..62dd2d5 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/new/kernel.h b/l4-x86/l4-y-still-int30/c-bind/new/kernel.h new file mode 100644 index 0000000..1453c09 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/new/syscalls.h b/l4-x86/l4-y-still-int30/c-bind/new/syscalls.h new file mode 100644 index 0000000..dde12de --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/test.c b/l4-x86/l4-y-still-int30/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/types.h b/l4-x86/l4-y-still-int30/c-bind/new/types.h new file mode 100644 index 0000000..caa4d84 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-compiler.h b/l4-x86/l4-y-still-int30/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-idt.h b/l4-x86/l4-y-still-int30/c-bind/new/x-idt.h new file mode 100644 index 0000000..d94359e --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-ipc.h b/l4-x86/l4-y-still-int30/c-bind/new/x-ipc.h new file mode 100644 index 0000000..3af3278 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-kdebug.h b/l4-x86/l4-y-still-int30/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..d916efb --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-kernel.h b/l4-x86/l4-y-still-int30/c-bind/new/x-kernel.h new file mode 100644 index 0000000..3ae9846 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-lid.c b/l4-x86/l4-y-still-int30/c-bind/new/x-lid.c new file mode 100644 index 0000000..383cc1b --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-syscalls.h b/l4-x86/l4-y-still-int30/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..a11b855 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/new/x-types.h b/l4-x86/l4-y-still-int30/c-bind/new/x-types.h new file mode 100644 index 0000000..5072703 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/compiler.h b/l4-x86/l4-y-still-int30/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/idt.h b/l4-x86/l4-y-still-int30/c-bind/orig/idt.h new file mode 100644 index 0000000..c123fc2 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/ipc-trent.c b/l4-x86/l4-y-still-int30/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/ipc.h b/l4-x86/l4-y-still-int30/c-bind/orig/ipc.h new file mode 100644 index 0000000..4ac1d0d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/kdebug.h b/l4-x86/l4-y-still-int30/c-bind/orig/kdebug.h new file mode 100644 index 0000000..62dd2d5 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/kernel.h b/l4-x86/l4-y-still-int30/c-bind/orig/kernel.h new file mode 100644 index 0000000..1453c09 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/syscalls.h b/l4-x86/l4-y-still-int30/c-bind/orig/syscalls.h new file mode 100644 index 0000000..dde12de --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/orig/types.h b/l4-x86/l4-y-still-int30/c-bind/orig/types.h new file mode 100644 index 0000000..caa4d84 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/compiler.h b/l4-x86/l4-y-still-int30/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/idl.m4 b/l4-x86/l4-y-still-int30/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/idt.h b/l4-x86/l4-y-still-int30/c-bind/provisional/idt.h new file mode 100644 index 0000000..c123fc2 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/ipc-trent.c b/l4-x86/l4-y-still-int30/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/ipc.h b/l4-x86/l4-y-still-int30/c-bind/provisional/ipc.h new file mode 100644 index 0000000..2cb3375 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/kdebug.h b/l4-x86/l4-y-still-int30/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..62dd2d5 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/kernel.h b/l4-x86/l4-y-still-int30/c-bind/provisional/kernel.h new file mode 100644 index 0000000..1453c09 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/syscalls.h b/l4-x86/l4-y-still-int30/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..dde12de --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y-still-int30/c-bind/provisional/types.h b/l4-x86/l4-y-still-int30/c-bind/provisional/types.h new file mode 100644 index 0000000..caa4d84 --- /dev/null +++ b/l4-x86/l4-y-still-int30/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:53 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y-still-int30/kernel/adrsman.asm b/l4-x86/l4-y-still-int30/kernel/adrsman.asm new file mode 100644 index 0000000..aa0c641 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/adrsman.asm @@ -0,0 +1,1044 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 10,04,00, 9026 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.10.00 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public create_kernel_including_task + public set_address_space_data_for_all_threads + public set_proot_for_all_threads + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86,pIII + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+KR + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + mov eax,[ebp+thread_proot] ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + sub edi,edi ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + test edi,edi ; + IFZ ; + mov edi,[ebp+thread_proot] + call detach_associated_small_space + FI ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + ; + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,[(ecx*4)+task_root] + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_root eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_root esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax + lea___tcb ebp,eax ; + + mov edi,[edi*4+task_root] + sub edi,ds:[empty_proot] + CORC + IFAE edi,KB4 + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + lno___task ecx,ebp + store_root eax,ecx + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + FI + + ret + + + + icod ends + + + + + + + +;---------------------------------------------------------------------------- +; +; set address space / small space data for all threads +; +;---------------------------------------------------------------------------- +; set address space PRECONDITION: +; +; EAX task pdir +; EBX as base +; ECX as size +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set small space PRECONDITION: +; +; EAX as number +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set proot PRECONDITION: +; +; EAX proot address +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread_proot set in all threads of task +; +; CR2, CPU_CR3, and linear_space segements updated if own task +; +;---------------------------------------------------------------------------- + + +set_address_space_data_for_all_threads: + + push edx + push esi + push edi + push ebp + + lno___task edi,ebp + mov ds:[(edi*4)+task_root],eax + + mov edi,ebx + rol edi,8 + bswap edi + and edi,0FF0000FFh + or edi,000C0F300h + + mov edx,ecx + shr edx,log2_pagesize + dec edx + mov esi,edx + and edx,000F0000h + and esi,0000FFFFh + or edi,edx + + mov edx,ebx + shl edx,16 + or esi,edx + + + and ebp,-(lthreads*sizeof tcb) + mov edx,lthreads + DO + test__page_writable ebp + IFNC + mov [ebp+thread_proot],eax + mov [ebp+thread_segment],esi + mov [ebp+thread_segment+4],edi + mov [ebp+as_base],ebx + mov [ebp+as_size],ecx + + add ebp,sizeof tcb + dec edx + REPEATNZ + ELSE_ + and ebp,-pagesize + add ebp,pagesize + sub edx,pagesize/sizeof tcb + REPEATA + FI + OD + + pop ebp + + mov edx,ebp + xor edx,esp + test edx,mask task_no + IFZ + mov ds:[gdt+linear_space/8*8],esi + mov ds:[gdt+linear_space/8*8+4],edi + add edi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8],esi + mov ds:[gdt+linear_space_exec/8*8+4],edi + mov ds:[cpu_cr3],eax + mov cr3,eax + mov edx,linear_space + mov es,edx + mov fs,edx + mov gs,edx + FI + + pop edi + pop esi + pop edx + ret + + + + + +set_small_space_data_for_all_threads: + + push ebx + push ecx + mov ebx,eax + + mov eax,[ebp+thread_proot] + mov ecx,virtual_space_size + shl ebx,22 + IFNZ + add ebx,offset small_virtual_spaces + movzx ecx,ds:[small_space_size_div_MB4] + shl ecx,22 + FI + call set_address_space_data_for_all_threads + + mov eax,ebx + pop ecx + pop ebx + ret + + + +set_proot_for_all_threads: + + push ebx + push ecx + + mov ebx,[ebp+as_base] + mov ecx,[ebp+as_size] + call set_address_space_data_for_all_threads + + pop ecx + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; EBP a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + movzx eax,ah + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + CANDNZ eax,ecx + + call detach_associated_small_space + + test eax,eax + IFNZ + movzx ecx,[(eax*2)+small_associated_task] + test ecx,ecx + IFNZ + push ebp + mov ebp,ecx + shl ebp,task_no + lea___tcb ebp,ebp + call detach_small_space + pop ebp + FI + FI + FI + + lno___task ecx,ebp + mov [(eax*2)+small_associated_task],cx + + call set_small_space_data_for_all_threads + + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space / detach associated small space +; +;---------------------------------------------------------------------------- +; detach associated small space PRECONDITION: +; +; EBP tcb of task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; detach small space PRECONDITION: +; +; EBP tcb of task +; ECX small space no +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push eax + push ecx + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + lno___task eax,ebp + call detach_small_space + FI + + pop ecx + pop eax + ret + + + +detach_small_space: + + push eax + + IFZ ax,word ptr [(ecx*2)+small_associated_task] + + mov word ptr [(ecx*2)+small_associated_task],0 + + sub eax,eax + call set_small_space_data_for_all_threads + + call flush_small_pde_block_in_all_pdirs + + mov eax,cr3 + mov cr3,eax + + ELSE_ + ke 'detach_err' + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; make own address space large +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + + + +make_own_address_space_large: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + call set_small_space_data_for_all_threads + + pop ebp + ret + + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + sub edx,edx + DO + cmp edx,tasks + EXITAE + + mov ebp,[(edx*4)+task_root] + inc edx + test ebp,pagesize-1 + REPEATNZ + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + mov eax,[esi+as_base] + test eax,eax + IFNZ + sub eax,offset small_virtual_spaces + shr eax,22 + add al,al + add al,ds:[small_space_size_DIV_MB4] + FI + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/atrace.asm b/l4-x86/l4-y-still-int30/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/boot.asm b/l4-x86/l4-y-still-int30/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-y-still-int30/kernel/contents b/l4-x86/l4-y-still-int30/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/cpuctr.asm b/l4-x86/l4-y-still-int30/kernel/cpuctr.asm new file mode 100644 index 0000000..a55e399 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/cpuctr.asm @@ -0,0 +1,1223 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 10,04,00, 71, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.04.00 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86,pIII + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + push eax + and ah,0Fh + IFZ ah,6 + CANDB al,30h + and al,0Fh + CANDB al,3 + btr edx,sysenter_present_bit + FI + pop eax + IF kernel_relocation EQ 0 + btr edx,sysenter_present_bit + ENDIF + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + shr al,4 + CORA al,p6_family + IFB_ al,p5_family + mov al,other_family + FI + mov ds:[cpu_family],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+KR + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int+KR + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov dword ptr ds:[local_apic+apic_timer_init+KR],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler+KR + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + +switch_context: + + switch_thread con,ebx + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + mov esi,[ebp+thread_proot] + IFNZ esi,ds:[cpu_cr3] + mov ds:[cpu_cr3],esi + mov dword ptr ds:[tlb_invalidated],esi + mov cr3,esi + FI + + mov esi,[ebp+thread_segment] + mov ds:[gdt+linear_space/8*8],esi + mov ds:[gdt+linear_space_exec/8*8],esi + mov esi,[ebp+thread_segment+4] + mov ds:[gdt+linear_space/8*8+4],esi + add esi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret+KR + + +deallocate_ressources: + + push eax + + test [edi+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + CORNZ [ebp+as_base],0 + mov eax,[ebp+thread_proot] + IFZ ds:[cpu_cr3],eax + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used+mask in_partner_space + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd+KR + push offset reallocate_ressources_by_ret+KR + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + call reallocate_ressources + + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + push eax + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + pop eax + FI + + test al,mask in_partner_space + IFNZ + mov eax,[ebp+com_partner] + mov eax,ss:[eax+thread_proot] + IFNZ eax,ss:[cpu_cr3] + mov ss:[cpu_cr3],eax + mov cr3,eax + FI + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret+KR + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd+KR + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],kernel_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+KR + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/dispatch.asm b/l4-x86/l4-y-still-int30/kernel/dispatch.asm new file mode 100644 index 0000000..6d3eea2 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/dispatch.asm @@ -0,0 +1,1408 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 03,02,00, 9090, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.02.00 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86,pIII + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc+KR + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc+KR + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret+KR + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret+KR + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFBE ah,2*max_small_spaces-1 + push ebp + mov ebp,esi + call attach_small_space + pop ebp + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/emuctr.asm b/l4-x86/l4-y-still-int30/kernel/emuctr.asm new file mode 100644 index 0000000..9ee169a --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/emuctr.asm @@ -0,0 +1,511 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler+KR + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return+KR + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + align 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/idecode.asm b/l4-x86/l4-y-still-int30/kernel/idecode.asm new file mode 100644 index 0000000..c62cff7 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],kernel_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/intctr.asm b/l4-x86/l4-y-still-int30/kernel/intctr.asm new file mode 100644 index 0000000..60746b3 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/intctr.asm @@ -0,0 +1,543 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 20,03,00, 59 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.03.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86,pIII + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler+KR + db dpl3 + dd offset initial_debug_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler+KR + db dpl3 + dd offset overflow_handler+KR + db dpl3 + dd offset bound_check_handler+KR + db dpl3 + dd offset invalid_opcode_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler+KR + db dpl0 + dd offset stack_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler+KR + db dpl0 + dd offset alignment_check_handler+KR + db dpl0 + dd offset machine_check_exception+KR + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,kernel_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + push es + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + ; mov ecx,linear_space ; + ; CORNZ [esp+ip_ds],ecx ; + ; mov edx,es ; + ; IFNZ edx,ecx ; + ; test byte ptr ss:[esp+ip_cs],11b + ; IFNZ ; + ; mov [esp+ip_ds],ecx; do not update DS + ; mov [esp+ip_es],ecx; do not update ES + ; ; if within kernel ! + ; ipost ; (DS might be kernel seg) + ; FI ; + ; FI ; + + + IFBE word ptr ss:[esp+ip_ds],3 + mov [esp+ip_ds],linear_space + ipost + FI + IFBE word ptr ss:[esp+ip_es],3 + mov [esp+ip_es],linear_space + ipost + FI + + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + CANDNZ [ebp+as_base],0 + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/ipcman.asm b/l4-x86/l4-y-still-int30/kernel/ipcman.asm new file mode 100644 index 0000000..344a18c --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/ipcman.asm @@ -0,0 +1,3384 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCmovs, 10,04,00, 9180, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.04.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push es + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+KR + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+KR + jmp switch_context + FI + FI + + jmp switch_from_intr + + + + align 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + align 16 + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + +ipc_sysenter: + + push eax + push ebx + + cmp eax,virtual_space_size-MB4 + jae receive_only + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + mov [ebx+waiting_for],esi + and eax,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + ; + and ebp,mask task_no ; + mov edx,ebx ; + ; + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + mov edx,[edx+ebp+redirection_table] ; + ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + and ebp,mask thread_no + + mov [ebx+mword2],edi + add ebp,offset tcb_space + + mov edi,[ebx+myself] + ;REDIR: and al,(NOT ipc_control_mask)+deceit+map_msg + + mov edx,[ebp+myself] + xor edi,esi + + test edi,mask chief_no + xc nz,to_chief,long + + cmp esi,edx + jnz ipc_dest_not_existent + + test eax,deceit + xc nz,propagate_pre,long + + mov dl,[ebp+fine_state] + + + and dl,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + xc nz,pending_or_auto_propagating,long + FI + + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + + mov edx,[ebx+rcv_descriptor] + mov ch,running + + mov [ebp+fine_state],ch + cmp edx,virtual_space_size + + IF____xc ae,send_only,long + + ELSE__ + + and edx,nclos + mov edi,dword ptr ds:[ebx+fine_state] + shr edi,zpolled+16 + test edi,edx + + jnz fetch_next + + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + +;;;;; switch_thread ipc,edi + mov cl,[edi+ressources] + + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov esi,[edi+myself] + + test eax,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + + +;;;;;;;;;;;; switch_space + + push ecx + + mov ecx,[ebp+thread_segment] + mov ds:[gdt+linear_space/8*8],ecx + mov ds:[gdt+linear_space_exec/8*8],ecx + + mov ecx,[ebp+thread_segment+4] + mov ds:[gdt+linear_space/8*8+4],ecx + add ecx,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ecx + + mov ecx,linear_space + mov ds,ecx + mov es,ecx + + IFS + pop ecx + pop ebp + iretd + FI + +; IFNS + mov ecx,[ebp+thread_proot] + mov ebp,offset cpu_cr3 + + IFNZ dword ptr ss:[ebp],ecx + + mov dword ptr ss:[ebp],ecx + mov dword ptr ss:[ebp+tlb_invalidated-offset cpu_cr3],ecx + mov cr3,ecx + FI +; FI + +; sti + + + pop ecx + pop ebp + iretd + + + + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z + + mov esi,[edi+virtual_sender] + xret + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret+KR + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + mov edi,[esp+iret_esp+3*4] ; must be read from user space, + sub edx,edx + + mov [ebx+propagatee_tcb],edx + mov edi,es:[edi] ; potentially small space + + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + mov [ebx+virtual_sender],edi + + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + test esi,mask task_no + IFZ + lea___tcb esi,edi + + test__page_writable esi + IFNC + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + CANDZ dl,closed_wait + CANDZ [ebx+myself],edi + + mov [ebx+propagatee_tcb],esi + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + xret ,long + FI + + + ;REDIR begin -------------------------------- + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + test edx,mask chief_no ; ; + xret z,long ; + ; + mov edx,[ebx+myself] ; + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; + ; + and ebp,mask task_no ; + mov esi,edi ; + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + pop ebp ; + pop ecx ; + xret ,long ; + OD ; + pop ebp ; + pop ecx ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + ;REDIR ends ----------------------------------- + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret+KR + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + + mov [ebx+fine_state],locked_running + mov [ebp+fine_state],locked_waiting + + and eax,ipc_control_mask + mov esi,[esp+4+4] + + mov edx,[ebx+as_base] + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + + and esi,NOT (deceit+map_msg) + IFNZ + mov edi,[esi+edx+msg_dope] + and edi,0FFFFFF00h + or eax,edi + FI + + + mov edi,[ebp+rcv_descriptor] + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add eax,ipc_cut + and edi,NOT (deceit+map_msg) + + CANDNZ ,,long + + sub eax,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + + lea eax,[(ecx*4)+esi+msg_w3] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_mwords_source,long + + add esi,edx + + lea eax,[(ecx*4)+edi+msg_w3] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_mwords_dest,long + + add edi,[ebp+as_base] + + xc ns,mwords_through_com_space,long + + sti + + mov edx,[edi+msg_size_dope] + shr edx,md_mwords + cmp ecx,edx + xc a,shorten_mwords,long + + mov edx,edi + sub ecx,2 + IFA + push esi + add esi,offset msg_w3 + add edi,offset msg_w3 + + push ds + pop es + cld + rep movsd + pop esi + FI + pop eax + pop ebx + + test eax,mask md_strings + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressources ebx,com_used,in_partner_space + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + + FI + + test eax,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+KR + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + align 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edx + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + +XHEAD address_space_overflow_mwords_source + ke 'mw_source_ovfl' + xret ,long + +XHEAD address_space_overflow_mwords_dest + ke 'mw_dest_overfl' + xret ,long + + + +;XHEAD prepare_small_source +; +; lea edx,[ecx*4+esi] +; +; sass__32 cmp,edx,MB4-offset msg_w3 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; and eax,0FFFFFF00h +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long +; + + + + + + copy_long: + + ;; push es + ;; push ds + ;; pop es + ;; mov eax,ecx + ;; and ecx,-8 + ;; and eax,8-1 + ;; cld + ;; rep movsd + ;; mov ecx,eax + ;; pop es + ;; ret + ;; + ;; DO + ;; mov eax,[esi] + ;; mov ebx,[edi+32] + ;; mov ebx,[esi+4] + ;; mov [edi],eax + ;; mov [edi+4],ebx + ;; mov eax,[esi+8] + ;; mov ebx,[esi+12] + ;; mov [edi+8],eax + ;; mov [edi+12],ebx + ;; mov eax,[esi+16] + ;; mov ebx,[esi+20] + ;; mov [edi+16],eax + ;; mov [edi+20],ebx + ;; mov eax,[esi+24] + ;; mov ebx,[esi+28] + ;; mov [edi+24],eax + ;; mov [edi+28],ebx + ;; add esi,32 + ;; add edi,32 + ;; sub ecx,8 + ;; cmp ecx,8 + ;; REPEATA + ;; OD + ;; ret + + + + +XHEAD mwords_through_com_space + + mov eax,[ebp+thread_proot] + IFNZ eax,ds:[cpu_cr3] + + mark__ressource ebx,com_used + + mov edx,[ebx+thread_proot] + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + + add edi,com0_base + + cmp ds:[tlb_invalidated],0 + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + + ELSE_ + + mark__ressource ebx,in_partner_space + + FI + + xret ,long + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + cmp eax,ecx + cmovb ecx,eax + cmp ebx,ecx + cmovb ecx,ebx + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + lea eax,[esi+ecx] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_str_source,long + add esi,[ebx+as_base] + + lea eax,[edi+ecx] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_str_dest,long + add edi,[ebp+as_base] + + IFNS + mov edx,[ebp+thread_proot] + IFNZ edx,ds:[cpu_cr3] ;; + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + FI + + push ds + pop es + cld + rep movsb ; as fast as movsd + + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + +XHEAD address_space_overflow_str_source + ke 'str_source_ovfl' + xret ,long + +XHEAD address_space_overflow_str_dest + ke 'str_dest_overfl' + xret ,long + + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +;XHEAD prepare_small_string_source +; +; shl eax,16 +; +; lea edx,[esi+ecx] +; sass__32 cmp,edx,MB4 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; mov al,0 +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long + + + + + + + align 16 + + + +fetch_next: + + mov [ebx+fine_state],locked_waiting + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+KR + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+KR + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret+KR + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret+KR + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll+KR + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret+KR + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret+KR + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll+KR + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret+KR + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret+KR + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+KR + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],sysenter_present_bit + IFNC + ke '-processor does not support fast system calls' + FI + + mov ecx,sysenter_cs_msr + mov eax,kernel_exec + sub edx,edx + wrmsr + + mov ecx,sysenter_eip_msr + mov eax,offset ipc_sysenter+KR + sub edx,edx + wrmsr + + mov ecx,sysenter_esp_msr + mov eax,ds:[cpu_esp0] + sub edx,edx + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/kdebug.asm b/l4-x86/l4-y-still-int30/kernel/kdebug.asm new file mode 100644 index 0000000..a52da1e --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/kdebug.asm @@ -0,0 +1,5883 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 11,04,00, 80 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 11.04.00 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_root +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86,pIII + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + +processor_family db 0 + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar+KR ; 0 + dd outstring+KR ; 1 + dd outcstring+KR ; 2 + dd clear_page+KR ; 3 + dd cursor+KR ; 4 + + dd outhex32+KR ; 5 + dd outhex20+KR ; 6 + dd outhex16+KR ; 7 + dd outhex12+KR ; 8 + dd outhex8+KR ; 9 + dd outhex4+KR ; 10 + dd outdec+KR ; 11 + + dd kd_incharety+KR; 12 + dd kd_inchar+KR ; 13 + dd inhex32+KR ; 14 + dd inhex16+KR ; 15 + dd inhex8+KR ; 16 + dd inhex32+KR ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + + ELIFA ebx,PM + sub ebx,KR + FI + + mov ax,ds:[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,ds:[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_root + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler+KR + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ ss:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ ss:[breakpoint_thread+PM],0 + cmp ss:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp ss:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ ss:[bx_size+PM],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + mov eax,[esi+waddr] + IFAE eax,offset small_virtual_spaces + kd____disp <6,4,60,' waddr : '> + kd____outhex32 + ELSE_ + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + FI + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + mov eax,[esi+as_base] + test eax,eax + IFNZ + kd____disp <6,0,39, 'smallspace:'> + kd____outhex32 + kd____disp <' size='> + mov eax,[esi+as_size] + shr eax,20 + kd____outdec + kd____disp <'MB'> + FI + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + push ds + push phys_mem + pop ds + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + pop ds + IFZ + mov al,0 + ret + FI + + IFZ esi,ebp + push ds + push phys_mem + pop ds + mov eax,[kdebug_esp] + pop ds + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + push ds + push phys_mem + pop ds + cmp ebp,[kdebug_esp] + pop ds + IFZ + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_root + ELIFZ al,'t' + mov eax,offset task_root + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword+KR + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__root eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir+KR + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_root + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault+KR + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov ebx,cr3 ; ensures that kdebug can run even if current + push ebx ; current address space has not sufficient + mov ebx,ss:[kernel_proot] ; memory mapped for kdebug + mov cr3,ebx ; + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ebx + mov cr3,ebx + pop es + pop ds + + popad + jmp ss:[page_fault_handler+PM] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc+KR + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + + popad + add esp,4 + jmp ss:[ipc_handler+PM] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor+KR + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,ss:[monitored_exception+PM] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,ss:[monitored_ec_min+PM] + movzx ecx,ss:[monitored_ec_max+PM] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop es + pop ds + + popad + + CORB ss:[monitored_exception+PM],8 + IFA ss:[monitored_exception+PM],14 + IFNZ ss:[monitored_exception+PM],17 + add esp,4 + FI + FI + + jmp ss:[monitored_exception_handler+PM] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler+KR + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop es + pop ds + + popad + add esp,4 + FI + + jmp ss:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_root + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__root edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0,long + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + mov dword ptr [edi+trace_entry_type],80h + mov dword ptr [edi+trace_entry_string],'-4L ' + mov byte ptr [edi+trace_entry_string],8 + mov dword ptr [edi+trace_entry_string+4],'RATS' + mov dword ptr [edi+trace_entry_string+8],'T' + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + add edi,sizeof trace_buffer_entry + mov [trace_buffer_in_pointer],edi + sub ecx,sizeof trace_buffer_entry + + shr ecx,2 + sub eax,eax + cld + rep stosd + + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ ,,long + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + + mov al,[processor_family+PM] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P5_event_select_msr + mov eax,ebx + wrmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + mov ebx,eax + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P6_event_select0_msr + mov eax,ebx + wrmsr + FI + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov eax,[trace_buffer_in_pointer] + mov ebx,[eax+trace_entry_timestamp] + or ebx,[eax+trace_entry_timestamp+4] + IFZ + sub eax,[trace_buffer_begin] + CANDZ eax,sizeof trace_buffer_entry + ret + FI + + + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + kd____disp <' no trace buffer',13,10> + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer+KR + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer+KR + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + EXITZ + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +P5_event_select_msr equ 11h +P5_event_counter0_msr equ 12h +P5_event_counter1_msr equ 13h + + + +P5_rd_miss equ 000011b +P5_wr_miss equ 000100b +P5_rw_miss equ 101001b +P5_ex_miss equ 001110b + +P5_d_wback equ 000110b + +P5_rw_tlb equ 000010b +P5_ex_tlb equ 001101b + +P5_a_stall equ 00011111b +P5_w_stall equ 00011001b +P5_r_stall equ 00011010b +P5_x_stall equ 00011011b +P5_agi_stall equ 00011111b + +P5_bus_util equ 00011000b + +P5_pipline_flush equ 010101b + +P5_non_cache_rd equ 011110b +P5_ncache_refs equ 011110b +P5_locked_bus equ 011100b + +P5_mem2pipe equ 001001b +P5_bank_conf equ 001010b + + +P5_instrs_ex equ 010110b +P5_instrs_ex_V equ 010111b + + + + + + +P6_event_select0_msr equ 186h +P6_event_select1_msr equ 187h +P6_event_counter0_msr equ 0C1h +P6_event_counter1_msr equ 0C2h + + + + +;P6_rd_miss equ +P6_wr_miss equ 46h +P6_rw_miss equ 45h +P6_ex_miss equ 81h + +P6_d_wback equ 47h + +;P6_rw_tlb equ +P6_ex_tlb equ 85h + +P6_stalls equ 0A2h + +;P6_L2_rd_miss equ +P6_L2_wr_miss equ 25h +P6_L2_rw_miss equ 24h +P6_L2_ex_miss equ + +P6_L2_d_wback equ 27h + + + +P6_bus_util equ 62h + + +P6_instrs_ex equ 0C0h + + + + + + + +set_performance_tracing: + + push ds + push linear_kernel_space + pop ds + mov al,ds:[cpu_family] + pop ds + mov [processor_family],al + + IFNZ al,p5_family + CANDNZ al,p6_family + kd____disp <' not supported by this processor',13,10> + sub eax,eax ; Z! + ret + FI + + + kd____clear_page + call show_trace_perf_monitoring_mode + + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + + mov al,[processor_family] + IFZ al,p5_family,long + + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + ELIFZ al,p6_family,long + + kd____disp <'1 : L1 Dcache Misses (rd/wback)',13,10> + kd____disp <'2 : L2 Cache Misses (rd/wback)',13,10> + kd____disp <'i : Icache/ITLB Misses',13,10> + kd____disp <'I : Instructions/stalls',13,10> + kd____disp <'b : Bus Utilization/Instructions',13,10> + kd____disp <'x : uuee0/uuee1',13,10> + FI + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + mov ah,[processor_family] + IFZ ah,p5_family,long + + sub ebx,ebx + IFZ al,'i' + mov ebx,P5_instrs_ex + (P5_instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,P5_rw_miss + (P5_ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,P5_rw_tlb + (P5_ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,P5_r_stall + (P5_w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,P5_agi_stall + (P5_bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,P5_bus_util + (P5_instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + mov ecx,P5_event_counter0_msr + wrmsr + mov ecx,P5_event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,P5_event_select_msr + wrmsr + FI + + + ELIFZ ah,p6_family,long + + sub ebx,ebx + sub ecx,ecx + + IFZ al,'1' + mov bl,P6_rw_miss + mov cl,P6_d_wback + FI + IFZ al,'2' + mov bl,P6_L2_rw_miss + mov cl,P6_L2_d_wback + FI + IFZ al,'i' + mov bl,P6_ex_miss + mov cl,P6_ex_tlb + FI + IFZ al,'I' + mov bl,P6_instrs_ex + mov cl,P6_stalls + FI + IFZ al,'b' + mov bl,P6_bus_util + mov cl,P6_instrs_ex + FI + IFZ al,'x' + kd____disp <6,11,5,' PerfCnt0: '> + kd____inhex16 + movzx ebx,ax + kd____disp <' PerfCnt1: '> + kd____inhex16 + movzx ecx,ax + FI + + test ebx,ebx + IFNZ + push ecx + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + wrmsr + mov ecx,P6_event_counter1_msr + wrmsr + pop ecx + + bts ebx,22 ; enable counters + + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,10b + ELIFZ al,user_perf_mon + mov al,01b + ELSE_ + mov al,11b + FI + shl eax,16 + or ebx,eax + or ecx,eax + + mov eax,ecx + mov ecx,P6_event_select1_msr + wrmsr + mov eax,ebx + mov ecx,P6_event_select0_msr + wrmsr + FI + + + FI + + + test esp,esp ; NZ ! + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/kdiopc.asm b/l4-x86/l4-y-still-int30/kernel/kdiopc.asm new file mode 100644 index 0000000..277000a --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86,pIII + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/kernel.asm b/l4-x86/l4-y-still-int30/kernel/kernel.asm new file mode 100644 index 0000000..7f0d1e2 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '04.04.00' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-Y Nucleus (PIII), Copyright (C) IBM 1997 & University of Karlsruhe 2000',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/ktest.asm b/l4-x86/l4-y-still-int30/kernel/ktest.asm new file mode 100644 index 0000000..43cf735 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/ktest.asm @@ -0,0 +1,756 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 03,04,00, 16 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.04.00 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86,pIII + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task);;;+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + +kernel_info_page equ 1000h + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + ; kd____disp <13,10,10,'PageFault: '> + ; call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_1000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; kd____disp <13,10,'ipc_16 : '> + mov eax,4 SHL md_mwords + ; call ping_1000 + + if 0 + + kd____disp <13,10,'ipc_128 : '> + mov eax,32 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc_512 : '> + mov eax,128 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc__4K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB4 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB4 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB4 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB4 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,MB2 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_16K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB16 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB16 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB16 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB16 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_64K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB64 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB64 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB64 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB64 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + endif + + + call exit_ktest + + + mov eax,2 + cpuid + + ke 'done' + + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + + REPEAT + OD + + + + + + +ping_short_1000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],1000 + + mov [cycles],0 + + rdtsc + push eax + clign 16 + + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + +display_time_and_cycles: + + sub edx,edx + div ebx + + push eax + + mov ebx,1000000000 + mul ebx + mov ebx,ds:[kernel_info_page].cpu_clock_freq + div ebx + + sub edx,edx + mov ebx,1000 + div ebx + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + sub edx,edx + mov ebx,10 + div ebx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + kd____disp <' us, '> + + pop eax + + IFB_ eax,100000 + kd____disp <' '> + FI + IFB_ eax,10000 + kd____disp <' '> + FI + IFB_ eax,1000 + kd____disp <' '> + FI + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + kd____disp <' cycles'> + + + ret + + + + + + +ping_1000: + + mov [ping_snd_msg+msg_dope],eax + mov [ping_snd_msg+msg_size_dope],eax + mov [ping_rcv_msg+msg_dope],eax + mov [ping_rcv_msg+msg_size_dope],eax + mov [pong_snd_msg+msg_dope],eax + mov [pong_snd_msg+msg_size_dope],eax + mov [pong_rcv_msg+msg_dope],eax + mov [pong_rcv_msg+msg_size_dope],eax + + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],1000 + + rdtsc + push eax + clign 16 + + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + if pong_thread ne sigma1_task + + mov eax,(pong_thread-sigma1_task)/(sizeof tcb) + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + endif + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + + DO + clign 16 + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + + + align 16 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + rdtsc + push eax + + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + rdtsc + pop ebx + sub eax,ebx + mov ebx,127 + + call display_time_and_cycles + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/memctr.asm b/l4-x86/l4-y-still-int30/kernel/memctr.asm new file mode 100644 index 0000000..ec7ed07 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/memctr.asm @@ -0,0 +1,519 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + mov ebx,ds:[sigma0_proot] + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/pagctr.asm b/l4-x86/l4-y-still-int30/kernel/pagctr.asm new file mode 100644 index 0000000..7b05721 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/pagctr.asm @@ -0,0 +1,1181 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 24,08,99, 116 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn set_proot_for_all_threads:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_root + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + add edi,4 + cmp edi,offset task_root+tasks*4 + REPEATB + OD + + + mov ds:[kernel_proot],edx + mov ds:[empty_proot],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 48 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + + push ebp + mov ebp,edx + call set_proot_for_all_threads + pop ebp + + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + int ipc + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + int ipc + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/pagfault.asm b/l4-x86/l4-y-still-int30/kernel/pagfault.asm new file mode 100644 index 0000000..0dce0bb --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/pagfault.asm @@ -0,0 +1,833 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 05,04,00, 9165, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 05.04.00 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86,pIII + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler+KR + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + + + +page_fault_handler: + + cmp ss:[esp+iret_cs+4],kernel_exec + xc z,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + test [ebp+fine_state],nlock + IFNZ + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + push 0 + push kernel_exec + push offset ipcret+KR + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + + test [ebp+ressources],in_partner_space + jnz partner_space_fault + + + call push_ipc_state + + IFNZ + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + ;; test__page_present edx + ;; CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,offset small_virtual_spaces+small_virtual_spaces_size + jb small_space_com_write_fault + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin+KR + CANDBE eax,offset ipc_critical_region_end+KR + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDX faulting virtual address (may be rel to large space) +; +; EAX,EBX,ECX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + + mov cl,ds:[log2_small_space_size_DIV_MB4] + mov ch,cl + + xpdir eax,edx + + mov edi,dword ptr ds:[gdt+(linear_space AND -8)+4] + mov esi,edi + and edi,0FF000000h + and esi,0000000FFh + shl esi,16 + add edi,esi + xor edi,edx + shr edi,22 + shr edi,cl + + mov cl,32-22 + sub cl,ch + + test edi,edi + IFZ + shl edx,cl + shr edx,cl + mov esi,ebp + ELSE_ + mov esi,[ebp+com_partner] + FI + + mov edi,ds:[cpu_cr3] + lea edi,[(eax*4)+edi+PM] + test byte ptr [edi],page_present + xret nz,long + + + mov esi,[esi+thread_proot] + add esi,PM + + mov eax,edx + shl eax,cl + shr eax,cl + xpdir eax,eax + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + + mov esi,[ebp+com_partner] ; com partner is tcb address + + mov edi,[ebp+waddr] + + mark__ressource ebp,com_used + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + pop esi + REPEAT + OD + + + + + + +small_space_com_write_fault: + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,[esi+as_base] + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + +;---------------------------------------------------------------------------- +; +; partner-space write fault (msg copy small -> large, in large as +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +partner_space_fault: + + + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__root eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/pagmap.asm b/l4-x86/l4-y-still-int30/kernel/pagmap.asm new file mode 100644 index 0000000..91fdb74 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/pagmap.asm @@ -0,0 +1,1962 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 25,03,00, 46 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.03.00 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86,pIII + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+KR + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_+KR + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage special ext: set/reset PCD bits +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+KR + jmp short do_fpage + FI + push offset unmap_write_page+KR + jmp short do_fpage + FI + + bt ecx,30 + IFNC + test ch,page_write_permit + IFNZ + push offset flush_page+KR + jmp short do_fpage + FI + push offset flush_write_page+KR + jmp short do_fpage + FI + + test ch,page_cache_disable + IFZ + push offset set_page_cacheable+KR + ELSE_ + push offset set_page_uncacheable+KR + FI + jmp short do_fpage + + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page+KR + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebp,cr3 + IFAE , + mov ebp,esp + and ebp,-sizeof tcb + mov ebp,[ebp+thread_proot] + FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + ;; and ebx,[ebp+map_mask] + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + push edx + + mov edx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,edx + mov bl,[edx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize;;;;;;;;0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + pop ebx + xc z,unmap_in_own_address_space + + pop edx + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + test ebx,1 + IFNZ + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + ELSE_ + push edx + mov ebx,edx + and edx,(pagesize-1) AND -4 + shr ebx,log2_pagesize + shl edx,log2_pagesize-2 + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ebx,(pagesize-1) AND -4 + shl ebx,2*log2_pagesize-4 + add edx,ebx + invlpg [edx] + pop edx + FI + + + cmp edx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp edx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + pop ebx + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + + + test ebx,1 + IFZ + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -4 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -4 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + FI + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; set page cacheable/uncacheable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + +set_page_cacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT (page_cache_disable+page_write_through) + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + +set_page_uncacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + or byte ptr [esi],page_cache_disable+page_write_through + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + mov edx,[ebp+thread_proot] + add edx,PM + + mov ecx,esp + and ecx,-sizeof tcb + mov ecx,[ebp+thread_proot] + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+KR + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + mov ecx,ds:[sigma0_proot] + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/proj.err b/l4-x86/l4-y-still-int30/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-y-still-int30/kernel/sgmctr.asm b/l4-x86/l4-y-still-int30/kernel/sgmctr.asm new file mode 100644 index 0000000..19c003d --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/sgmctr.asm @@ -0,0 +1,264 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.09.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS kernel_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6+KR,kernel_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + add ds:[logical_info_page].kdebug_exception,KR + add dword ptr ss:[esp],KR + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + IF KR EQ 0 + descriptor xr32, dpl0, PM, + ELSE + descriptor xr32, dpl0, 0, ; 08 : kernel_exec + ENDIF + descriptor rw32, dpl0, 0, ; 10 : linear_kernel_space + + descriptor rw32, dpl3, 0, user_space_size ; 18 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 20 : linear space + + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-y-still-int30/kernel/sigma0.asm b/l4-x86/l4-y-still-int30/kernel/sigma0.asm new file mode 100644 index 0000000..23b9b8f --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/sigma0.asm @@ -0,0 +1,767 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + ; CORZ al,dedicated_mem + ; CORZ al,ah + ; IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + ; FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-y-still-int30/kernel/start.asm b/l4-x86/l4-y-still-int30/kernel/start.asm new file mode 100644 index 0000000..a202a24 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/start.asm @@ -0,0 +1,357 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86,pIII + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + mov eax,2 + cpuid + + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/startpc.asm b/l4-x86/l4-y-still-int30/kernel/startpc.asm new file mode 100644 index 0000000..0bb7bcd --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/startpc.asm @@ -0,0 +1,1308 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure+KR + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher+KR + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int+KR + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + ; Select status register A from RTC + + mov al,rtc_reg_a + out rtc_address,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + + ; Wait for UIP (update in progress) flag to disappear + + DO + in al,rtc_data + and al,80h + REPEATNZ + OD + + ; Wait for UIP flag to appear again. This indicates + ; that a second has passed + + DO + in al,rtc_data + and al,80h + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-y-still-int30/kernel/tables.asm b/l4-x86/l4-y-still-int30/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/tcbman.asm b/l4-x86/l4-y-still-int30/kernel/tcbman.asm new file mode 100644 index 0000000..b35d68f --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/tcbman.asm @@ -0,0 +1,750 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 10,04,00, 9143 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.04.00 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc+KR + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + mov ebp,esp + and ebp,-sizeof tcb + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + FI + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + + + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret+KR + + mov dword ptr [esi+4],linear_space + mov dword ptr [esi+8],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + + mov [ebp+pager],esi + + lno___task esi,ebp + load__root esi,esi + mov [ebp+thread_proot],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + + mov esi,[eax+as_base] + mov [ebp+as_base],esi + mov esi,[eax+as_size] + mov [ebp+as_size],esi + mov esi,[eax+thread_segment] + mov [ebp+thread_segment],esi + mov esi,[eax+thread_segment+4] + mov [ebp+thread_segment+4],esi + + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + + ELSE_ + mov [ebp+as_base],0 + mov [ebp+as_size],virtual_space_size + mov [ebp+thread_segment],((virtual_space_size SHR 12)-1) AND 0FFFFh + mov [ebp+thread_segment+4],00C0F300h+(((virtual_space_size SHR 12)-1) AND 000F0000h) + + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret+KR + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + mov dword ptr [ebx+ip_es+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + + + + + + icode + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/x.asm b/l4-x86/l4-y-still-int30/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernel/y.asm b/l4-x86/l4-y-still-int30/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-y-still-int30/kernel/yoonseva.asm b/l4-x86/l4-y-still-int30/kernel/yoonseva.asm new file mode 100644 index 0000000..ef1ed69 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),kernel_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/adrspac5.inc b/l4-x86/l4-y-still-int30/kernifc/adrspac5.inc new file mode 100644 index 0000000..82639ec --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/adrspac5.inc @@ -0,0 +1,207 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ((64+64)*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ((88-64)*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00BF3000h-(max_ptabs*(chapters_per_page+4))-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_root dd tasks dup (?) ; | + xxroot_end_marker dd 1 dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + + dd (kernel_r_tables_size - offset kernel_resident_tables) + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_roots struc + + db offset task_root dup (?) + + empty_proot dd 0 + kernel_proot dd 0 + sigma0_proot dd 0 + +special_roots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) + + + +kernel_relocation equ PM + +KR equ kernel_relocation diff --git a/l4-x86/l4-y-still-int30/kernifc/adrspace.inc b/l4-x86/l4-y-still-int30/kernifc/adrspace.inc new file mode 100644 index 0000000..45ad26d --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ PIII + +subtitle L4/PIII Version Y + +kernel_type = pIII + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-y-still-int30/kernifc/apic.inc b/l4-x86/l4-y-still-int30/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/contents b/l4-x86/l4-y-still-int30/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/cpucb.inc b/l4-x86/l4-y-still-int30/kernifc/cpucb.inc new file mode 100644 index 0000000..f539fad --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/cpucb.inc @@ -0,0 +1,12 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + IF (kernel_type EQ pIII) + +include cpucb6.inc + + ENDIF + diff --git a/l4-x86/l4-y-still-int30/kernifc/cpucb5.inc b/l4-x86/l4-y-still-int30/kernifc/cpucb5.inc new file mode 100644 index 0000000..ffa596e --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/cpucb5.inc @@ -0,0 +1,293 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y-still-int30/kernifc/cpucb6.inc b/l4-x86/l4-y-still-int30/kernifc/cpucb6.inc new file mode 100644 index 0000000..c5338c4 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/cpucb6.inc @@ -0,0 +1,307 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination tcb +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDX, EDI scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov eax,[ebp+thread_segment] + mov edi,[ebp+thread_segment+4] + + mov ds:[gdt+linear_space/8*8],eax + mov ds:[gdt+linear_space/8*8+4],edi + add edi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8],eax + mov ds:[gdt+linear_space_exec/8*8+4],edi + + IFNS + mov edi,[ebp+thread_proot] + CANDNZ edi,ds:[cpu_cr3] + mov ds:[cpu_cr3],edi + mov dword ptr ds:[tlb_invalidated],edi + mov cr3,edi + FI + mov eax,linear_space + mov ds,eax + mov es,eax + + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + +;---------------------------------------------------------------------------- +; +; machine specific registers +; +;---------------------------------------------------------------------------- + + +sysenter_cs_msr equ 174h +sysenter_esp_msr equ 175h +sysenter_eip_msr equ 176h + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +sysenter_present_bit equ 11 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y-still-int30/kernifc/intrifc.inc b/l4-x86/l4-y-still-int30/kernifc/intrifc.inc new file mode 100644 index 0000000..0291688 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/intrifc.inc @@ -0,0 +1,327 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_es dd 0 + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + push es + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/kpage.inc b/l4-x86/l4-y-still-int30/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-y-still-int30/kernifc/l4const.inc b/l4-x86/l4-y-still-int30/kernifc/l4const.inc new file mode 100644 index 0000000..e93d85d --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/l4const.inc @@ -0,0 +1,101 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +kernel_exec equ 0008h +linear_kernel_space equ 0010h + +linear_space equ (0018h+3) +linear_space_exec equ (0020h+3) + +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h + +p5_family equ 5 +p6_family equ 6 + +other_family equ 0 + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/l4kd.inc b/l4-x86/l4-y-still-int30/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-y-still-int30/kernifc/l4pre.inc b/l4-x86/l4-y-still-int30/kernifc/l4pre.inc new file mode 100644 index 0000000..ba3fccc --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/l4pre.inc @@ -0,0 +1,807 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + + +cmovx macro cc,d,s +db 0Fh,&cc,0C0h+&d&code*8+&s&code +endm + + +cmovb macro d,s +cmovx 42h,d,s +endm + + +cmovs macro d,s +cmovx 48h,d,s +endm + + + + +clign macro alignment + local xx + jmp short xx + align alignment + xx: +endm + + + + + + + + + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-y-still-int30/kernifc/lbmac.inc b/l4-x86/l4-y-still-int30/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-y-still-int30/kernifc/pagcb.inc b/l4-x86/l4-y-still-int30/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/kernifc/pagconst.inc b/l4-x86/l4-y-still-int30/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-y-still-int30/kernifc/pagmac.inc b/l4-x86/l4-y-still-int30/kernifc/pagmac.inc new file mode 100644 index 0000000..6674bce --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/pagmac.inc @@ -0,0 +1,86 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + + +load__root macro reg,task_no + + mov reg,ds:[(task_no*4)+task_root] + endm + + +store_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + +store_inactive_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + + + + diff --git a/l4-x86/l4-y-still-int30/kernifc/perfmon.inc b/l4-x86/l4-y-still-int30/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-y-still-int30/kernifc/pnodes.inc b/l4-x86/l4-y-still-int30/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-y-still-int30/kernifc/proj.err b/l4-x86/l4-y-still-int30/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-y-still-int30/kernifc/schedcb.inc b/l4-x86/l4-y-still-int30/kernifc/schedcb.inc new file mode 100644 index 0000000..8f80035 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-y-still-int30/kernifc/schedcb2.inc b/l4-x86/l4-y-still-int30/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-y-still-int30/kernifc/small-as.inc b/l4-x86/l4-y-still-int30/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-y-still-int30/kernifc/tcb.inc b/l4-x86/l4-y-still-int30/kernifc/tcb.inc new file mode 100644 index 0000000..6d2f097 --- /dev/null +++ b/l4-x86/l4-y-still-int30/kernifc/tcb.inc @@ -0,0 +1,274 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + com_partner dd 0 + thread_proot dd 0 + + thread_segment dd 0,0 + as_base dd 0 + as_size dd 0 + + + myself dd 0 + waiting_for dd 0 + waddr dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + pager dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:3,in_partner_space:1,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_root/4 GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_root)/4 - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-y-still-int30/make/l4.rsp b/l4-x86/l4-y-still-int30/make/l4.rsp new file mode 100644 index 0000000..a83dd90 --- /dev/null +++ b/l4-x86/l4-y-still-int30/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-y-still-int30/make/make-l4 b/l4-x86/l4-y-still-int30/make/make-l4 new file mode 100644 index 0000000..9166dc4 --- /dev/null +++ b/l4-x86/l4-y-still-int30/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-y\kernel\;\liedtke\l4-y\kernifc\;\liedtke\l4-y\userifc\} +a=d:\liedtke\l4-y\PIII^\ +all_includes_PIII= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb6.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_PIII) $(p)adrsman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII adrsman asm + +$(a)cpuctr.obj : $(all_includes_PIII) $(p)cpuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII cpuctr asm + +$(a)dispatch.obj : $(all_includes_PIII) $(p)dispatch.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII dispatch asm + +$(a)emuctr.obj : $(all_includes_PIII) $(p)emuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII emuctr asm + +$(a)intctr.obj : $(all_includes_PIII) $(p)intctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII intctr asm + +$(a)ipcman.obj : $(all_includes_PIII) $(p)ipcman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ipcman asm + +$(a)kdebug.obj : $(all_includes_PIII) $(p)kdebug.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdebug asm + +$(a)kdiopc.obj : $(all_includes_PIII) $(p)kdiopc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kernel asm + +$(a)ktest.obj : $(all_includes_PIII) $(p)ktest.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ktest asm + +$(a)memctr.obj : $(all_includes_PIII) $(p)memctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII memctr asm + +$(a)pagctr.obj : $(all_includes_PIII) $(p)pagctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagctr asm + +$(a)pagfault.obj : $(all_includes_PIII) $(p)pagfault.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagfault asm + +$(a)pagmap.obj : $(all_includes_PIII) $(p)pagmap.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagmap asm + +$(a)sgmctr.obj : $(all_includes_PIII) $(p)sgmctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sgmctr asm + +$(a)sigma0.obj : $(all_includes_PIII) $(p)sigma0.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sigma0 asm + +$(a)start.obj : $(all_includes_PIII) $(p)start.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII start asm + +$(a)startpc.obj : $(all_includes_PIII) $(p)startpc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII startpc asm + +$(a)tcbman.obj : $(all_includes_PIII) $(p)tcbman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII tcbman asm + +$(a)yoonseva.obj : $(all_includes_PIII) $(p)yoonseva.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-y\PIII + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_PIII) $(p)boot.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-y\PIII + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/make/ml-piii.bat b/l4-x86/l4-y-still-int30/make/ml-piii.bat new file mode 100755 index 0000000..2eff3bb --- /dev/null +++ b/l4-x86/l4-y-still-int30/make/ml-piii.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=pIII /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-y-still-int30/make/proj.err b/l4-x86/l4-y-still-int30/make/proj.err new file mode 100644 index 0000000..d806192 --- /dev/null +++ b/l4-x86/l4-y-still-int30/make/proj.err @@ -0,0 +1,30 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\adrsman.asm + Assembling: ..\kernel\cpuctr.asm + Assembling: ..\kernel\dispatch.asm + Assembling: ..\kernel\emuctr.asm + Assembling: ..\kernel\intctr.asm + Assembling: ..\kernel\ipcman.asm + Assembling: ..\kernel\kdebug.asm + Assembling: ..\kernel\kdiopc.asm + Assembling: ..\kernel\ktest.asm + Assembling: ..\kernel\memctr.asm + Assembling: ..\kernel\pagctr.asm + Assembling: ..\kernel\pagfault.asm + Assembling: ..\kernel\pagmap.asm + Assembling: ..\kernel\sgmctr.asm + Assembling: ..\kernel\sigma0.asm + Assembling: ..\kernel\start.asm + Assembling: ..\kernel\startpc.asm + Assembling: ..\kernel\tcbman.asm + Assembling: ..\kernel\yoonseva.asm + Assembling: ..\kernel\boot.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/l4-y-still-int30/userifc/contents b/l4-x86/l4-y-still-int30/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-y-still-int30/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/userifc/msg.inc b/l4-x86/l4-y-still-int30/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-y-still-int30/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-y-still-int30/userifc/scmac.inc b/l4-x86/l4-y-still-int30/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-y-still-int30/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/userifc/syscalls.inc b/l4-x86/l4-y-still-int30/userifc/syscalls.inc new file mode 100644 index 0000000..ff0f980 --- /dev/null +++ b/l4-x86/l4-y-still-int30/userifc/syscalls.inc @@ -0,0 +1,25 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 \ No newline at end of file diff --git a/l4-x86/l4-y-still-int30/userifc/uid.inc b/l4-x86/l4-y-still-int30/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-y-still-int30/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/l4-y/c-bind/new/compiler.h b/l4-x86/l4-y/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y/c-bind/new/idt.h b/l4-x86/l4-y/c-bind/new/idt.h new file mode 100644 index 0000000..4f6563c --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y/c-bind/new/ipc-trent.c b/l4-x86/l4-y/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y/c-bind/new/ipc.h b/l4-x86/l4-y/c-bind/new/ipc.h new file mode 100644 index 0000000..4e470c7 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y/c-bind/new/kdebug.h b/l4-x86/l4-y/c-bind/new/kdebug.h new file mode 100644 index 0000000..15d3b4b --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y/c-bind/new/kernel.h b/l4-x86/l4-y/c-bind/new/kernel.h new file mode 100644 index 0000000..9c4589d --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y/c-bind/new/syscalls.h b/l4-x86/l4-y/c-bind/new/syscalls.h new file mode 100644 index 0000000..40dc72a --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y/c-bind/new/test.c b/l4-x86/l4-y/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/l4-y/c-bind/new/types.h b/l4-x86/l4-y/c-bind/new/types.h new file mode 100644 index 0000000..067ff57 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y/c-bind/new/x-compiler.h b/l4-x86/l4-y/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y/c-bind/new/x-idt.h b/l4-x86/l4-y/c-bind/new/x-idt.h new file mode 100644 index 0000000..af09d0e --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y/c-bind/new/x-ipc.h b/l4-x86/l4-y/c-bind/new/x-ipc.h new file mode 100644 index 0000000..beb9d3e --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y/c-bind/new/x-kdebug.h b/l4-x86/l4-y/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..6a02e40 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y/c-bind/new/x-kernel.h b/l4-x86/l4-y/c-bind/new/x-kernel.h new file mode 100644 index 0000000..759b720 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y/c-bind/new/x-lid.c b/l4-x86/l4-y/c-bind/new/x-lid.c new file mode 100644 index 0000000..98dfde9 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/l4-y/c-bind/new/x-syscalls.h b/l4-x86/l4-y/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..561e560 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y/c-bind/new/x-types.h b/l4-x86/l4-y/c-bind/new/x-types.h new file mode 100644 index 0000000..e1f38a2 --- /dev/null +++ b/l4-x86/l4-y/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2001/03/07 11:30:47 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y/c-bind/orig/compiler.h b/l4-x86/l4-y/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y/c-bind/orig/idt.h b/l4-x86/l4-y/c-bind/orig/idt.h new file mode 100644 index 0000000..396c044 --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y/c-bind/orig/ipc-trent.c b/l4-x86/l4-y/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y/c-bind/orig/ipc.h b/l4-x86/l4-y/c-bind/orig/ipc.h new file mode 100644 index 0000000..d7df0f5 --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y/c-bind/orig/kdebug.h b/l4-x86/l4-y/c-bind/orig/kdebug.h new file mode 100644 index 0000000..97a9ca3 --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y/c-bind/orig/kernel.h b/l4-x86/l4-y/c-bind/orig/kernel.h new file mode 100644 index 0000000..7f81d94 --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y/c-bind/orig/syscalls.h b/l4-x86/l4-y/c-bind/orig/syscalls.h new file mode 100644 index 0000000..e933adb --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y/c-bind/orig/types.h b/l4-x86/l4-y/c-bind/orig/types.h new file mode 100644 index 0000000..dba1f0f --- /dev/null +++ b/l4-x86/l4-y/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y/c-bind/provisional/compiler.h b/l4-x86/l4-y/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/l4-y/c-bind/provisional/idl.m4 b/l4-x86/l4-y/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/l4-y/c-bind/provisional/idt.h b/l4-x86/l4-y/c-bind/provisional/idt.h new file mode 100644 index 0000000..396c044 --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/l4-y/c-bind/provisional/ipc-trent.c b/l4-x86/l4-y/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/l4-y/c-bind/provisional/ipc.h b/l4-x86/l4-y/c-bind/provisional/ipc.h new file mode 100644 index 0000000..61acff5 --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/l4-y/c-bind/provisional/kdebug.h b/l4-x86/l4-y/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..97a9ca3 --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/l4-y/c-bind/provisional/kernel.h b/l4-x86/l4-y/c-bind/provisional/kernel.h new file mode 100644 index 0000000..7f81d94 --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/l4-y/c-bind/provisional/syscalls.h b/l4-x86/l4-y/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..e933adb --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/l4-y/c-bind/provisional/types.h b/l4-x86/l4-y/c-bind/provisional/types.h new file mode 100644 index 0000000..dba1f0f --- /dev/null +++ b/l4-x86/l4-y/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2001/03/07 11:30:48 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/l4-y/kernel/adrsman.asm b/l4-x86/l4-y/kernel/adrsman.asm new file mode 100644 index 0000000..0be1617 --- /dev/null +++ b/l4-x86/l4-y/kernel/adrsman.asm @@ -0,0 +1,1044 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 10,04,00, 9026 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 10.10.00 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public create_kernel_including_task + public set_address_space_data_for_all_threads + public set_proot_for_all_threads + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86,pIII + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + mov eax,[eax] ; + + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc+KR + call define_idt_gate + + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + +task_new_failed: + + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + + + +task_new_sc: + + tpre trap2,ds,es + + and esi,NOT mask lthread_no + + mov ebp,esp + and ebp,-sizeof tcb + + IFZ ebx,1,long ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + mov eax,[ebp+thread_proot] ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + sub edi,edi ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + test edi,edi ; + IFZ ; + mov edi,[ebp+thread_proot] + call detach_associated_small_space + FI ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + ; + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + + lno___task ecx,ebx + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,[(ecx*4)+task_root] + + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_root eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_root esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + lno___task edi,eax + lea___tcb ebp,eax ; + + mov edi,[edi*4+task_root] + sub edi,ds:[empty_proot] + CORC + IFAE edi,KB4 + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + + + + + icode + + + + +create_kernel_including_task: + + IFNZ [ebx].ktask_stack,0 + + lea___tcb ebp,eax + + call gen_kernel_including_address_space + + lno___task ecx,ebp + store_root eax,ecx + + mov ecx,[ebx].ktask_stack + mov edx,[ebx].ktask_start + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + mov esi,sigma0_task + + call create_thread + + FI + + ret + + + + icod ends + + + + + + + +;---------------------------------------------------------------------------- +; +; set address space / small space data for all threads +; +;---------------------------------------------------------------------------- +; set address space PRECONDITION: +; +; EAX task pdir +; EBX as base +; ECX as size +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set small space PRECONDITION: +; +; EAX as number +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; set proot PRECONDITION: +; +; EAX proot address +; EBP tcb of task +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread_proot set in all threads of task +; +; CR2, CPU_CR3, and linear_space segements updated if own task +; +;---------------------------------------------------------------------------- + + +set_address_space_data_for_all_threads: + + push edx + push esi + push edi + push ebp + + lno___task edi,ebp + mov ds:[(edi*4)+task_root],eax + + mov edi,ebx + rol edi,8 + bswap edi + and edi,0FF0000FFh + or edi,000C0F300h + + mov edx,ecx + shr edx,log2_pagesize + dec edx + mov esi,edx + and edx,000F0000h + and esi,0000FFFFh + or edi,edx + + mov edx,ebx + shl edx,16 + or esi,edx + + + and ebp,-(lthreads*sizeof tcb) + mov edx,lthreads + DO + test__page_writable ebp + IFNC + mov [ebp+thread_proot],eax + mov [ebp+thread_segment],esi + mov [ebp+thread_segment+4],edi + mov [ebp+as_base],ebx + mov [ebp+as_size],ecx + + add ebp,sizeof tcb + dec edx + REPEATNZ + ELSE_ + and ebp,-pagesize + add ebp,pagesize + sub edx,pagesize/sizeof tcb + REPEATA + FI + OD + + pop ebp + + mov edx,ebp + xor edx,esp + test edx,mask task_no + IFZ + mov ds:[gdt+linear_space/8*8],esi + mov ds:[gdt+linear_space/8*8+4],edi + add edi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8],esi + mov ds:[gdt+linear_space_exec/8*8+4],edi + mov ds:[cpu_cr3],eax + mov cr3,eax + mov edx,linear_space + mov es,edx + mov fs,edx + mov gs,edx + FI + + pop edi + pop esi + pop edx + ret + + + + + +set_small_space_data_for_all_threads: + + push ebx + push ecx + mov ebx,eax + + mov eax,[ebp+thread_proot] + mov ecx,virtual_space_size + shl ebx,22 + IFNZ + add ebx,offset small_virtual_spaces + movzx ecx,ds:[small_space_size_div_MB4] + shl ecx,22 + FI + call set_address_space_data_for_all_threads + + mov eax,ebx + pop ecx + pop ebx + ret + + + +set_proot_for_all_threads: + + push ebx + push ecx + + mov ebx,[ebp+as_base] + mov ecx,[ebp+as_size] + call set_address_space_data_for_all_threads + + pop ecx + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + mov cl,3 ; 32 MB + call change_small_space_size + + ret + + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; EBP a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + movzx eax,ah + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + CANDNZ eax,ecx + + call detach_associated_small_space + + test eax,eax + IFNZ + movzx ecx,[(eax*2)+small_associated_task] + test ecx,ecx + IFNZ + push ebp + mov ebp,ecx + shl ebp,task_no + lea___tcb ebp,ebp + call detach_small_space + pop ebp + FI + FI + FI + + lno___task ecx,ebp + mov [(eax*2)+small_associated_task],cx + + call set_small_space_data_for_all_threads + + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space / detach associated small space +; +;---------------------------------------------------------------------------- +; detach associated small space PRECONDITION: +; +; EBP tcb of task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; detach small space PRECONDITION: +; +; EBP tcb of task +; ECX small space no +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push eax + push ecx + + mov ecx,[ebp+as_base] + sub ecx,offset small_virtual_spaces + IFNC + shr ecx,22 + lno___task eax,ebp + call detach_small_space + FI + + pop ecx + pop eax + ret + + + +detach_small_space: + + push eax + + IFZ ax,word ptr [(ecx*2)+small_associated_task] + + mov word ptr [(ecx*2)+small_associated_task],0 + + sub eax,eax + call set_small_space_data_for_all_threads + + call flush_small_pde_block_in_all_pdirs + + mov eax,cr3 + mov cr3,eax + + ELSE_ + ke 'detach_err' + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; make own address space large +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + + + +make_own_address_space_large: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + call set_small_space_data_for_all_threads + + pop ebp + ret + + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + sub edx,edx + DO + cmp edx,tasks + EXITAE + + mov ebp,[(edx*4)+task_root] + inc edx + test ebp,pagesize-1 + REPEATNZ + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + + + +;---------------------------------------------------------------------------- +; +; change small space size +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + mov ch,cl + xchg cl,ds:[log2_small_space_size_DIV_MB4] + add cl,22 + add ch,22 + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + mov eax,[esi+as_base] + test eax,eax + IFNZ + sub eax,offset small_virtual_spaces + shr eax,22 + add al,al + add al,ds:[small_space_size_DIV_MB4] + FI + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/atrace.asm b/l4-x86/l4-y/kernel/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/l4-y/kernel/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y/kernel/boot.asm b/l4-x86/l4-y/kernel/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/l4-y/kernel/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/l4-y/kernel/contents b/l4-x86/l4-y/kernel/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/l4-y/kernel/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/cpuctr.asm b/l4-x86/l4-y/kernel/cpuctr.asm new file mode 100644 index 0000000..04a0397 --- /dev/null +++ b/l4-x86/l4-y/kernel/cpuctr.asm @@ -0,0 +1,1243 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 22,04,00, 573, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 22.04.00 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn ipc_exit:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for pIII + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + test eax,1 SHL ac_flag + IFZ + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + + mov eax,1 + cpuid + + push eax + and ah,0Fh + IFZ ah,6 + CANDB al,30h + and al,0Fh + CANDB al,3 + btr edx,sysenter_present_bit + FI + pop eax + IF kernel_relocation EQ 0 + btr edx,sysenter_present_bit + ENDIF + + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + shr al,4 + CORA al,p6_family + IFB_ al,p5_family + mov al,other_family + FI + mov ds:[cpu_family],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + + add eax,cpu0_tss + ltr ax + + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception+KR + call define_idt_gate + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + mov bh,0 SHL 5 + mov bl,invalid_tss + mov eax,offset invalid_tss_handler+KR + call define_idt_gate + + + lno___prc eax + test eax,eax + IFZ + call wait_for_one_second_tick + rdtsc + mov ebx,eax + call wait_for_one_second_tick + rdtsc + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int+KR + call define_idt_gate + + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + + + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + lno___prc eax + test eax,eax + IFZ + + mov edi,1000000 + mov dword ptr ds:[local_apic+apic_timer_init+KR],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + + mov eax,offset apic_error_handler+KR + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + +switch_context: + + switch_thread con,ebx + + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + + + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + mov esi,[ebp+thread_proot] + IFNZ esi,ds:[cpu_cr3] + mov ds:[cpu_cr3],esi + mov dword ptr ds:[tlb_invalidated],esi + mov cr3,esi + FI + + mov esi,[ebp+thread_segment] + mov ds:[gdt+linear_space/8*8],esi + mov ds:[gdt+linear_space_exec/8*8],esi + mov esi,[ebp+thread_segment+4] + mov ds:[gdt+linear_space/8*8+4],esi + add esi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + push offset switch_thread_tunnel_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_con: + mov edi,ebx + push offset switch_thread_con_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_int: + mov edi,ebx + push offset switch_thread_int_ret+KR + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + push offset switch_thread_ipc_ret+KR + + +deallocate_ressources: + + push eax + + test [edi+ressources],mask x87_used + IFNZ + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + and [edi+ressources],NOT mask x87_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask com_used + IFNZ + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + CORNZ [ebp+as_base],0 + mov eax,[ebp+thread_proot] + IFZ ds:[cpu_cr3],eax + mov eax,cr3 + mov cr3,eax + FI + + and [edi+ressources],NOT mask com_used + IFZ + pop eax + ret + FI + FI + + test [edi+ressources],mask dr_used+mask in_partner_space + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + + pop eax + ret + + FI + + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + sub eax,eax + mov dr7,eax + + sub [edi+thread_esp],2*4 + + pop eax + pop edi + + push offset reallocate_ressources_by_ipc_exit+KR + push offset reallocate_ressources_by_ret+KR + + + push edi + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_ipc_exit: + + call reallocate_ressources + + jmp ipc_exit + + + + +reallocate_ressources_by_ret: + + add esp,4 + + + +reallocate_ressources: + + push eax + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + mov al,[ebp+ressources] + + test al,mask dr_used + IFNZ + push eax + call reload_debug_registers + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + pop eax + FI + + test al,mask in_partner_space + IFNZ + mov eax,[ebp+com_partner] + mov eax,ss:[eax+thread_proot] + IFNZ eax,ss:[cpu_cr3] + mov ss:[cpu_cr3],eax + mov cr3,eax + FI + FI + + pop ebp + pop eax + ret + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + mov eax,esp + sub eax,ebp + IFAE eax, + + test [ebp+ressources],mask dr_used + CANDNZ + + mov eax,[ebp+thread_esp] + CANDNZ , + + sub eax,2*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret+KR + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_ipc_exit+KR + + mov [ebp+thread_esp],eax + FI + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + +;---------------------------------------------------------------------------- +; +; invalid tss handler (if user sets NT-flag, then sysenter -> kernel -> iret +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NT-flag reset +; +;---------------------------------------------------------------------------- + + +invalid_tss_handler: + + btr ss:[esp+iret_eflags+4],nt_flag + add esp,4 + iretd + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],kernel_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + mov eax,dr7 + test al,10101010b + IFZ + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + mark__ressource ebp,dr_used + + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + unmrk_ressource ebp,dr_used + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov eax,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov eax,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + mov ds:[actual_co1_tcb],0 + + mov al,ds:[co1_type] + + IFZ al,no87 + + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler+KR + call define_idt_gate + + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + mov ebp,esp + and ebp,-sizeof tcb + + clts + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + + test eax,eax + IFNZ + fnsave [eax+reg_387] + fwait + FI + + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + finit + ELSE_ + frstor [ebp+reg_387] + FI + mov ds:[actual_co1_tcb],ebp + FI + + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + IFZ ds:[actual_co1_tcb],ebp + + push eax + + clts ; clts prevents from INT 7 at fnsave + fnsave [ebp+reg_387] + fwait + sub eax,eax + mov ds:[actual_co1_tcb],eax + + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/dispatch.asm b/l4-x86/l4-y/kernel/dispatch.asm new file mode 100644 index 0000000..36d3628 --- /dev/null +++ b/l4-x86/l4-y/kernel/dispatch.asm @@ -0,0 +1,1408 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 03,02,00, 9090, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.02.00 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86,pIII + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax + cld + rep stosd + mov dword ptr ds:[dispatcher_table],-1 + + mov ds:[highest_active_prio],0 + + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + mov ds:[system_clock_low],1 + + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc+KR + call define_idt_gate + + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc+KR + call define_idt_gate + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + mov [ebx+prio],0 + + llinit ebx,present + + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + + inc [present_chain_version+PM] + + test [ebp+list_state],is_present + IFZ + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + + IFZ ebp, + call init_dispatcher_tcb + ELSE_ + + + test [ebp+fine_state],nwake + IFNZ + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + mov ebx,esp + and ebx,-sizeof tcb + + test [ebp+list_state],is_present + IFNZ + lldel ebp,edx,eax,present + FI + + test [ebp+list_state],is_ready + IFNZ + call delete_from_ready_list + FI + + + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + btr [ebp+wakeup_low],31 + IFC + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + test [ebp+list_state],cl + IFNZ + push esi + push edi + + mov edi,offset dispatcher_tcb + DO + mov esi,edi + mov edi,[edi+edx] + test edi,edi + EXITZ + cmp edi,ebp + REPEATNZ + + not cl + and [edi+list_state],cl + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + movzx eax,[ebx+prio] + + test [ebx+list_state],is_ready + IFZ + mov edi,[eax*4+dispatcher_table] + test edi,edi + IFZ + IFA eax,ds:[highest_active_prio] + mov ds:[highest_active_prio],eax + FI + mov [eax*4+dispatcher_table],ebx + llinit ebx,ready + ret + FI + + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + + test [ebp+list_state],is_ready + IFNZ + movzx eax,[ebp+prio] + IFNZ ebp,[ebp+ready_llink].succ + + mov edi,dword ptr ds:[eax*4+dispatcher_table] + IFZ edi,ebp + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + lldel ebp,edi,edx,ready + ret + FI + + and [ebp+list_state],NOT is_ready + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + cmp eax,ds:[highest_active_prio] + IFZ + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + mov ds:[highest_active_prio],eax + ret + + ELIFB + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored an a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + mov [ebx+thread_esp],esp + + +restart_dispatch: + + sti + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + cli + + mov eax,ds:[highest_active_prio] + + test eax,eax + jz restart_dispatch + + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + CORZ ebp,ebx + test [ebp+fine_state],nready + CORNZ + IFLE [ebp+rem_timeslice],0 + + mov ebp,[ebp+ready_llink].succ + DO + test [ebp+fine_state],nready + EXITZ + + call delete_from_ready_list + mov ebp,edi + + test eax,eax + REPEATNZ + + jmp restart_dispatch + OD + + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz switch_context + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : donate, thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + mov ebp,esp + and ebp,-sizeof tcb + mov ebx,ebp + + mark__ready ebx + + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + push offset switch_ret+KR + + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + IFNZ ebp,ebx + test__page_writable ebp + CANDNC + CANDZ esi,[ebp+myself] + + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + + + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret+KR + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word +; EBX ext preempter / 0 +; ESI thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + mov edx,esi + lea___tcb esi + + cmp [esi+myself],edx + + IFZ ,,long + + mov edi,esp + and edi,-sizeof tcb + + push eax + push ebx + + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state + xchg ebp,esi + + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + FI + FI + + shl edx,12 + + call get_small_space + mov dh,al + + mov dl,[esi+prio] + + mov ch,[edi+max_controlled_prio] + + pop ebx + pop eax + + + CANDBE dl,ch,long + + + + IFNZ eax,-1 + CANDBE al,ch + + push eax + + cmp al,1 ; al := max (al,1) + adc al,0 ; + + + IFNZ dl,al + test [esi+list_state],is_ready + IFNZ + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + mov [esi+prio],al + mov ebx,esi + call insert_into_ready_list + popad + ELSE_ + mov [esi+prio],al + FI + FI + + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + IFBE ah,2*max_small_spaces-1 + push ebp + mov ebp,esi + call attach_small_space + pop ebp + FI + + FI + mov ebx,edx + + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + + mov eax,ebx + + mov esi,[esi+waiting_for] + + ELSE_ + + sub eax,eax + dec eax + + FI + + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/emuctr.asm b/l4-x86/l4-y/kernel/emuctr.asm new file mode 100644 index 0000000..9ee169a --- /dev/null +++ b/l4-x86/l4-y/kernel/emuctr.asm @@ -0,0 +1,511 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 27,09,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.09.99 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler+KR + call define_idt_gate + + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + lea___ip_bottom ebp,ebp + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + test eax,(1 SHL vif_flag) + xret z + + btr [esp+iv_eflags],vip_flag + mov al,nmi + jmp exception + + + + + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + + push offset gp_ud_emu_al_return+KR + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + pop eax + ret + + + + + + + + align 16 + + +gp_ud_emu_2_return: + + mov eax,2 + + + +gp_ud_emu_al_return: + + and eax,0FFh + add [esp+ip_eip+4],eax + + pop eax + ipost + + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/idecode.asm b/l4-x86/l4-y/kernel/idecode.asm new file mode 100644 index 0000000..c62cff7 --- /dev/null +++ b/l4-x86/l4-y/kernel/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],kernel_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/l4-y/kernel/intctr.asm b/l4-x86/l4-y/kernel/intctr.asm new file mode 100644 index 0000000..d030a92 --- /dev/null +++ b/l4-x86/l4-y/kernel/intctr.asm @@ -0,0 +1,543 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 20,03,00, 59 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 20.03.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86,pIII + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler+KR + db dpl3 + dd offset initial_debug_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler+KR + db dpl3 + dd offset overflow_handler+KR + db dpl3 + dd offset bound_check_handler+KR + db dpl3 + dd offset invalid_opcode_handler+KR + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler+KR + db dpl0 + dd offset stack_exception_handler+KR + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler+KR + db dpl0 + dd offset alignment_check_handler+KR + db dpl0 + dd offset machine_check_exception+KR + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + movzx edi,bl + shl edi,3 + add edi,offset idt + + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,kernel_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + push es + + +exception: + + + mov ebp,esp + and ebp,-sizeof tcb + + and eax,000000FFh + + +; CORZ al,seg_not_present ; ensures that seg regs are valid +; CORZ al,stack_exception ; + IFZ al,general_protection,long ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt,long + ; data segment + ; mov ecx,linear_space ; + ; CORNZ [esp+ip_ds],ecx ; + ; mov edx,es ; + ; IFNZ edx,ecx ; + ; test byte ptr ss:[esp+ip_cs],11b + ; IFNZ ; + ; mov [esp+ip_ds],ecx; do not update DS + ; mov [esp+ip_es],ecx; do not update ES + ; ; if within kernel ! + ; ipost ; (DS might be kernel seg) + ; FI ; + ; FI ; + + + IFBE word ptr ss:[esp+ip_ds],3 + mov [esp+ip_ds],linear_space + ipost + FI + IFBE word ptr ss:[esp+ip_es],3 + mov [esp+ip_es],linear_space + ipost + FI + + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + CANDNZ [ebp+as_base],0 + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz perhaps_kd_exception + cmp ebx,virtual_space_size + ja perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov eax,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/ipcman-yoon.asm b/l4-x86/l4-y/kernel/ipcman-yoon.asm new file mode 100644 index 0000000..ee1cb7b --- /dev/null +++ b/l4-x86/l4-y/kernel/ipcman-yoon.asm @@ -0,0 +1,3637 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 18,04,00, 9580, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 18.04.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb +; public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + public ipcman_sysexit_to_user_instruction + public ipc_exit + + public kernel_ipc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + +ipc_kernel_stack struc + + ipc_edx dd 0 + ipc_ebx dd 0 + ipc_eax dd 0 + ipc_esp dd 0 + +ipc_kernel_stack ends + + +ipc_user_stack struc + + ipc_user_eip dd 0 + ipc_user_cs dd 0 + ipc_user_rcv_descriptor dd 0 + ipc_user_timeouts dd 0 + +ipc_user_stack ends + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push es + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+KR + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + switch_space + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+KR + jmp switch_context + FI + FI + + jmp switch_from_intr + + + + align 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + align 16 + + + +;---------------------------------------------------------------------------- +; +; INT 30h IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + kcod ends + + +ipc_sc: + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + call kernel_ipc + + push linear_space + pop ds + push linear_space + pop es + + iretd + + + + +; push ebx +; +; mov ebx,ss:[esp+iret_esp+4] +; sub ebx,sizeof ipc_user_stack +; +; mov ds:[ebx+ipc_user_timeouts],ecx +; mov ds:[ebx+ipc_user_rcv_descriptor],ebp +; mov ds:[ebx+ipc_user_cs],linear_space_exec +; mov ecx,ss:[esp+iret_eip+4] +; mov ds:[ebx+ipc_user_eip],ecx +; +; mov ecx,ebx +; pop ebx +; +; mov esp,offset cpu_esp0 +; +; jmp ipc_sysenter + + + + + + kcode + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +; EIP +; CS +; rcv descriptor +; I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov [esp+ipc_eax],offset receive_timeout_ret+KR + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + sub eax,eax + jmp ipc_exit + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+fine_state],locked_running + mov [ebp+fine_state],locked_waiting + + and eax,ipc_control_mask + mov esi,[esp+ipc_eax] + + mov edx,[ebx+as_base] + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + + and esi,NOT (deceit+map_msg) + IFNZ + mov edi,[esi+edx+msg_dope] + and edi,0FFFFFF00h + or eax,edi + FI + + + mov edi,[ebp+rcv_descriptor] + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add eax,ipc_cut + and edi,NOT (deceit+map_msg) + + CANDNZ ,,long + + ; mov ecx,linear_kernel_space + ; mov es,ecx + + sub eax,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + + lea eax,[(ecx*4)+esi+msg_w3] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_mwords_source,long + + add esi,edx + + lea eax,[(ecx*4)+edi+msg_w3] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_mwords_dest,long + + mov eax,[ebp+as_base] + add edi,eax + + test eax,eax + ;;;;cmp eax,eax + xc z,mwords_through_com_space,long + + ;; sti + + mov edx,[edi+msg_size_dope] + shr edx,md_mwords + cmp ecx,edx + xc a,shorten_mwords,long + + mov edx,edi + sub ecx,2 + IFA + push esi + add esi,offset msg_w3 + add edi,offset msg_w3 + + IFAE ecx,32/4 + DO + mov eax,[esi] + ;; mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,32/4 + cmp ecx,32/4 + REPEATA + OD + FI + IFAE ecx,4/4 + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + sub ecx,4/4 + REPEATA + OD + FI + + ;cld + ;rep movsd + + pop esi + + FI + pop eax + pop ebx + + test eax,mask md_strings + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressources ebx,com_used,in_partner_space + + test edi,edi + IFNZ + or edi,map_msg + FI + + ;; cli + + mov ecx,[ebx+timeouts] + + FI + + test eax,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+ipc_ebx+2*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+ipc_ebx+2*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+KR + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + align 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + ke 'shorten_mwords' + mov ecx,edx + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + +XHEAD address_space_overflow_mwords_source + ke 'mw_source_ovfl' + xret ,long + +XHEAD address_space_overflow_mwords_dest + ke 'mw_dest_overfl' + xret ,long + + + +;XHEAD prepare_small_source +; +; lea edx,[ecx*4+esi] +; +; sass__32 cmp,edx,MB4-offset msg_w3 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; and eax,0FFFFFF00h +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long +; + + + + + + copy_long: + + ;; push es + ;; push ds + ;; pop es + ;; mov eax,ecx + ;; and ecx,-8 + ;; and eax,8-1 + ;; cld + ;; rep movsd + ;; mov ecx,eax + ;; pop es + ;; ret + ;; + + copy: + + IFAE ecx,32/4 + DO + mov eax,[esi] + ;; mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,32/4 + cmp ecx,32/4 + REPEATA + OD + pop ebp + pop edx + FI + IFAE ecx,4/4 + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + sub ecx,4/4 + REPEATA + OD + FI + + ret + + + + +XHEAD mwords_through_com_space + + mov eax,[ebp+thread_proot] + IFNZ eax,ds:[cpu_cr3] + + mark__ressource ebx,com_used + + mov edx,[ebx+thread_proot] ;;; may be not in its own address space + IFNZ edx,ds:[cpu_cr3] ;;; if source is small !!!!! + mov ds:[cpu_cr3],edx + mov cr3,edx + FI + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + + add edi,com0_base + + cmp ds:[tlb_invalidated],0 + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + + ELSE_ + + mark__ressource ebx,in_partner_space + + FI + + xret ,long + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + mov eax,linear_kernel_space + mov es,eax + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + cmp eax,ecx + cmovb ecx,eax + cmp ebx,ecx + cmovb ecx,ebx + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + lea eax,[esi+ecx] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_str_source,long + add esi,[ebx+as_base] + + lea eax,[edi+ecx] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_str_dest,long + + mov eax,[ebp+as_base] + add edi,eax + + test eax,eax + ;;;cmp eax,eax + IFZ + mov edx,[ebp+thread_proot] + IFNZ edx,ds:[cpu_cr3] ;; + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + FI + + cld + rep movsb ; as fast as movsd + + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + ELSE_ + ke 'cut_string' + + FI + + xret ,long + + + + + +XHEAD address_space_overflow_str_source + ke 'str_source_ovfl' + xret ,long + +XHEAD address_space_overflow_str_dest + ke 'str_dest_overfl' + xret ,long + + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +;XHEAD prepare_small_string_source +; +; shl eax,16 +; +; lea edx,[esi+ecx] +; sass__32 cmp,edx,MB4 +; IFB_ +; add esi,eax +; xret ,long +; FI +; +; lno___task eax,ebx +; mov eax,[eax*8+task_proot].proot_ptr +; mov al,0 +; mov ds:[cpu_cr3],eax +; mov ds:[tlb_invalidated],al +; mov cr3,eax +; xret ,long + + + + + + + align 16 + + + +fetch_next: + + mov [ebx+fine_state],locked_waiting + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+KR + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + jmp ipc_exit + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + ke '??' + jmp ipc_exit + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + ke '??' ;REDIR ends -------------------------- + jmp ipc_exit + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+KR + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov eax,[esp+ipc_eax] + mov ecx,[ebx+timeouts] + mov esi,[ebx+waiting_for] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + jmp ipc_restart + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + add esp,sizeof ipc_kernel_stack-2*4 + sub eax,eax + mov al,ipc_timeout+ipc_s + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + pop edx + pop eax + + mov ebp,[ebx+rcv_descriptor] + + cmp ebp,virtual_space_size + jae w_err + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret+KR + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + push eax + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + jmp ipc_exit + + + + align 16 + + +received_ok_ret: + + popad + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + IFZ word ptr [ebp+sizeof tcb-sizeof ipc_kernel_stack].ipc_esp,linear_space + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + CANDAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + +.erre (linear_space AND 3) ne 0 +.erre (linear_space lt 1000h) ; kernel start address MOD 64 K + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + lea esi,[ebp+sizeof tcb - (sizeof ipc_kernel_stack-2*4+2*4)] + mov ebx,offset reset_ipc_sysenter_ret+KR + + IFZ word ptr [esi+ipc_esp],linear_space + + add esi,(sizeof tcb-(sizeof iret_vec+2*4)) - (sizeof tcb-(sizeof ipc_kernel_stack-2*4+2*4)) + add ebx,(offset reset_ipc_sc_ret+KR) - (offset reset_ipc_sysenter_ret+KR) + FI + + mov [esi+4],eax + mov [esi],ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + +reset_ipc_sysenter_ret: + + pop eax + ke 'reset_ipc_sysenter' + jmp ipc_exit + + + +reset_ipc_sc_ret: + + pop eax + ke 'reset_ipc_sc' + + push linear_space + pop ds + push linear_space + pop es + + iretd + + + +.erre (linear_space AND 3) ne 0 +.erre (linear_space lt 1000h) ; kernel start address MOD 64 K + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll+KR + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +;ipcman_rerun_thread: +; +; pushad +; +; mov al,[ebp+fine_state] +; and al,NOT nwake +; +; CORZ al, +; IFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; IFAE [ebp+waiting_for],intr_sources +; mov [ebp+fine_state],running +; FI +; +; ELIFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; +; ELIFZ al, +; ELIFZ al, +; sub ecx,4 +; mov dword ptr [ecx],offset ret_from_poll+KR +; +; ELIFZ al, +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELIFZ al, +; mov al,[ebp+coarse_state] +; and al,nblocked+ndead +; CANDZ al,ndead +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELSE_ +; ke 'ill_mess_rerun' +; FI +; +; mov [esp+6*4],ecx +; mov [esp+2*4],ebp +; popad +; ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+KR + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],sysenter_present_bit + IFNC + ke '-processor does not support fast system calls' + FI + + mov ecx,sysenter_cs_msr + mov eax,kernel_exec + sub edx,edx + wrmsr + + mov ecx,sysenter_eip_msr + mov eax,offset ipc_sysenter+KR + sub edx,edx + wrmsr + + mov ecx,sysenter_esp_msr + mov eax,offset cpu_esp0 + sub edx,edx + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/ipcman.asm b/l4-x86/l4-y/kernel/ipcman.asm new file mode 100644 index 0000000..de11c5b --- /dev/null +++ b/l4-x86/l4-y/kernel/ipcman.asm @@ -0,0 +1,3512 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 04,07,00, 9582, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 04.07.00 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb +; public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + public ipcman_sysexit_to_user_instruction + public ipc_exit + + public kernel_ipc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for pIII + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push es + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr+KR + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + switch_space + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + jmp ipc_exit + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr+KR + jmp switch_context + FI + FI + + jmp switch_from_intr + + + + align 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + align 16 + + + +;---------------------------------------------------------------------------- +; +; INT 30h IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + kcod ends + + +ipc_sc: + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + call kernel_ipc + + push linear_space + pop ds + push linear_space + pop es + + iretd + + + + + + kcode + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX user esp +; EDX snd.w0 +; EBX snd.w1 +; EBP - +; ESI dest +; EDI msg.w2 +; +; EIP +; CS +; rcv descriptor +; I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov [esp+ipc_eax],offset receive_timeout_ret+KR + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + sub eax,eax + jmp ipc_exit + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+fine_state],locked_running + mov [ebp+fine_state],locked_waiting + + and eax,ipc_control_mask + mov esi,[esp+ipc_eax] + + mov edx,[ebx+as_base] + + mov [ebx+com_partner],ebp + mov [ebp+com_partner],ebx + + and esi,NOT (deceit+map_msg) + IFNZ + mov edi,[esi+edx+msg_dope] + and edi,0FFFFFF00h + or eax,edi + FI + + + mov edi,[ebp+rcv_descriptor] + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add eax,ipc_cut + and edi,NOT (deceit+map_msg) + + CANDNZ ,,long + + ; mov ecx,linear_kernel_space + ; mov es,ecx + + sub eax,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + + lea eax,[(ecx*4)+esi+msg_w3] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_mwords_source,long + + add esi,edx + + lea eax,[(ecx*4)+edi+msg_w3] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_mwords_dest,long + + mov eax,[ebp+as_base] + add edi,eax + + test eax,eax + xc z,mwords_through_com_space,long + + ;; sti + + mov edx,[edi+msg_size_dope] + shr edx,md_mwords + cmp ecx,edx + xc a,shorten_mwords,long + + mov edx,edi + sub ecx,2 + IFA + push esi + add esi,offset msg_w3 + add edi,offset msg_w3 + + IFAE ecx,32/4 + DO + mov eax,[esi] + ;; mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,32/4 + cmp ecx,32/4 + REPEATA + OD + FI + IFAE ecx,4/4 + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + sub ecx,4/4 + REPEATA + OD + FI + + ;cld + ;rep movsd + + pop esi + + FI + pop eax + pop ebx + + test eax,mask md_strings + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressources ebx,com_used,in_partner_space + + test edi,edi + IFNZ + or edi,map_msg + FI + + ;; cli + + mov ecx,[ebx+timeouts] + + FI + + test eax,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+ipc_ebx+2*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+ipc_ebx+2*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret+KR + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + align 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + ke 'shorten_mwords' + mov ecx,edx + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + +XHEAD address_space_overflow_mwords_source + ke 'mw_source_ovfl' + xret ,long + +XHEAD address_space_overflow_mwords_dest + ke 'mw_dest_overfl' + xret ,long + + + + + + + +XHEAD mwords_through_com_space + + mov eax,[ebp+thread_proot] + IFNZ eax,ds:[cpu_cr3] + + mark__ressource ebx,com_used + + mov edx,[ebx+thread_proot] ;;; may be not in its own address space + IFNZ edx,ds:[cpu_cr3] ;;; if source is small !!!!! + mov ds:[cpu_cr3],edx + mov cr3,edx + FI + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + + add edi,com0_base + + cmp ds:[tlb_invalidated],0 + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or eax,page_accessed+page_dirty + or ebx,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + + ELSE_ + + mark__ressource ebx,in_partner_space + + FI + + xret ,long + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + mov eax,linear_kernel_space + mov es,eax + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + and eax,7FFFFFFFh + and ebx,7FFFFFFFh + + mov ecx,MB4 + cmp eax,ecx + cmovb ecx,eax + cmp ebx,ecx + cmovb ecx,ebx + + + pushad + + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + lea eax,[esi+ecx] + cmp eax,[ebx+as_size] + xc a,address_space_overflow_str_source,long + add esi,[ebx+as_base] + + lea eax,[edi+ecx] + cmp eax,[ebp+as_size] + xc a,address_space_overflow_str_dest,long + + mov eax,[ebp+as_base] + add edi,eax + + test eax,eax + IFZ + mov edx,[ebp+thread_proot] + IFNZ edx,ds:[cpu_cr3] ;; + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + FI + + cld + rep movsb ; as fast as movsd + + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATS + + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + ELSE_ + ke 'cut_string' + + FI + + xret ,long + + + + + +XHEAD address_space_overflow_str_source + ke 'str_source_ovfl' + xret ,long + +XHEAD address_space_overflow_str_dest + ke 'str_dest_overfl' + xret ,long + + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + lea___pdir ecx,ebp + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + + + + + align 16 + + + +fetch_next: + + mov [ebx+fine_state],locked_waiting + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret+KR + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + sub eax,eax + jmp ipc_exit + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + ke '??' + jmp ipc_exit + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + ke '??' ;REDIR ends -------------------------- + jmp ipc_exit + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + test al,deceit + IFNZ + cmp esi,[ebx+virtual_sender] + xret z,long + FI + + + mov edi,[ebx+myself] + DO + mov dl,[ebp+coarse_state] + add ebp,sizeof tcb + test dl,auto_propagating + EXITZ + + test__page_writable ebp + EXITC + + test [ebp+coarse_state],ndead + EXITZ + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + sub ebp,sizeof tcb + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll+KR + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov eax,[esp+ipc_eax] + mov ecx,[ebx+timeouts] + mov esi,[ebx+waiting_for] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + mov edi,[ebx+myself] + + jmp ipc_restart + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + add esp,sizeof ipc_kernel_stack-2*4 + sub eax,eax + mov al,ipc_timeout+ipc_s + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + pop edx + pop eax + + mov ebp,[ebx+rcv_descriptor] + + cmp ebp,virtual_space_size + jae w_err + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret+KR + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + push eax + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + jmp ipc_exit + + + + align 16 + + +received_ok_ret: + + popad + jmp ipc_exit + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + jmp ipc_exit + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + jmp ipc_exit + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + IFZ word ptr [ebp+sizeof tcb-sizeof ipc_kernel_stack].ipc_esp,linear_space + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + CANDAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + +.erre (linear_space AND 3) ne 0 +.erre (linear_space lt 1000h) ; kernel start address MOD 64 K + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + lea esi,[ebp+sizeof tcb - (sizeof ipc_kernel_stack-2*4+2*4)] + mov ebx,offset reset_ipc_sysenter_ret+KR + + IFZ word ptr [esi+ipc_esp],linear_space + + add esi,(sizeof tcb-(sizeof iret_vec+2*4)) - (sizeof tcb-(sizeof ipc_kernel_stack-2*4+2*4)) + add ebx,(offset reset_ipc_sc_ret+KR) - (offset reset_ipc_sysenter_ret+KR) + FI + + mov [esi+4],eax + mov [esi],ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + +reset_ipc_sysenter_ret: + + pop eax + ke 'reset_ipc_sysenter' + jmp ipc_exit + + + +reset_ipc_sc_ret: + + pop eax + ke 'reset_ipc_sc' + + push linear_space + pop ds + push linear_space + pop es + + iretd + + + +.erre (linear_space AND 3) ne 0 +.erre (linear_space lt 1000h) ; kernel start address MOD 64 K + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll+KR + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0+KR] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +;ipcman_rerun_thread: +; +; pushad +; +; mov al,[ebp+fine_state] +; and al,NOT nwake +; +; CORZ al, +; IFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; IFAE [ebp+waiting_for],intr_sources +; mov [ebp+fine_state],running +; FI +; +; ELIFZ al, +; mov dword ptr [ecx],offset receive_timeout_ret+KR +; +; ELIFZ al, +; ELIFZ al, +; sub ecx,4 +; mov dword ptr [ecx],offset ret_from_poll+KR +; +; ELIFZ al, +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELIFZ al, +; mov al,[ebp+coarse_state] +; and al,nblocked+ndead +; CANDZ al,ndead +; mov dword ptr [ecx],offset send_ok_ret+KR +; +; ELSE_ +; ke 'ill_mess_rerun' +; FI +; +; mov [esp+6*4],ecx +; mov [esp+2*4],ebp +; popad +; ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc+KR + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc+KR + call define_idt_gate + + bt ds:[cpu_feature_flags],sysenter_present_bit + IFNC + ke '-processor does not support fast system calls' + FI + + mov ecx,sysenter_cs_msr + mov eax,kernel_exec + sub edx,edx + wrmsr + + mov ecx,sysenter_eip_msr + mov eax,offset ipc_sysenter+KR + sub edx,edx + wrmsr + + mov ecx,sysenter_esp_msr + mov eax,offset cpu_esp0 + sub edx,edx + wrmsr + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/kdebug.asm b/l4-x86/l4-y/kernel/kdebug.asm new file mode 100644 index 0000000..d38342a --- /dev/null +++ b/l4-x86/l4-y/kernel/kdebug.asm @@ -0,0 +1,5959 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 23,04,00, 581 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 23.04.00 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_root +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86,pIII + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + + +ipc_prot_state db 0 +ipc_prot_handler_active db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + +ipc_handler dd 0 +ipc_sysenter_address dd 0 + + +niltext db 0 + +page_fault_prot_state db 0 +page_fault_prot_handler_active db 0 + align 4 +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh +page_fault_handler dd 0 + + + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + +processor_family db 0 + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar+KR ; 0 + dd outstring+KR ; 1 + dd outcstring+KR ; 2 + dd clear_page+KR ; 3 + dd cursor+KR ; 4 + + dd outhex32+KR ; 5 + dd outhex20+KR ; 6 + dd outhex16+KR ; 7 + dd outhex12+KR ; 8 + dd outhex8+KR ; 9 + dd outhex4+KR ; 10 + dd outdec+KR ; 11 + + dd kd_incharety+KR; 12 + dd kd_inchar+KR ; 13 + dd inhex32+KR ; 14 + dd inhex16+KR ; 15 + dd inhex8+KR ; 16 + dd inhex32+KR ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + + ELIFA ebx,PM + sub ebx,KR + FI + + mov ax,ds:[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,ds:[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + cmp bl,'g' + REPEATNZ + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + + + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_root + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + IF kernel_x2 + kd____disp <6,lines-1,0,'LNKD('> + lno___prc eax + add al,'a' + kd____outchar + kd____disp <'): '> + ELSE + kd____disp <6,lines-1,0,'LNKD: '> + ENDIF + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler+KR + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ ss:[no_breakpoint_thread+PM],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ ss:[breakpoint_thread+PM],0 + cmp ss:[breakpoint_thread+PM],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp ss:[debug_exception_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ ss:[bx_size+PM],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + mov eax,[esi+waddr] + IFAE eax,offset small_virtual_spaces + kd____disp <6,4,60,' waddr : '> + kd____outhex32 + ELSE_ + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + FI + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + mov eax,[esi+as_base] + test eax,eax + IFNZ + kd____disp <6,0,39, 'smallspace:'> + kd____outhex32 + kd____disp <' size='> + mov eax,[esi+as_size] + shr eax,20 + kd____outdec + kd____disp <'MB'> + FI + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + push ds + push phys_mem + pop ds + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + pop ds + IFZ + mov al,0 + ret + FI + + IFZ esi,ebp + push ds + push phys_mem + pop ds + mov eax,[kdebug_esp] + pop ds + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + push ds + push phys_mem + pop ds + cmp ebp,[kdebug_esp] + pop ds + IFZ + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_root + ELIFZ al,'t' + mov eax,offset task_root + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword+KR + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__root eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir+KR + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page+KR + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_root + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],1 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault+KR + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + IFNZ [page_fault_prot_handler_active],0 + mov [page_fault_prot_handler_active],0 + mov eax,[page_fault_handler] + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov ebx,cr3 ; ensures that kdebug can run even if current + push ebx ; current address space has not sufficient + mov ebx,ss:[kernel_proot] ; memory mapped for kdebug + mov cr3,ebx ; + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM] + CANDBE eax,[page_fault_high+PM] + CANDB eax, ; do not protocol pseudo PFs in comspace +.errnz (offset com1_space+com1_space_size) ; otherwise a periodic inzterrupt (kb, e.g.) leads + ; to starvation if prot is on + mov ebx,cr2 + mov ecx,[esp+ip_eip+4] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ebx + mov cr3,ebx + pop es + pop ds + + popad + jmp ss:[page_fault_handler+PM] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],1 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc+KR + mov bl,ipc + call set_exception_handler + IFZ [ipc_sysenter_address],0 + mov ecx,sysenter_eip_msr + rdmsr + mov [ipc_sysenter_address],eax + mov eax,offset show_ipc_sysenter+KR + sub edx,edx + wrmsr + FI + ret + FI + IFZ al,'-' + IFNZ [ipc_prot_handler_active],0 + mov [ipc_prot_handler_active],0 + mov eax,[ipc_handler] + mov bl,ipc + call set_exception_handler + mov eax,[ipc_sysenter_address] + IFNZ eax,0 + mov [ipc_sysenter_address],0 + mov ecx,sysenter_eip_msr + sub edx,edx + wrmsr + FI + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + + popad + add esp,4 + jmp ss:[ipc_handler+PM] + + + + + +show_ipc_sysenter: + + mov esp,ss:[esp] + + pushad + push ds + push es + + push linear_kernel_space + pop ds + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop es + pop ds + popad + + mov esp,offset cpu_esp0 + jmp ss:[ipc_sysenter_address+PM] + + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor+KR + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,ss:[monitored_exception+PM] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,ss:[monitored_ec_min+PM] + movzx ecx,ss:[monitored_ec_max+PM] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop es + pop ds + + popad + + CORB ss:[monitored_exception+PM],8 + IFA ss:[monitored_exception+PM],14 + IFNZ ss:[monitored_exception+PM],17 + add esp,4 + FI + FI + + jmp ss:[monitored_exception_handler+PM] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler+KR + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop es + pop ds + + popad + add esp,4 + FI + + jmp ss:[timer_intr_handler+PM] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_root + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_root + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__root edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + mov edx,ds:[kernel_proot] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0,long + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + mov dword ptr [edi+trace_entry_type],80h + mov dword ptr [edi+trace_entry_string],'-4L ' + mov byte ptr [edi+trace_entry_string],8 + mov dword ptr [edi+trace_entry_string+4],'RATS' + mov dword ptr [edi+trace_entry_string+8],'T' + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + add edi,sizeof trace_buffer_entry + mov [trace_buffer_in_pointer],edi + sub ecx,sizeof trace_buffer_entry + + shr ecx,2 + sub eax,eax + cld + rep stosd + + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ ,,long + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + + mov al,[processor_family+PM] + IFZ al,p5_family + + mov ecx,P5_event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,P5_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P5_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P5_event_select_msr + mov eax,ebx + wrmsr + + ELIFZ al,p6_family + + mov ecx,P6_event_select0_msr + rdmsr + mov ebx,eax + btr eax,22 ; disable counters + wrmsr + mov ecx,P6_event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,P6_event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,P6_event_select0_msr + mov eax,ebx + wrmsr + FI + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov eax,[trace_buffer_in_pointer] + mov ebx,[eax+trace_entry_timestamp] + or ebx,[eax+trace_entry_timestamp+4] + IFZ + sub eax,[trace_buffer_begin] + CANDZ eax,sizeof trace_buffer_entry + ret + FI + + + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + kd____disp <' no trace buffer',13,10> + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_root + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer+KR + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer+KR + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + EXITZ + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +P5_event_select_msr equ 11h +P5_event_counter0_msr equ 12h +P5_event_counter1_msr equ 13h + + + +P5_rd_miss equ 000011b +P5_wr_miss equ 000100b +P5_rw_miss equ 101001b +P5_ex_miss equ 001110b + +P5_d_wback equ 000110b + +P5_rw_tlb equ 000010b +P5_ex_tlb equ 001101b + +P5_a_stall equ 00011111b +P5_w_stall equ 00011001b +P5_r_stall equ 00011010b +P5_x_stall equ 00011011b +P5_agi_stall equ 00011111b + +P5_bus_util equ 00011000b + +P5_pipline_flush equ 010101b + +P5_non_cache_rd equ 011110b +P5_ncache_refs equ 011110b +P5_locked_bus equ 011100b + +P5_mem2pipe equ 001001b +P5_bank_conf equ 001010b + + +P5_instrs_ex equ 010110b +P5_instrs_ex_V equ 010111b + + + + + + +P6_event_select0_msr equ 186h +P6_event_select1_msr equ 187h +P6_event_counter0_msr equ 0C1h +P6_event_counter1_msr equ 0C2h + + + + +;P6_rd_miss equ +P6_wr_miss equ 46h +P6_rw_miss equ 45h +P6_ex_miss equ 81h + +P6_d_wback equ 47h + +;P6_rw_tlb equ +P6_ex_tlb equ 85h + +P6_stalls equ 0A2h + +;P6_L2_rd_miss equ +P6_L2_wr_miss equ 25h +P6_L2_rw_miss equ 24h +P6_L2_ex_miss equ + +P6_L2_d_wback equ 27h + + + +P6_bus_util equ 62h + + +P6_instrs_ex equ 0C0h + + + + + + + +set_performance_tracing: + + push ds + push linear_kernel_space + pop ds + mov al,ds:[cpu_family] + pop ds + mov [processor_family],al + + IFNZ al,p5_family + CANDNZ al,p6_family + kd____disp <' not supported by this processor',13,10> + sub eax,eax ; Z! + ret + FI + + + kd____clear_page + call show_trace_perf_monitoring_mode + + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + + mov al,[processor_family] + IFZ al,p5_family,long + + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + ELIFZ al,p6_family,long + + kd____disp <'1 : L1 Dcache Misses (rd/wback)',13,10> + kd____disp <'2 : L2 Cache Misses (rd/wback)',13,10> + kd____disp <'i : Icache/ITLB Misses',13,10> + kd____disp <'I : Instructions/stalls',13,10> + kd____disp <'b : Bus Utilization/Instructions',13,10> + kd____disp <'x : uuee0/uuee1',13,10> + FI + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + mov ah,[processor_family] + IFZ ah,p5_family,long + + sub ebx,ebx + IFZ al,'i' + mov ebx,P5_instrs_ex + (P5_instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,P5_rw_miss + (P5_ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,P5_rw_tlb + (P5_ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,P5_r_stall + (P5_w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,P5_agi_stall + (P5_bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,P5_bus_util + (P5_instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,P5_event_select_msr + wrmsr + mov ecx,P5_event_counter0_msr + wrmsr + mov ecx,P5_event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,P5_event_select_msr + wrmsr + FI + + + ELIFZ ah,p6_family,long + + sub ebx,ebx + sub ecx,ecx + + IFZ al,'1' + mov bl,P6_rw_miss + mov cl,P6_d_wback + FI + IFZ al,'2' + mov bl,P6_L2_rw_miss + mov cl,P6_L2_d_wback + FI + IFZ al,'i' + mov bl,P6_ex_miss + mov cl,P6_ex_tlb + FI + IFZ al,'I' + mov bl,P6_instrs_ex + mov cl,P6_stalls + FI + IFZ al,'b' + mov bl,P6_bus_util + mov cl,P6_instrs_ex + FI + IFZ al,'x' + kd____disp <6,11,5,' PerfCnt0: '> + kd____inhex16 + movzx ebx,ax + kd____disp <' PerfCnt1: '> + kd____inhex16 + movzx ecx,ax + FI + + test ebx,ebx + IFNZ + push ecx + sub eax,eax + mov ecx,P6_event_select0_msr + wrmsr + mov ecx,P6_event_select1_msr + wrmsr + mov ecx,P6_event_counter0_msr + wrmsr + mov ecx,P6_event_counter1_msr + wrmsr + pop ecx + + bts ebx,22 ; enable counters + + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,10b + ELIFZ al,user_perf_mon + mov al,01b + ELSE_ + mov al,11b + FI + shl eax,16 + or ebx,eax + or ecx,eax + + mov eax,ecx + mov ecx,P6_event_select1_msr + wrmsr + mov eax,ebx + mov ecx,P6_event_select0_msr + wrmsr + FI + + + FI + + + test esp,esp ; NZ ! + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/kdiopc.asm b/l4-x86/l4-y/kernel/kdiopc.asm new file mode 100644 index 0000000..277000a --- /dev/null +++ b/l4-x86/l4-y/kernel/kdiopc.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86,pIII + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/l4-y/kernel/kernel.asm b/l4-x86/l4-y/kernel/kernel.asm new file mode 100644 index 0000000..7f0d1e2 --- /dev/null +++ b/l4-x86/l4-y/kernel/kernel.asm @@ -0,0 +1,78 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '04.04.00' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-Y Nucleus (PIII), Copyright (C) IBM 1997 & University of Karlsruhe 2000',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/ktest.asm b/l4-x86/l4-y/kernel/ktest.asm new file mode 100644 index 0000000..e076753 --- /dev/null +++ b/l4-x86/l4-y/kernel/ktest.asm @@ -0,0 +1,851 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 03,04,00, 16 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.04.00 ****** +;****** ****** +;********************************************************************* + + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86,pIII + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+2*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + +kernel_info_page equ 1000h + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + ipc___syscall + + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_1000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_16 : '> + mov eax,4 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc_128 : '> + mov eax,32 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc_512 : '> + mov eax,128 SHL md_mwords + call ping_1000 + + kd____disp <13,10,'ipc__4K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB4 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB4 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB4 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB4 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_rd4K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB4 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,0 + mov [ping_rcv_msg+msg_w3].buf_addr,0 + + mov [pong_snd_msg+msg_w3].str_len,0 + mov [pong_snd_msg+msg_w3].str_addr,0 + mov [pong_rcv_msg+msg_w3].buf_size,KB4 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call read_16 + + + if 0 + + kd____disp <13,10,'ipc_16K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB16 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB16 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB16 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB16 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + kd____disp <13,10,'ipc_64K : '> + + mov [ping_snd_msg+msg_w3].str_len,KB64 + mov [ping_snd_msg+msg_w3].str_addr,MB2 + mov [ping_rcv_msg+msg_w3].buf_size,KB64 + mov [ping_rcv_msg+msg_w3].buf_addr,MB2 + + mov [pong_snd_msg+msg_w3].str_len,KB64 + mov [pong_snd_msg+msg_w3].str_addr,MB2+KB64 + mov [pong_rcv_msg+msg_w3].buf_size,KB64 + mov [pong_rcv_msg+msg_w3].buf_addr,MB2+KB64 + + mov eax,(2 SHL md_mwords) + (1 SHL md_strings) + call ping_1000 + + + endif + call exit_ktest + + + mov eax,2 + cpuid + + ke 'done' + + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + + REPEAT + OD + + + + + + +ping_short_1000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + + mov [counter],1000 + + mov [cycles],0 + + rdtsc + push eax + clign 16 + + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + mov esi,pong_thread + ipc___syscall + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + +display_time_and_cycles: + + sub edx,edx + div ebx + + push eax + + mov ebx,1000000000 + mul ebx + mov ebx,ds:[kernel_info_page].cpu_clock_freq + div ebx + + sub edx,edx + mov ebx,1000 + div ebx + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + sub edx,edx + mov ebx,10 + div ebx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + kd____disp <' us, '> + + pop eax + + IFB_ eax,100000 + kd____disp <' '> + FI + IFB_ eax,10000 + kd____disp <' '> + FI + IFB_ eax,1000 + kd____disp <' '> + FI + IFB_ eax,100 + kd____disp <' '> + FI + IFB_ eax,10 + kd____disp <' '> + FI + kd____outdec + kd____disp <' cycles'> + + + ret + + + + + + +ping_1000: + + mov [ping_snd_msg+msg_dope],eax + mov [ping_snd_msg+msg_size_dope],eax + mov [ping_rcv_msg+msg_dope],eax + mov [ping_rcv_msg+msg_size_dope],eax + mov [pong_snd_msg+msg_dope],eax + mov [pong_snd_msg+msg_size_dope],eax + mov [pong_rcv_msg+msg_dope],eax + mov [pong_rcv_msg+msg_size_dope],eax + + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + + mov [counter],1000 + + rdtsc + push eax + clign 16 + + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ long + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,2*1000 + + call display_time_and_cycles + + ret + + + + + + + + +read_16: + + mov ebx,[ping_snd_msg+msg_w3].str_addr + mov ecx,16 + DO + mov edx,[ebx] + add ebx,KB4 + dec ecx + REPEATNZ + OD + + + mov [ping_snd_msg+msg_dope],eax + mov [ping_snd_msg+msg_size_dope],eax + mov [ping_rcv_msg+msg_dope],eax + mov [ping_rcv_msg+msg_size_dope],0 + mov [pong_rcv_msg+msg_dope],eax + mov [pong_rcv_msg+msg_size_dope],eax + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + ipc___syscall + + mov [counter],16 + + rdtsc + push eax + clign 16 + + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov edx,MB2+100 + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + prefetch edx + add edx,32 + prefetch edx + ipc___syscall + test al,al + EXITNZ long + add [ping_snd_msg+msg_w3].str_addr,KB4 + sub [counter],1 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + rdtsc + pop ebx + sub eax,ebx + mov ebx,16 + + call display_time_and_cycles + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + + + if pong_thread ne sigma1_task + + mov eax,(pong_thread-sigma1_task)/(sizeof tcb) + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + ipc___syscall + REPEAT + OD + + endif + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + ipc___syscall + + + mov eax,-1 + + + DO + clign 16 + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + ipc___syscall + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + + + align 16 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + rdtsc + push eax + + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + rdtsc + pop ebx + sub eax,ebx + mov ebx,127 + + call display_time_and_cycles + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/memctr.asm b/l4-x86/l4-y/kernel/memctr.asm new file mode 100644 index 0000000..8bf83f6 --- /dev/null +++ b/l4-x86/l4-y/kernel/memctr.asm @@ -0,0 +1,515 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + sub edx,edx + IFAE esp, + CANDB esp, + add edx,PM + FI + IF kernel_x2 + lno___prc eax + lea edx,[eax*4+edx] + ENDIF + mov eax,[edx+lowest_allocated_frame] + + test eax,eax + jnz initial_grab_frame + + + sub eax,eax + mov ecx,eax + lea edx,[eax-2] ; w0 = FFFFFFFE + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg + + mov esi,sigma0_task + sub edi,edi + + int ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + + ke <'-',0E5h,'0_err'> + FI + + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + sub eax,pagesize + + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + dec ch + REPEATNZ + OD + + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + mov [edx+lowest_allocated_frame],eax + + + + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + mov edi,offset physical_kernel_info_page + xpush edi + + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + mov eax,sigma0_task + call create_kernel_including_task + + call init_sigma0_space + + ret + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + mov ebx,ds:[sigma0_proot] + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + IF kernel_x2 + lno___prc edi + test edi,edi + IFNZ + mov eax,ds:[eax+next_kpage_link] + FI + ENDIF + mov dl,page_user_permit+page_present + call map_ur_page_initially + + lno___prc eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/pagctr.asm b/l4-x86/l4-y/kernel/pagctr.asm new file mode 100644 index 0000000..7eed1a1 --- /dev/null +++ b/l4-x86/l4-y/kernel/pagctr.asm @@ -0,0 +1,1187 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 14,04,00, 516 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 14.04.00 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn kernel_ipc:near + extrn set_proot_for_all_threads:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: + + pushad + + call grab_frame + mov edx,eax + + mov cr3,eax + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + + ELSE_ + + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + call alloc_initial_pagmap_pages + + mov esi,offset gdt+first_kernel_sgm + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm) + call alloc_kernel_pages + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + + mov eax,offset physical_kernel_info_page + IF kernel_x2 + lno___prc ecx + test cl,cl + IFNZ + mov eax,[eax+next_kpage_link] + FI + ENDIF + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + call alloc_kernel_pages + + + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + mov eax,cr0 + bts eax,31 + mov cr0,eax + + jmp $+2 + + mov edi,offset task_root + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + add edi,4 + cmp edi,offset task_root+tasks*4 + REPEATB + OD + + + mov ds:[kernel_proot],edx + mov ds:[empty_proot],ebx + + popad + ret + + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + DO + push eax + mov cl,page_present+page_write_permit + call grab_frame + call map_page_initially + pop eax + add esi,pagesize + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + + + + + + + icod ends + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 48 + + + icode + + +init_fresh_frame_pool: + + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + mov ecx,initial_fresh_frames + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + cli + + and eax,-pagesize + lea edx,[eax+PM] + + xchg ds:[first_free_fresh_frame],eax + mov [edx],eax + + inc ds:[free_fresh_frames] + + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + pop edi + ret + + FI + + inc ds:[free_fresh_frames] + + ke '-fframe_underflow' + + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + call request_fresh_frame + IFNC + push esi + + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + call request_fresh_frame + IFNC + call map_system_shared_page + IFC + call insert_into_fresh_frame_pool + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + + push ebp + mov ebp,edx + call set_proot_for_all_threads + pop ebp + + lea___pdir eax,edx + call flush_system_shared_page + pop ecx + + xret ,long + + + + + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + mov esi,ds:[empty_proot] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman init called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + push ds + push es + + DO + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task + + call kernel_ipc + + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + + DO + push edx + + sub ecx,ecx + mov eax,ecx + lea ebp,[ecx+(log2_)*4+map_msg] + lea edx,[ecx-2] ; w0 = FFFFFFFE + mov esi,sigma0_task + + push ds + push es + + call kernel_ipc + + pop es + pop ds + + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + xor ebx,edx + and ebx,-pagesize + CANDZ + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + sub ecx,ecx + lea eax,[ecx-1] + mov ebp,ecx + sub esi,esi + sub edi,edi + + call kernel_ipc + + REPEAT + OD + + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + mov ebx,ds:[kernel_proot] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + mov ecx,ds:[kernel_proot] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + + + + + + + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + mov esi,ds:[kernel_proot] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/pagfault.asm b/l4-x86/l4-y/kernel/pagfault.asm new file mode 100644 index 0000000..b4b3bfc --- /dev/null +++ b/l4-x86/l4-y/kernel/pagfault.asm @@ -0,0 +1,853 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 04,07,00, 9567, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 04.07.00 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn kernel_ipc:near + extrn ipc_exit:near + extrn ipcman_sysexit_to_user_instruction:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86,pIII + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + mov eax,offset page_fault_handler+KR + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + align 16 + + + + + + +page_fault_handler: + + + cmp ss:[esp+iret_eip+4],PM + xc ae,page_fault_pl0,long + + + ipre ec_present + + mov ebp,esp + + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + + mov edx,cr2 + + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + and ebp,-sizeof tcb + + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + + IFB_ edx,,long + + test [ebp+fine_state],nlock + IFNZ + cmp ebx,-1 + xc z,occurred_within_ipc,long + CANDNZ + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + mov esi,[ebp+pager] + sub edi,edi + sub ecx,ecx + sub eax,eax + mov ebp,32*4+map_msg + + call kernel_ipc + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + + test [ebp+ressources],in_partner_space + jnz partner_space_fault + + + call push_ipc_state + + IFNZ + push edx + push ebp + push ds + + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + mov ebp,32*4+map_msg + + call kernel_ipc + + pop ds + pop ebp + pop edx + + test al,ipc_error_mask + IFZ + ;; test__page_present edx + ;; CANDNC + + call pop_ipc_state + + ipost + FI + FI + jmp cancel_if_within_ipc + + FI + + + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + cmp eax,offset small_virtual_spaces+small_virtual_spaces_size + jb small_space_com_write_fault + + cmp eax,shared_table_base + jb short addressing_error + + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + cmp eax,offset iopbm + jb short addressing_error + + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + cmp eax,offset com0_space + jb short addressing_error + + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin+KR + CANDBE eax,offset ipc_critical_region_end+KR + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDX faulting virtual address (may be rel to large space) +; +; EAX,EBX,ECX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + + + xpdir eax,edx + + + mov esi,ebp + sub edx,[ebp+as_base] + + CORC + IFAE edx,[ebp+as_size] + + mov esi,[ebp+com_partner] + add edx,[ebp+as_base] + mov edi,edx + sub edi,[esi+as_base] + CORC + IFAE edi,[esi+as_size] + ke 'small_com_err' + FI + FI + + mov edi,ds:[cpu_cr3] + lea edi,[(eax*4)+edi+PM] + test byte ptr [edi],page_present + xret nz,long + + + mov esi,[esi+thread_proot] + add esi,PM + + mov ch,ds:[log2_small_space_size_DIV_MB4] + mov cl,32-22 + sub cl,ch + + mov eax,edx + shl eax,cl + shr eax,cl + xpdir eax,eax + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + mov edi,ds:[kernel_proot] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + + mov esi,[ebp+com_partner] ; com partner is tcb address + + mov edi,[ebp+waddr] + + mark__ressource ebp,com_used + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + pop esi + REPEAT + OD + + + + + + +small_space_com_write_fault: + + mov edi,ebp + + mov ebp,[ebp+com_partner] ; com partner is tcb address + sub eax,[ebp+as_base] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + +;---------------------------------------------------------------------------- +; +; partner-space write fault (msg copy small -> large, in large as +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +partner_space_fault: + + + mov eax,edx + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + ipost + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__root eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + +.erre KR ge PM + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + IFZ eax,offset ipcman_sysexit_to_user_instruction+KR + + mov [esp+iret_eip+4+4],offset ipc_exit+KR + mov [esp+iret_cs+4+4],kernel_exec + btr [esp+iret_eflags+4+4],i_flag + mov eax,[esp+iret_esp+4+4] + mov [esp+iret_esp+4+4+4],eax + + pop eax + xret ,long + FI + + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + push edx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + mov ecx,ss:[kernel_proot] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + mov dh,cl + test cl,page_present + IFNZ + test cl,superpage + CANDZ + and ecx,-pagesize + xptab eax,eax + and dh,byte ptr ss:[(eax*4)+ecx+PM] + FI + and dh,dl + IFZ dh,dl + and byte ptr ss:[esp+iret_eflags+5*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+5*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+5*4],4 + + pop edx + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/pagmap.asm b/l4-x86/l4-y/kernel/pagmap.asm new file mode 100644 index 0000000..d85e905 --- /dev/null +++ b/l4-x86/l4-y/kernel/pagmap.asm @@ -0,0 +1,1973 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 25,03,00, 46 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.03.00 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86,pIII + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir + mov eax,sizeof shadow_pdir + call alloc_kernel_pages + + mov esi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + call alloc_kernel_pages + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + call alloc_kernel_pages + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + call alloc_kernel_pages + + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + + + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc+KR + call define_idt_gate + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + push offset grant_page_+KR + jmp do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage special ext: set/reset PCD bits +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + mov ch,cl + mov cl,al + shr cl,2 + shr eax,cl + shl eax,cl + sub cl,log2_pagesize + IFNC + + push offset unmap_fpage_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + push eax + + test ecx,ecx + IFNS + test ch,page_write_permit + IFNZ + push offset unmap_page+KR + jmp short do_fpage + FI + push offset unmap_write_page+KR + jmp short do_fpage + FI + + bt ecx,30 + IFNC + test ch,page_write_permit + IFNZ + push offset flush_page+KR + jmp short do_fpage + FI + push offset flush_write_page+KR + jmp short do_fpage + FI + + test ch,page_cache_disable + IFZ + push offset set_page_cacheable+KR + ELSE_ + push offset set_page_uncacheable+KR + FI + jmp short do_fpage + + + + unmap_fpage_ret: + + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + push offset map_page+KR + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + + + + + + +do_fpage: + + mov ebx,esp + and ebx,-sizeof tcb + + mov ebp,cr3 + IFNZ [ebx+as_base],0 + mov ebp,[ebx+thread_proot] + mov cr3,ebp + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + FI + +;; mov ebp,cr3 +;; IFAE , +;; mov ebp,esp +;; and ebp,-sizeof tcb +;; mov ebp,[ebp+thread_proot] +;; FI + + + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__root edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + ;; and ebx,[ebp+map_mask] + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + push edx + + mov edx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,edx + mov bl,[edx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize;;;;;;;;0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + pop ebx + xc z,unmap_in_own_address_space + + pop edx + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + test ebx,1 + IFNZ + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + + ELSE_ + push edx + mov ebx,edx + and edx,(pagesize-1) AND -4 + shr ebx,log2_pagesize + shl edx,log2_pagesize-2 + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ebx,(pagesize-1) AND -4 + shl ebx,2*log2_pagesize-4 + add edx,ebx + invlpg [edx] + pop edx + FI + + + cmp edx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp edx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + push ebx + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + pop ebx + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + + + test ebx,1 + IFZ + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -4 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -4 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + FI + + xchg ebp,[esp] + mov byte ptr [ebp+tlb_flush_indicator],2 + xchg ebp,[esp] + xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; set page cacheable/uncacheable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + +set_page_cacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT (page_cache_disable+page_write_through) + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + +set_page_uncacheable: + + IFB_ esi, + + mov eax,[ebp].cache0 + + or byte ptr [esi],page_cache_disable+page_write_through + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + mov edx,[ebp+thread_proot] + add edx,PM + + mov ecx,esp + and ecx,-sizeof tcb + mov ecx,[ebp+thread_proot] + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret+KR + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page+KR + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + mov ecx,ds:[sigma0_proot] + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end diff --git a/l4-x86/l4-y/kernel/proj.err b/l4-x86/l4-y/kernel/proj.err new file mode 100644 index 0000000..6f34825 --- /dev/null +++ b/l4-x86/l4-y/kernel/proj.err @@ -0,0 +1,7 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1052: file 'C:\ln-21\make\make-ln' not found +Stop. +Loading NMAKE diff --git a/l4-x86/l4-y/kernel/sgmctr.asm b/l4-x86/l4-y/kernel/sgmctr.asm new file mode 100644 index 0000000..19c003d --- /dev/null +++ b/l4-x86/l4-y/kernel/sgmctr.asm @@ -0,0 +1,264 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.09.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + + + + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS kernel_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6+KR,kernel_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + + add ds:[logical_info_page].kdebug_exception,KR + add dword ptr ss:[esp],KR + ret + + + align 4 + + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + +.errnz virtual_space_size AND (MB4-1) + + +.xall +initial_gdt dd 0,0 ; dummy seg + + IF KR EQ 0 + descriptor xr32, dpl0, PM, + ELSE + descriptor xr32, dpl0, 0, ; 08 : kernel_exec + ENDIF + descriptor rw32, dpl0, 0, ; 10 : linear_kernel_space + + descriptor rw32, dpl3, 0, user_space_size ; 18 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 20 : linear space + + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/l4-y/kernel/sigma0.asm b/l4-x86/l4-y/kernel/sigma0.asm new file mode 100644 index 0000000..23b9b8f --- /dev/null +++ b/l4-x86/l4-y/kernel/sigma0.asm @@ -0,0 +1,767 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + ; CORZ al,dedicated_mem + ; CORZ al,ah + ; IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + ; FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/l4-y/kernel/start.asm b/l4-x86/l4-y/kernel/start.asm new file mode 100644 index 0000000..a202a24 --- /dev/null +++ b/l4-x86/l4-y/kernel/start.asm @@ -0,0 +1,357 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 24,08,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + + + + + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +.list + + +ok_for x86,pIII + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + strt ends + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + call init_cpuctr + call init_pagfault + call init_pagmap + call init_fresh_frame_pool + call init_schedcb + call init_tcbman + call init_dispatcher + call init_ipcman + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts + + bt ds:[cpu_feature_flags],on_chip_apic_bit +; IFC +; call init_apic +; ELSE_ + call init_rtc_timer +; FI + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + mov eax,2 + cpuid + + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + + jmp ptabman_start + + + + + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/startpc.asm b/l4-x86/l4-y/kernel/startpc.asm new file mode 100644 index 0000000..0bb7bcd --- /dev/null +++ b/l4-x86/l4-y/kernel/startpc.asm @@ -0,0 +1,1308 @@ +include l4pre.inc + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86,pIII + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + + sub ax,ax + mov ds,ax + mov ax,cs + mov es,ax + mov si,offset initial_gdt + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + push 0 + push cs + push lowword offset protected_mode_from_real_mode + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + + cli + + mov esp,offset bootstack + + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + mov edx,ds + mov ss,edx + mov es,edx + + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + DO + cmp eax,2BADB002h + REPEATNZ + OD + + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + + mov [edx+start_ebx+physical_kernel_info_page],ebx + + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + + inrtc 80h ;C01 ms + + + + + + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + mov esp,offset bootstack + + mov eax,initial_tss + ltr ax + + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + + inrtc 0 ; enable NMI !!! + + call define_8259_base + call init_interrupt_catcher + + call init_nmi + + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure+KR + call define_idt_gate + + inrtc 0 + + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic1_icw4,al ; special fully nested mode !! + + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + mov al,01h ;;;;;;---- special test for Uwe ------------------------------------------- + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + IFB_ ecx,16 + + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher+KR + call define_idt_gate + + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int+KR + call define_idt_gate + + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + inrtc rtc_reg_c ; reset timer intr line + + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +reset: + + mov edx,ecx + + cli + inrtc 80h ; disable NMI + + sub eax,eax + mov dr7,eax ; disable all breakpoints + + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + ; Select status register A from RTC + + mov al,rtc_reg_a + out rtc_address,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + + ; Wait for UIP (update in progress) flag to disappear + + DO + in al,rtc_data + and al,80h + REPEATNZ + OD + + ; Wait for UIP flag to appear again. This indicates + ; that a second has passed + + DO + in al,rtc_data + and al,80h + REPEATZ + OD + + pop eax + ret + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 diff --git a/l4-x86/l4-y/kernel/tables.asm b/l4-x86/l4-y/kernel/tables.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/l4-y/kernel/tables.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/tcbman.asm b/l4-x86/l4-y/kernel/tcbman.asm new file mode 100644 index 0000000..526e38e --- /dev/null +++ b/l4-x86/l4-y/kernel/tcbman.asm @@ -0,0 +1,852 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 26,06,00, 9546 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 26.06.00 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn tunnel_to:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86,pIII + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc+KR + call define_idt_gate + + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + jmp ebx + + + icod ends + + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + CORB ebp,dispatcher_table + IFAE ebp,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + + + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + lno___task edx,ebp ; be mult inserted into sndq + + call dispatcher_open_tcb + call ipcman_open_tcb + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + +lthread_ex_regs_restart: + + mov ebp,esp + and ebp,-sizeof tcb + + pushad + + mov edi,eax + + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + test [ebp+coarse_state],ndead + IFZ + pushad + + mov ebx,esp + and ebx,-sizeof tcb + + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + call create_thread + + popad + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,(max_lthread_no SHL lthread_no) + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + add esp,8*4 + tpost ,ds,es + + FI + + + bt edi,ex_regs_update_flag + IFC + bt edi,ex_regs_auto_propagating_flag + IFC + CANDL eax,max_lthread_no + or [ebp+coarse_state],auto_propagating + ELSE_ + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + + + lea edi,[ebp+sizeof tcb-sizeof int_pm_stack] + + IFZ word ptr [edi].ip_ss,linear_space + + IFNZ ecx,-1 + xchg ecx,[edi].ip_esp + ELSE_ + mov ecx,[edi].ip_esp + FI + + IFNZ edx,-1 + + xchg edx,[edi].ip_eip + + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + + ELSE_ + mov edx,[edi].ip_eip + FI + + mov eax,[edi].ip_eflags + + ELSE_ long + + push ebx + push esi + + lea esi,[ebp+sizeof tcb-sizeof ipc_kernel_stack] + + push esi + + mov eax,[esi+ipc_esp] + + IFZ ecx,-1 + mov ebx,eax + ELSE_ + lea ebx,[ecx-sizeof ipc_user_stack] + FI + + mov edi,esp + and edi,-sizeof tcb + + call tunnel_to + test__page_present eax + CORC + test__page_writable ebx + lea ebx,[ebx+4] + test__page_writable ebx + lea ebx,[ebx-4] + IFC + mov cl,[eax] + add byte ptr [ebx],0 + add byte ptr [ebx+4],0 + xchg edi,ebp + call tunnel_to + + add esp,3*4 + popad + jmp lthread_ex_regs_restart + FI + + mov ecx,edx + mov edx,[eax] + mov eax,ecx + IFZ ecx,-1 + mov ecx,edx + FI + mov [ebx],ecx + mov word ptr [ebx+4],linear_space_exec + + xchg edi,ebp + call tunnel_to + xchg edi,ebp + + pop esi + + mov [esi+ipc_esp],ebx + lea ecx,[eax+sizeof ipc_user_stack] + + pop esi + pop ebx + + IFNZ eax,-1 + pushad + call cancel_if_within_ipc + IFZ al,running + call reset_running_thread + FI + popad + FI + + mov eax,0202h ; pseudo EFLAGS + + FI + + + + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + mov esi,[ebp+pager] + FI + + + + add esp,8*4 + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + IFZ [ebp+fine_state],running + ret + FI + + + ke 'reset_running_thread' + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + mov dword ptr [esi],offset reset_running_thread_ret+KR + + mov dword ptr [esi+4],linear_space + mov dword ptr [esi+8],linear_space + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + mov ebp,ebp + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + FI + + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + mov [ebp+coarse_state],ndead+nblocked + + + call init_sndq ; must be done before (!) + ; myself initiated + + + push eax + mov eax,esp + and eax,-sizeof tcb + + mov [ebp+pager],esi + + lno___task esi,ebp + load__root esi,esi + mov [ebp+thread_proot],esi + + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + + mov esi,[eax+as_base] + mov [ebp+as_base],esi + mov esi,[eax+as_size] + mov [ebp+as_size],esi + mov esi,[eax+thread_segment] + mov [ebp+thread_segment],esi + mov esi,[eax+thread_segment+4] + mov [ebp+thread_segment+4],esi + + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + + ELSE_ + mov [ebp+as_base],0 + mov [ebp+as_size],virtual_space_size + mov [ebp+thread_segment],((virtual_space_size SHR 12)-1) AND 0FFFFh + mov [ebp+thread_segment+4],00C0F300h+(((virtual_space_size SHR 12)-1) AND 000F0000h) + + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + mov [ebp+myself],esi + + pop eax + + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + mov dword ptr [ebx],offset reset_running_thread_ret+KR + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + mov dword ptr [ebx+ip_es+4],linear_space + + + + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + shr eax,16 + mov [ebp+max_controlled_prio],al + + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + IFB_ ebp,-1 ;;; max_root_tcb + + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + mov [ebp+fine_state],running + + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + call cancel_if_within_ipc + popad + + call detach_coprocessor + + call dispatcher_close_tcb + + push eax + push ebp + + mov [ebp+coarse_state],unused_tcb + sub eax,eax + mov [ebp+myself],eax + + and ebp,-pagesize + mov al,pagesize/sizeof tcb + DO + cmp [ebp+coarse_state],unused_tcb + EXITNZ + add ebp,sizeof tcb + dec al + REPEATNZ + OD + IFZ + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + mov ebp,esp + and ebp,-sizeof tcb + + and [ebp+coarse_state],NOT ndead + + DO + sub ecx,ecx + mov esi,ecx + mov edi,ecx + lea eax,[ecx-1] + mov ebp,ecx + int ipc + REPEAT + OD + + + + + + + + icode + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + call create_thread + pop ecx + + IFZ ebp,dispatcher_tcb + mov [ebp+myself],-1 + ELSE_ + mark__ready ebp + FI + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/x.asm b/l4-x86/l4-y/kernel/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/l4-y/kernel/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernel/y.asm b/l4-x86/l4-y/kernel/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/l4-y/kernel/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/l4-y/kernel/yoonseva.asm b/l4-x86/l4-y/kernel/yoonseva.asm new file mode 100644 index 0000000..ef1ed69 --- /dev/null +++ b/l4-x86/l4-y/kernel/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86,pIII + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),kernel_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/adrspac5.inc b/l4-x86/l4-y/kernifc/adrspac5.inc new file mode 100644 index 0000000..82639ec --- /dev/null +++ b/l4-x86/l4-y/kernifc/adrspac5.inc @@ -0,0 +1,207 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ((64+64)*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ((88-64)*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) + + small_virtual_spaces db small_virtual_spaces_size dup (?) + + tcb_space db tcb_space_size dup (?) + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! + pnode_space db pnode_space_size dup (?) ; dyn allocated ! + + reserved_space_1 db reserved_space_1_size dup (?) + + pdir_space db pdir_space_size dup (?) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! + + dd vint_size/4 dup (?) + iopbm dd iopbm_size/4 dup (?) + ldt dd ldt_size/4 dup (?) + + reserved_space_2 db reserved_space_2_size dup (?) + + ptab_space db ptab_space_size dup (?) + com0_space db com0_space_size dup (?) + com1_space db com1_space_size dup (?) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) + ptab_backlink dd max_ptabs dup (?) + chapter_map db max_ptabs*chapters_per_page dup (?) + + reserved_space_3 db 00BF3000h-(max_ptabs*(chapters_per_page+4))-4*KB4-KB256 dup (?) ;REDIR: -KB256 + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) + local_apic dd KB4/4 dup (?) + + logical_info_page db KB4 dup (?) + + db 100h-8 dup (?) + gdt dd 8*2*4/4 dup (?) + db 4 dup (?) + cpu_cb db 128+4 dup (?) + sched_cb db 16*8+64 dup (?) + intr_cb db 16*4 dup (?) + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_root dd tasks dup (?) ; | + xxroot_end_marker dd 1 dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + + dd (kernel_r_tables_size - offset kernel_resident_tables) + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_roots struc + + db offset task_root dup (?) + + empty_proot dd 0 + kernel_proot dd 0 + sigma0_proot dd 0 + +special_roots ends + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) + + + +kernel_relocation equ PM + +KR equ kernel_relocation diff --git a/l4-x86/l4-y/kernifc/adrspace.inc b/l4-x86/l4-y/kernifc/adrspace.inc new file mode 100644 index 0000000..45ad26d --- /dev/null +++ b/l4-x86/l4-y/kernifc/adrspace.inc @@ -0,0 +1,30 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ PIII + +subtitle L4/PIII Version Y + +kernel_type = pIII + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/l4-y/kernifc/apic.inc b/l4-x86/l4-y/kernifc/apic.inc new file mode 100644 index 0000000..61f951b --- /dev/null +++ b/l4-x86/l4-y/kernifc/apic.inc @@ -0,0 +1,70 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/contents b/l4-x86/l4-y/kernifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/l4-y/kernifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/cpucb.inc b/l4-x86/l4-y/kernifc/cpucb.inc new file mode 100644 index 0000000..f539fad --- /dev/null +++ b/l4-x86/l4-y/kernifc/cpucb.inc @@ -0,0 +1,12 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + IF (kernel_type EQ pIII) + +include cpucb6.inc + + ENDIF + diff --git a/l4-x86/l4-y/kernifc/cpucb5.inc b/l4-x86/l4-y/kernifc/cpucb5.inc new file mode 100644 index 0000000..ffa596e --- /dev/null +++ b/l4-x86/l4-y/kernifc/cpucb5.inc @@ -0,0 +1,293 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y/kernifc/cpucb6.inc b/l4-x86/l4-y/kernifc/cpucb6.inc new file mode 100644 index 0000000..ac6ac5e --- /dev/null +++ b/l4-x86/l4-y/kernifc/cpucb6.inc @@ -0,0 +1,308 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + cpu_family db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination tcb +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDX, EDI scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + + + mov edi,[ebp+thread_segment] + mov ds:[gdt+linear_space/8*8],edi + mov ds:[gdt+linear_space_exec/8*8],edi + + mov edi,[ebp+thread_segment+4] + mov ds:[gdt+linear_space/8*8+4],edi + add edi,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],edi + + IFNS + mov edi,[ebp+thread_proot] + CANDNZ edi,ds:[cpu_cr3] + mov ds:[cpu_cr3],edi + mov dword ptr ds:[tlb_invalidated],edi + mov cr3,edi + FI + mov ebp,linear_space + mov ds,ebp + mov es,ebp + + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +unmrk_ressources macro reg,rscr1,rscr2 + + and [reg+ressources],NOT (mask rscr1 + mask rscr2) + endm + + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number ( 0 / 1 ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + IF kernel_x2 + str ®&hl + and reg,11b + ELSE + sub reg,reg + ENDIF + endm + + + + +;---------------------------------------------------------------------------- +; +; machine specific registers +; +;---------------------------------------------------------------------------- + + +sysenter_cs_msr equ 174h +sysenter_esp_msr equ 175h +sysenter_eip_msr equ 176h + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +sysenter_present_bit equ 11 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/l4-y/kernifc/intrifc.inc b/l4-x86/l4-y/kernifc/intrifc.inc new file mode 100644 index 0000000..9a0d7ce --- /dev/null +++ b/l4-x86/l4-y/kernifc/intrifc.inc @@ -0,0 +1,357 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_es dd 0 + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + +;---------------------------------------------------------------------------- +; +; ipc sysenter stack descriptions +; +;---------------------------------------------------------------------------- + + + + +ipc_kernel_stack struc + + ipc_edx dd 0 + ipc_ebx dd 0 + ipc_eax dd 0 + ipc_esp dd 0 + +ipc_kernel_stack ends + + +ipc_user_stack struc + + ipc_user_eip dd 0 + ipc_user_cs dd 0 + ipc_user_rcv_descriptor dd 0 + ipc_user_timeouts dd 0 + +ipc_user_stack ends + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + push es + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop es + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/kpage.inc b/l4-x86/l4-y/kernifc/kpage.inc new file mode 100644 index 0000000..dec0015 --- /dev/null +++ b/l4-x86/l4-y/kernifc/kpage.inc @@ -0,0 +1,102 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/l4-y/kernifc/l4const.inc b/l4-x86/l4-y/kernifc/l4const.inc new file mode 100644 index 0000000..e93d85d --- /dev/null +++ b/l4-x86/l4-y/kernifc/l4const.inc @@ -0,0 +1,101 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +kernel_exec equ 0008h +linear_kernel_space equ 0010h + +linear_space equ (0018h+3) +linear_space_exec equ (0020h+3) + +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h + +p5_family equ 5 +p6_family equ 6 + +other_family equ 0 + \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/l4kd.inc b/l4-x86/l4-y/kernifc/l4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/l4-y/kernifc/l4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/l4-y/kernifc/l4pre.inc b/l4-x86/l4-y/kernifc/l4pre.inc new file mode 100644 index 0000000..166d77f --- /dev/null +++ b/l4-x86/l4-y/kernifc/l4pre.inc @@ -0,0 +1,826 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + + +cmovx macro cc,d,s +db 0Fh,&cc,0C0h+&d&code*8+&s&code +endm + + +cmovb macro d,s +cmovx 42h,d,s +endm + + +cmovs macro d,s +cmovx 48h,d,s +endm + + +cmovg macro d,s +cmovx 4Fh,d,s +endm + + +sysenter macro + db 0Fh,34h + endm + + +sysexit macro + db 0Fh,35h + endm + + +prefetch macro s +db 0Fh,18h,8+&s&code +endm + + + +clign macro alignment + local xx + jmp short xx + align alignment + xx: +endm + + + + + + + + + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/l4-y/kernifc/lbmac.inc b/l4-x86/l4-y/kernifc/lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/l4-y/kernifc/lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/l4-y/kernifc/pagcb.inc b/l4-x86/l4-y/kernifc/pagcb.inc new file mode 100644 index 0000000..d777340 --- /dev/null +++ b/l4-x86/l4-y/kernifc/pagcb.inc @@ -0,0 +1,17 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + +pagman_control_block ends \ No newline at end of file diff --git a/l4-x86/l4-y/kernifc/pagconst.inc b/l4-x86/l4-y/kernifc/pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/l4-y/kernifc/pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/l4-y/kernifc/pagmac.inc b/l4-x86/l4-y/kernifc/pagmac.inc new file mode 100644 index 0000000..6674bce --- /dev/null +++ b/l4-x86/l4-y/kernifc/pagmac.inc @@ -0,0 +1,86 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + + +load__root macro reg,task_no + + mov reg,ds:[(task_no*4)+task_root] + endm + + +store_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + +store_inactive_root macro reg,task_no + + mov ds:[(task_no*4)+task_root],reg + endm + + + + + diff --git a/l4-x86/l4-y/kernifc/perfmon.inc b/l4-x86/l4-y/kernifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/l4-y/kernifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/l4-y/kernifc/pnodes.inc b/l4-x86/l4-y/kernifc/pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/l4-y/kernifc/pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/l4-y/kernifc/proj.err b/l4-x86/l4-y/kernifc/proj.err new file mode 100644 index 0000000..869585b --- /dev/null +++ b/l4-x86/l4-y/kernifc/proj.err @@ -0,0 +1,213 @@ +Loading NMAKE + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + cd \ln-21\src\kernel + ..\..\make\xml-pent adrsman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: adrsman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent cpuctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: cpuctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent dispatch asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: dispatch.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent emuctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: emuctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent intctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: intctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ipcman5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ipcman5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdebug asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdebug.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent kdiopc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: kdiopc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent ktest5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: ktest5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent memctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: memctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagctr5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagctr5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagfault asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagfault.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent pagmap5 as5 +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: pagmap5.as5 + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sgmctr asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sgmctr.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent sigma0 asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: sigma0.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent start asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: start.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent startpc asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: startpc.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent tcbman asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: tcbman.asm + +C:\ln-21\src\kernel> + + cd \ln-21\src\kernel + ..\..\make\xml-pent yoonseva asm +Microsoft (R) Macro Assembler Version 6.11 +Copyright (C) Microsoft Corp 1981-1993. All rights reserved. + + Assembling: yoonseva.asm + +C:\ln-21\src\kernel> + + cd \ln-21\bin-pent + link @ln.rsp + +Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992 +Copyright (C) Microsoft Corp 1984-1992. All rights reserved. + +Object Modules [.obj]: kernel5+ +Object Modules [.obj]: startpc+ +Object Modules [.obj]: start+ +Object Modules [.obj]: cpuctr5+ +Object Modules [.obj]: ipcman5+ +Object Modules [.obj]: dispatch+ +Object Modules [.obj]: intctr+ +Object Modules [.obj]: tcbman+ +Object Modules [.obj]: memctr+ +Object Modules [.obj]: sgmctr+ +Object Modules [.obj]: pagctr5+ +Object Modules [.obj]: pagfault+ +Object Modules [.obj]: pagmap5+ +Object Modules [.obj]: adrsman5+ +Object Modules [.obj]: emuctr+ +Object Modules [.obj]: yoonseva+ +Object Modules [.obj]: kdiopc+ +Object Modules [.obj]: kdebug+ +Object Modules [.obj]: sigma0+ +Object Modules [.obj]: ktest5,ln.exe,ln.map; +LINK : warning L4021: no stack segment + +sigma0.obj(sigma0.asm) : error L2029: 'ide_stack' : unresolved external +sigma0.obj(sigma0.asm) : error L2029: 'ide_start' : unresolved external +start.obj(start.asm) : error L2029: 'ide_end' : unresolved external +start.obj(start.asm) : error L2029: 'ide_begin' : unresolved external + + +There were 4 errors detected +NMAKE : fatal error U1077: 'LINK' : return code '2' +Stop. diff --git a/l4-x86/l4-y/kernifc/schedcb.inc b/l4-x86/l4-y/kernifc/schedcb.inc new file mode 100644 index 0000000..8f80035 --- /dev/null +++ b/l4-x86/l4-y/kernifc/schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/l4-y/kernifc/schedcb2.inc b/l4-x86/l4-y/kernifc/schedcb2.inc new file mode 100644 index 0000000..b4c08c4 --- /dev/null +++ b/l4-x86/l4-y/kernifc/schedcb2.inc @@ -0,0 +1,35 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + diff --git a/l4-x86/l4-y/kernifc/small-as.inc b/l4-x86/l4-y/kernifc/small-as.inc new file mode 100644 index 0000000..1f4f2a5 --- /dev/null +++ b/l4-x86/l4-y/kernifc/small-as.inc @@ -0,0 +1,187 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + diff --git a/l4-x86/l4-y/kernifc/tcb.inc b/l4-x86/l4-y/kernifc/tcb.inc new file mode 100644 index 0000000..6d2f097 --- /dev/null +++ b/l4-x86/l4-y/kernifc/tcb.inc @@ -0,0 +1,274 @@ +new_tcb_version equ 0f2h ; 14.04.96 + +empty_tcb equ 0FFh + + + +thread_control_block struc + + soon_wakeup_link dd 0 + late_wakeup_link dd 0 + wakeup_low dd 0 + rem_timeslice db 0 + timeslice db 0 + max_controlled_prio db 0 + prio db 0 + + sndq_root dd 0,0 + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + + ready_llink dd 0,0 + com_partner dd 0 + thread_proot dd 0 + + thread_segment dd 0,0 + as_base dd 0 + as_size dd 0 + + + myself dd 0 + waiting_for dd 0 + waddr dd 0 + mword2 dd 0 + + fine_state db 0 + coarse_state db 0 + list_state db 0 + ressources db 0 + thread_esp dd 0 + rcv_descriptor dd 0 + timeouts dd 0 + + cpu_clock_low dd 0 + cpu_clock_high db 0 + wakeup_high db 0 + thread_dr6 db 0 + state_sp db 0 + pager dd 0 + clan_depth db 0 + db 0,0,0 + + thread_dr0 dd 0 + thread_dr1 dd 0 + thread_dr2 dd 0 + thread_dr3 dd 0 + + thread_idt_base dd 0 + present_llink dd 0,0 + thread_dr7 dd 0 + + reg_387 dd 108/4 dup (0) + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:3,in_partner_space:1,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_root/4 GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + +.errnz (offset sigma0_proot-offset task_root)/4 - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12 + add reg,offset pdir_space + endm + diff --git a/l4-x86/l4-y/make/l4.rsp b/l4-x86/l4-y/make/l4.rsp new file mode 100644 index 0000000..a83dd90 --- /dev/null +++ b/l4-x86/l4-y/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start cpuctr dispatch ipcman intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/l4-y/make/make-l4 b/l4-x86/l4-y/make/make-l4 new file mode 100644 index 0000000..9166dc4 --- /dev/null +++ b/l4-x86/l4-y/make/make-l4 @@ -0,0 +1,114 @@ + +p={\liedtke\l4-y\kernel\;\liedtke\l4-y\kernifc\;\liedtke\l4-y\userifc\} +a=d:\liedtke\l4-y\PIII^\ +all_includes_PIII= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb6.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + + + +$(a)adrsman.obj : $(all_includes_PIII) $(p)adrsman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII adrsman asm + +$(a)cpuctr.obj : $(all_includes_PIII) $(p)cpuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII cpuctr asm + +$(a)dispatch.obj : $(all_includes_PIII) $(p)dispatch.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII dispatch asm + +$(a)emuctr.obj : $(all_includes_PIII) $(p)emuctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII emuctr asm + +$(a)intctr.obj : $(all_includes_PIII) $(p)intctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII intctr asm + +$(a)ipcman.obj : $(all_includes_PIII) $(p)ipcman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ipcman asm + +$(a)kdebug.obj : $(all_includes_PIII) $(p)kdebug.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdebug asm + +$(a)kdiopc.obj : $(all_includes_PIII) $(p)kdiopc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII kernel asm + +$(a)ktest.obj : $(all_includes_PIII) $(p)ktest.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII ktest asm + +$(a)memctr.obj : $(all_includes_PIII) $(p)memctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII memctr asm + +$(a)pagctr.obj : $(all_includes_PIII) $(p)pagctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagctr asm + +$(a)pagfault.obj : $(all_includes_PIII) $(p)pagfault.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagfault asm + +$(a)pagmap.obj : $(all_includes_PIII) $(p)pagmap.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII pagmap asm + +$(a)sgmctr.obj : $(all_includes_PIII) $(p)sgmctr.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sgmctr asm + +$(a)sigma0.obj : $(all_includes_PIII) $(p)sigma0.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII sigma0 asm + +$(a)start.obj : $(all_includes_PIII) $(p)start.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII start asm + +$(a)startpc.obj : $(all_includes_PIII) $(p)startpc.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII startpc asm + +$(a)tcbman.obj : $(all_includes_PIII) $(p)tcbman.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII tcbman asm + +$(a)yoonseva.obj : $(all_includes_PIII) $(p)yoonseva.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \liedtke\l4-y\PIII + @link /nologo @..\make\l4.rsp + pause + + + +$(a)boot.obj : $(all_includes_PIII) $(p)boot.asm + @cd \liedtke\l4-y\PIII + @..\make\ml-PIII boot asm + +$(a)boot.com : $(a)boot.obj + @cd \liedtke\l4-y\PIII + link boot.obj/TINY,boot,boot.map + + + + + + \ No newline at end of file diff --git a/l4-x86/l4-y/make/ml-piii.bat b/l4-x86/l4-y/make/ml-piii.bat new file mode 100755 index 0000000..2eff3bb --- /dev/null +++ b/l4-x86/l4-y/make/ml-piii.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=pIII /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kernifc /I..\userifc ..\kernel\%1.%2 + diff --git a/l4-x86/l4-y/make/proj.err b/l4-x86/l4-y/make/proj.err new file mode 100644 index 0000000..440e23d --- /dev/null +++ b/l4-x86/l4-y/make/proj.err @@ -0,0 +1,5 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +'d:\liedtke\l4-y\PIII\l4.exe' is up-to-date diff --git a/l4-x86/l4-y/userifc/contents b/l4-x86/l4-y/userifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/l4-y/userifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/l4-y/userifc/msg.inc b/l4-x86/l4-y/userifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/l4-y/userifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/l4-y/userifc/scmac.inc b/l4-x86/l4-y/userifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/l4-y/userifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/l4-y/userifc/syscalls.inc b/l4-x86/l4-y/userifc/syscalls.inc new file mode 100644 index 0000000..43cad41 --- /dev/null +++ b/l4-x86/l4-y/userifc/syscalls.inc @@ -0,0 +1,35 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 + + +ipc___syscall macro + push ecx + push ebp + push linear_space_exec + push offset $+5+2+2 + mov ecx,esp + sysenter + endm diff --git a/l4-x86/l4-y/userifc/uid.inc b/l4-x86/l4-y/userifc/uid.inc new file mode 100644 index 0000000..60974e0 --- /dev/null +++ b/l4-x86/l4-y/userifc/uid.inc @@ -0,0 +1,270 @@ +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 +sigma1_task_no equ 3 +booter_task_no equ 4 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/smp/lx/STD.ERR b/l4-x86/smp/lx/STD.ERR new file mode 100644 index 0000000..c7749b6 --- /dev/null +++ b/l4-x86/smp/lx/STD.ERR @@ -0,0 +1,4 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + diff --git a/l4-x86/smp/lx/c-bind/new/compiler.h b/l4-x86/smp/lx/c-bind/new/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/smp/lx/c-bind/new/idt.h b/l4-x86/smp/lx/c-bind/new/idt.h new file mode 100644 index 0000000..575f697 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/c-bind/new/ipc-trent.c b/l4-x86/smp/lx/c-bind/new/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/smp/lx/c-bind/new/ipc.h b/l4-x86/smp/lx/c-bind/new/ipc.h new file mode 100644 index 0000000..c197980 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/smp/lx/c-bind/new/kdebug.h b/l4-x86/smp/lx/c-bind/new/kdebug.h new file mode 100644 index 0000000..7aa56c6 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/smp/lx/c-bind/new/kernel.h b/l4-x86/smp/lx/c-bind/new/kernel.h new file mode 100644 index 0000000..82c86dc --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/smp/lx/c-bind/new/syscalls.h b/l4-x86/smp/lx/c-bind/new/syscalls.h new file mode 100644 index 0000000..855864b --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/smp/lx/c-bind/new/test.c b/l4-x86/smp/lx/c-bind/new/test.c new file mode 100644 index 0000000..8d9247a --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/test.c @@ -0,0 +1,3 @@ + +#include + diff --git a/l4-x86/smp/lx/c-bind/new/types.h b/l4-x86/smp/lx/c-bind/new/types.h new file mode 100644 index 0000000..9d937aa --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/smp/lx/c-bind/new/x-compiler.h b/l4-x86/smp/lx/c-bind/new/x-compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/smp/lx/c-bind/new/x-idt.h b/l4-x86/smp/lx/c-bind/new/x-idt.h new file mode 100644 index 0000000..8b5f28e --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-idt.h @@ -0,0 +1,31 @@ +/* + * $Id: x-idt.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/c-bind/new/x-ipc.h b/l4-x86/smp/lx/c-bind/new/x-ipc.h new file mode 100644 index 0000000..a22a84f --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: x-ipc.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/smp/lx/c-bind/new/x-kdebug.h b/l4-x86/smp/lx/c-bind/new/x-kdebug.h new file mode 100644 index 0000000..f16511d --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: x-kdebug.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/smp/lx/c-bind/new/x-kernel.h b/l4-x86/smp/lx/c-bind/new/x-kernel.h new file mode 100644 index 0000000..aee1fc8 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: x-kernel.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/smp/lx/c-bind/new/x-lid.c b/l4-x86/smp/lx/c-bind/new/x-lid.c new file mode 100644 index 0000000..3d66b0c --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-lid.c @@ -0,0 +1,238 @@ + /* + * $Id: x-lid.c,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __LNX_LId_TYPE_H__ +#define __LNX_LId_TYPE_H__ + +//#include +#define L4_INLINE inline + + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} LnThreadId____; + +typedef struct { + unsigned version____:10; + unsigned thread____:14; + unsigned chief____:8; +} LnThreadId_____; + +typedef struct { + unsigned intr____:10; + unsigned zero____:22; +} LnInterruptId____; + + +typedef union {LnThreadId____ t; LnThreadId_____ t_; unsigned w;} LnThreadId ; + +typedef LnThreadId LId; + + + +#define LId_Nil ((LId) {0} ) +#define LId_Invalid ((LId) {0xffffffff} ) + + +//-------- Relational Operators on LId s ----------- + + +L4_INLINE int LId_Equal (LId LeftThreadId, LId RightThreadId) +{ + return ( LeftThreadId.w == RightThreadId.w); +} + +L4_INLINE int LId_IsNil (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Nil); +} + +L4_INLINE int IsInvalid_LId (LId ThreadId) +{ + return LId_Equal (ThreadId, LId_Invalid); +} + + +//------- Tasks and LIds ------------------- + + +#define LId_MaxTasks 256 +#define LId_MaxTaskNo (LId_MaxTasks-1) + +L4_INLINE int LId_TaskNo (LId ThreadId) +{ + return ThreadId.t.task____; +} + +L4_INLINE LId LId_Task (LId ThreadId, int TaskNo) +{ + ThreadId.t.task____ = TaskNo ; + return ThreadId ; +} + + +L4_INLINE int LId_SameTask (LId left, LId right) +{ + return (LId_TaskNo (left) == LId_TaskNo (right)); +} + + +//------- LThreads and LIds ------------------- + + +#define LId_MaxLThreads 64 +#define LId_MaxLThreadNo (LId_MaxLThreads-1) + + +L4_INLINE int LId_LThreadNo (LId ThreadId) +{ + return ThreadId.t.lthread____; +} + +L4_INLINE LId LId_LThread (LId ThreadId, int LThreadNo) +{ + ThreadId.t.lthread____ = LThreadNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextLThread (LId ThreadId) +{ + ThreadId.t.lthread____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxLThread (LId ThreadId) +{ + ThreadId.t.lthread____ = LId_MaxLThreadNo ; + return ThreadId ; +} + + +//------- Threads and LIds ------------------- + + +#define LId_MaxThreads (LId_MaxTasks*LId_MaxLThreads) +#define LId_MaxThreadNo (LId_MaxThreads-1) + + +L4_INLINE int LId_ThreadNo (LId ThreadId) +{ + return ThreadId.t_.thread____; +} + +//L4_INLINE LId LId_Thread (LId ThreadId, int ThreadNo) +//{ +// return (LnThreadId_X) ThreadId.t.thread____; +//} + + + +//------- Chiefs and LIds ------------------- + + +#define LId_MaxChiefs LId_MaxTasks +#define LId_MaxChiefNo (LId_MaxChiefs-1) + + +L4_INLINE int LId_ChiefNo (LId ThreadId) +{ + return ThreadId.t.chief____; +} + +L4_INLINE LId LId_Chief (LId ThreadId, int ChiefNo) +{ + ThreadId.t.chief____ = ChiefNo ; + return ThreadId ; +} + + +//------- Versions and LIds ------------------- + +#define LId_MaxVersions 1024 +#define LId_MaxVersionNo (LId_MaxVersions-1) + + + +L4_INLINE int LId_VersionNo (LId ThreadId) +{ + return ThreadId.t.version____; +} + + +L4_INLINE LId LId_Version (LId ThreadId, int VersionNo) +{ + ThreadId.t.version____ = VersionNo ; + return ThreadId ; +} + +L4_INLINE LId LId_FirstVersion (LId ThreadId) +{ + ThreadId.t.version____ = 0 ; + return ThreadId ; +} + +L4_INLINE LId LId_NextVersion (LId ThreadId) +{ + ThreadId.t.version____ ++ ; + return ThreadId ; +} + +L4_INLINE LId LId_MaxVersion (LId ThreadId) +{ + ThreadId.t.version____ = LId_MaxVersionNo ; + return ThreadId ; +} + + +//------- Interrupts and LIds ------------------- + + +#define LId_MaxInterrupts 16 +#define LId_MaxInterruptNo (LId_MaxInterrupts-1) + + +L4_INLINE int LId_IsInterrupt (LId ThreadId) +{ + return ( ( ThreadId.w < (LId_MaxInterruptNo+1)) && (ThreadId.w > 0) ) ; +} + +L4_INLINE int LId_InterruptNo (LId ThreadId) +{ + return ThreadId.w-1 ; +} + +L4_INLINE LId LID_Interrupt (int InterruptNo) +{ + return (LId) {InterruptNo+1} ; +} + +L4_INLINE LId LId_FirstInterrupt (void) +{ + return (LId) {1} ; +} + +L4_INLINE LId LId_NextInterrupt (LId ThreadId) +{ + return (LId) {ThreadId.w+1} ; +} + +L4_INLINE LId LId_MaxInterrupt (void) +{ + return (LId) {LId_MaxInterruptNo+1} ; +} + + + +#endif /* __LNX_LId_TYPE_H__ */ + + diff --git a/l4-x86/smp/lx/c-bind/new/x-syscalls.h b/l4-x86/smp/lx/c-bind/new/x-syscalls.h new file mode 100644 index 0000000..48fdb67 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: x-syscalls.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/smp/lx/c-bind/new/x-types.h b/l4-x86/smp/lx/c-bind/new/x-types.h new file mode 100644 index 0000000..696ed8e --- /dev/null +++ b/l4-x86/smp/lx/c-bind/new/x-types.h @@ -0,0 +1,292 @@ + /* + * $Id: x-types.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __LN_TYPES_H__ +#define __LN_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +/* + * LN unique identifiers + */ + +typedef struct { + unsigned version____:10; + unsigned lthread____:6; + unsigned task____:8; + unsigned chief____:8; +} Struct_LnThreadid; + +typedef union { + dword_t lh; + Struct_LnThreadid; +} LnThread; + +typedef LnThread LnTask; + +typedef struct { + unsigned intr:8; + unsigned char zero[3]; +} Struct_LnIntrid; + +typedef union { + dword_t lh; + Struct_LnIntrid id; +} LnIntr; + +#define Nil_LnThread ((LnThread){lh:{0}}) +#define Invalid_LnThread ((LnThread){lh:{0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE bool Equal_LnThread (LnThread l,r); +L4_INLINE bool IsNil_LnThread (LnThread t); +L4_INLINE bool IsInvalid_LnThread (LnThread t); +L4_INLINE int TaskNo_LnThread (LnThread t); +L4_INLINE int ThreadNo_LnThread (LnThread t); +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + +L4_INLINE bool Equal_LnThread (LnThread l,r) +{ + l==r +} + +L4_INLINE bool IsNil_LnThread (LnThread t) +{ + return Equal_LnThread (t, Nil_LnThread) +} + +L4_INLINE bool IsInvalid_LnThread (LnThread t) +{ + return Equal_LnThread (t, Invalid_LnThread) +} + +L4_INLINE int TaskNo_LnThread (LnThread t) +{ + return t.task____ +} + +L4_INLINE int ThreadNo_LnThread (LnThread t) +{ + return t.lthread____ +} + +L4_INLINE int LThreadNo_LnThread (LnThread t); +L4_INLINE int ChiefNo_LnThread (LnThread t); +L4_INLINE int Version_LnThread (LnThread t); +L4_INLINE SetTaskNo_LnThread (LnThread t, int i); +L4_INLINE SetThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetLThreadNo_LnThread (LnThread t, int i); +L4_INLINE SetChiefNo_LnThread (LnThread t, int i); +L4_INLINE SetVersion_LnThread (LnThread t, int i); + + + + + + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} + + + + + + + + + + + + + +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/smp/lx/c-bind/orig/compiler.h b/l4-x86/smp/lx/c-bind/orig/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/smp/lx/c-bind/orig/idt.h b/l4-x86/smp/lx/c-bind/orig/idt.h new file mode 100644 index 0000000..575f697 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/c-bind/orig/ipc-trent.c b/l4-x86/smp/lx/c-bind/orig/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/smp/lx/c-bind/orig/ipc.h b/l4-x86/smp/lx/c-bind/orig/ipc.h new file mode 100644 index 0000000..c197980 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/ipc.h @@ -0,0 +1,1236 @@ +/* + * $Id: ipc.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + "int $0x30 \n\t" + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/smp/lx/c-bind/orig/kdebug.h b/l4-x86/smp/lx/c-bind/orig/kdebug.h new file mode 100644 index 0000000..7aa56c6 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/smp/lx/c-bind/orig/kernel.h b/l4-x86/smp/lx/c-bind/orig/kernel.h new file mode 100644 index 0000000..82c86dc --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/smp/lx/c-bind/orig/syscalls.h b/l4-x86/smp/lx/c-bind/orig/syscalls.h new file mode 100644 index 0000000..855864b --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/smp/lx/c-bind/orig/types.h b/l4-x86/smp/lx/c-bind/orig/types.h new file mode 100644 index 0000000..9d937aa --- /dev/null +++ b/l4-x86/smp/lx/c-bind/orig/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/smp/lx/c-bind/provisional/compiler.h b/l4-x86/smp/lx/c-bind/provisional/compiler.h new file mode 100644 index 0000000..22f756d --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/compiler.h @@ -0,0 +1,26 @@ +#ifndef __L4_COMPILER_H__ +#define __L4_COMPILER_H__ + +#ifndef __ASSEMBLY__ + +#ifndef __GNUC__ +#error "The libl4sys library must be used with Gcc." +#endif + +#ifndef __cplusplus +# ifdef __OPTIMIZE__ +# define L4_INLINE extern __inline__ +# else /* ! __OPTIMIZE__ */ +# define L4_INLINE static +# endif /* ! __OPTIMIZE__ */ +#else /* __cplusplus */ +# define L4_INLINE inline +#endif /* __cplusplus */ + +#define L4_NORETURN __attribute__((noreturn)) + +#endif /* !__ASSEMBLY__ */ + +#include + +#endif diff --git a/l4-x86/smp/lx/c-bind/provisional/idl.m4 b/l4-x86/smp/lx/c-bind/provisional/idl.m4 new file mode 100644 index 0000000..f906d2b --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/idl.m4 @@ -0,0 +1,27 @@ + + + +# Begin_Interface_(FileServer) +# +# +# Procedure_(Read, InWord_(handle), InWord_(FilePointer), InWord_(length), +# OutWord_(result), OutMem_(BufferAddress, length) ) + + +define(`ifundef', ifdef($1,,$2)) + +define(`In', `define(`Mode',`in')') +define(`Out',`define(`Mode',`out')') + +define(`Word_', `ifelse(Mode,`in',`InWord_($1)', `OutWord_($1)')') + + +define(`InWord_', `ifundef(`SndWord0', `define(`SndWord0', $1 )') + ifundef(`SndWord1', `define(`SndWord1', $1 )') + ifundef(`SndWord2', `define(`SndWord2', $1 )') ' ) + + +In Word_(handle) +Word_(pointer) + +SndW0 = SndWord0 ; SndW1 = SndWord1 ; SndW2 = SndWord2 ; diff --git a/l4-x86/smp/lx/c-bind/provisional/idt.h b/l4-x86/smp/lx/c-bind/provisional/idt.h new file mode 100644 index 0000000..575f697 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/idt.h @@ -0,0 +1,31 @@ +/* + * $Id: idt.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#define TRAPGATE 0x70 +#define USERLEVEL 0x03 +#define SEGPRESENT 0x01 + +typedef struct { + unsigned IntHandlerLow: 16; + unsigned Selector: 16; + unsigned Reserved: 5; + unsigned TrapGate: 8; + unsigned Privilege: 2; + unsigned Present: 1; + unsigned IntHandlerHigh: 16; +} IDTEntryT; + +typedef void (*IntHandlerT)(void); + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/c-bind/provisional/ipc-trent.c b/l4-x86/smp/lx/c-bind/provisional/ipc-trent.c new file mode 100644 index 0000000..af62c13 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/ipc-trent.c @@ -0,0 +1,262 @@ +#include +#include +#include +#include + +/* + +Hairy C bindings + +Problems: Not enough registers + +*/ + +int +ln_i386_ipc_wait_redirect(ln_ipc_deceit_ids_t *ids, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + volatile unsigned long y; + +#ifdef WR_DEBUG + x.msgdope = 13; + y = 14; +#endif + + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + "pushl %%ebp \n\t" /* save ebp register */ + "pushl %%eax \n\t" /* push rcv msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* get current stack pointer address */ +#ifdef WR_DEBUG + "popl 0x34(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x30(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#else + "popl 0x2c(%%ebp) \n\t" /* pop eax into variable x : 0x34 w/ printk's */ + "popl 0x28(%%ebp) \n\t" /* pop ebp into variable y : 0x30 w/ printk's */ +#endif + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (ids->dest.lh.low), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + /* "=c" (ids->dest.lh.high), */ /* ECX,5 */ + "=D" (ids->true_src.lh.high), /* EDI,3 */ + "=S" (ids->true_src.lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (LN_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | LN_IPC_OPEN_IPC) /* EBX, 2 rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + + *result = x; + ids->dest.lh.high = y; + + return LN_IPC_ERROR(*result); +} + + + + +int +ln_i386_ipc_reply_deceiting_and_wait_redirect(ln_ipc_deceit_ids_t snd_ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_ipc_deceit_ids_t *rcv_ids, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + volatile ln_msgdope_t x; + struct { + ln_ipc_deceit_ids_t *snd_ids; + ln_ipc_deceit_ids_t *rcv_ids; + } addresses = { &snd_ids, rcv_ids}; + +#ifdef RDWR_DEBUG + printk("sender: %x %x; send dest: %x %x\n", (unsigned)snd_ids.true_src.lh.low, (unsigned)snd_ids.true_src.lh.high, + (unsigned)snd_ids.dest.lh.low, (unsigned)snd_ids.dest.lh.high); + printk("rcv_ids @ %x\n", (unsigned) rcv_ids); + x.msgdope = 15; +#endif + + __asm__ + __volatile__( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + "pushl %%ebp \n\t" /* save ebp after return */ + "pushl %%eax \n\t" /* push msgdope on stack */ + "movl %%esp,%%ebp \n\t" /* save esp in ebp */ +#ifdef RDWR_DEBUG + "popl 92(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#else + "popl 0x38(%%ebp) \n\t" /* pop eax into variable result (x): 92 w/ printk's */ +#endif + "popl %%ebp \n\t" /* restore ebp */ + + "testb $0b100,%%al \n\t" + "jnz 1f \n\t" + "subl %%ecx,%%ecx \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl %%ecx,%%eax \n\t" + "movl %%ebp,%%ecx \n\t" + "2: \n\t" + + "popl %%ebp \n\t" /* pop addresses off stack (see pushl %%esi) */ + "movl 0x4(%%ebp),%%ebp \n\t" + "movl %%esi, 8(%%ebp) \n\t" /* esi -> rcv_ids->true_src.lh.low */ + "movl %%edi, 12(%%ebp)\n\t" /* edi -> rcv_ids->true_src.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + + : + "=a" (rcv_ids->dest.lh.low), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1), /* EBX, 2 */ + "=c" (rcv_ids->dest.lh.high) /* ECX,5 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | LN_IPC_OPEN_IPC), /* EDI, 5 -> EBP rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *result = x; + +#ifdef RDWR_DEBUG + printk("result: %x; recv: %x %x; recv dest: %x %x\n", (unsigned) (*result).msgdope, + (unsigned)rcv_ids->true_src.lh.low, (unsigned)rcv_ids->true_src.lh.high, + (unsigned)rcv_ids->dest.lh.low, (unsigned)rcv_ids->dest.lh.high); + enter_kdebug("rd/wr"); +#endif + + return LN_IPC_ERROR(*result); +} + + + + +static inline int +ln_i386_ipc_send_deceiting_and_receive(ln_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + ln_threadid_t src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + ln_timeout_t timeout, + ln_msgdope_t *result) +{ + struct { + ln_ipc_deceit_ids_t *ids; + ln_threadid_t *src; + } addresses = { &ids, &src }; + + asm( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + "int $0x30 \n\t" + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) & (~LN_IPC_OPEN_IPC)), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) | (LN_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return LN_IPC_ERROR(*result); +} + + + diff --git a/l4-x86/smp/lx/c-bind/provisional/ipc.h b/l4-x86/smp/lx/c-bind/provisional/ipc.h new file mode 100644 index 0000000..d0f6236 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/ipc.h @@ -0,0 +1,1419 @@ +/* + * $Id: ipc.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_IPC_H__ +#define __L4_IPC_H__ + +/* + * L4 ipc + */ + +#include +#include + +// Version X adaption + +#define ToLId "shll 7,%%edi \n\t" \ + "andl $0x01feffff,%%esi \n\t" \ + "rcll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rorl $16,%%esi \n\t" \ + "addl %%edi,%%esi \n\t" + +#define FromLId "movl %%esi,%%edi \n\t" \ + "andl $0x00ffffff,%%esi \n\t" \ + "roll $16,%%esi \n\t" \ + "andl $0xff000000,%%edi \n\t" \ + "rcrl $16,%%esi \n\t" \ + "shrl $7,%%edi \m\t" + + +/* + * IPC parameters + */ + + +/* + * Structure used to describe destination and true source if a chief + * wants to deceit + */ + +typedef struct { + l4_threadid_t dest, true_src; +} l4_ipc_deceit_ids_t; + + + +/* + * Defines used for Parameters + */ + +#define L4_IPC_SHORT_MSG 0 + +/* + * Defines used to build Parameters + */ + +#define L4_IPC_STRING_SHIFT 8 +#define L4_IPC_DWORD_SHIFT 13 +#define L4_IPC_SHORT_FPAGE ((void *)2) + +#define L4_IPC_DOPE(dwords, strings) \ +( (l4_msgdope_t) {md: {0, 0, 0, 0, 0, 0, strings, dwords }}) + + +#define L4_IPC_TIMEOUT(snd_man, snd_exp, rcv_man, rcv_exp, snd_pflt, rcv_pflt)\ + ( (l4_timeout_t) \ + {to: { rcv_exp, snd_exp, rcv_pflt, snd_pflt, snd_man, rcv_man } } ) + +#define L4_IPC_NEVER ((l4_timeout_t) {timeout: 0}) +#define L4_IPC_MAPMSG(address, size) \ + ((void *)(dword_t)( ((address) & L4_PAGEMASK) | ((size) << 2) \ + | (unsigned long)L4_IPC_SHORT_FPAGE)) + +/* + * Some macros to make result checking easier + */ + +#define L4_IPC_ERROR_MASK 0xF0 +#define L4_IPC_DECEIT_MASK 0x01 +#define L4_IPC_FPAGE_MASK 0x02 +#define L4_IPC_REDIRECT_MASK 0x04 +#define L4_IPC_SRC_MASK 0x08 +#define L4_IPC_SND_ERR_MASK 0x10 + +#define L4_IPC_IS_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_MSG_DECEITED(x) (((x).msgdope) & L4_IPC_DECEIT_MASK) +#define L4_IPC_MSG_REDIRECTED(x) (((x).msgdope) & L4_IPC_REDIRECT_MASK) +#define L4_IPC_SRC_INSIDE(x) (((x).msgdope) & L4_IPC_SRC_MASK) +#define L4_IPC_SND_ERROR(x) (((x).msgdope) & L4_IPC_SND_ERR_MASK) +#define L4_IPC_MSG_TRANSFER_STARTED \ + ((((x).msgdope) & L4_IPC_ERROR_MASK) < 5) + +/* + * Prototypes + */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(const l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope); +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp); +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp); + +/* IPC bindings for chiefs */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result); + + + + + +/* + * + */ + +L4_INLINE int l4_ipc_fpage_received(l4_msgdope_t msgdope) +{ + return msgdope.md.fpage_received != 0; +} +L4_INLINE int l4_ipc_is_fpage_granted(l4_fpage_t fp) +{ + return fp.fp.grant != 0; +} +L4_INLINE int l4_ipc_is_fpage_writable(l4_fpage_t fp) +{ + return fp.fp.write != 0; +} + +/* + * IPC results + */ + +#define L4_IPC_ERROR(x) (((x).msgdope) & L4_IPC_ERROR_MASK) +#define L4_IPC_ENOT_EXISTENT 0x10 +#define L4_IPC_RETIMEOUT 0x20 +#define L4_IPC_SETIMEOUT 0x30 +#define L4_IPC_RECANCELED 0x40 +#define L4_IPC_SECANCELED 0x50 +#define L4_IPC_REMAPFAILED 0x60 +#define L4_IPC_SEMAPFAILED 0x70 +#define L4_IPC_RESNDPFTO 0x80 +#define L4_IPC_SERCVPFTO 0x90 +#define L4_IPC_REABORTED 0xA0 +#define L4_IPC_SEABORTED 0xB0 +#define L4_IPC_REMSGCUT 0xE0 +#define L4_IPC_SEMSGCUT 0xF0 + + +/* + * Internal defines used to build IPC parameters for the L4 kernel + */ + +#define L4_IPC_NIL_DESCRIPTOR (-1) +#define L4_IPC_DECEIT 1 +#define L4_IPC_OPEN_IPC 1 + + +/* + * Implementation + */ + +#define SCRATCH 1 +#define SCRATCH_MEMORY 1 + +#ifdef __pic__ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_call3 (l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, dword_t snd_word2, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +L4_INLINE int +l4_i386_ipc_reply_and_wait3 (l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, dword_t snd_dword2, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, dword_t *rcv_dword2, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + struct { +???? dword_t d1, d2, d3; + } dwords = {snd_dword0, snd_dword1, snd_dword2}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + + "movl 8(%%edx), %%edi \n\t" + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "int $0x30 \n\t" + + "popl %%ebp \n\t" + ??? "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%edi,%%ecx \n\t" + FromLId + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "movl %%ecx,%%edi \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1), /* ECX, 2 */ + "=D" (*rcv_dword2) /* EDI, */ + : + "2" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (&dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + + ToLId + "int $0x30 \n\t" + FromLId + + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "2" (timeout), /* ECX, 2 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 4 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (dwords) /* EDX, 1 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %5 ,%%ebp \n\t" + "movl %%esi, %%ebx \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&dest), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + } dwords = {snd_dword0, snd_dword1}; + + asm + volatile( + "pushl %%ebx \n\t" + + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=a" (*result) /* EAX,0 */ + : + "d" (&dwords), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + ToLId + "int $0x30 \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl %%esi,(%%ebp) \n\t" + "movl %%edi,4(%%ebp) \n\t" + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +/**************************************************************** +***************************************************************** +****************************************************************/ + +#else /* __pic__ */ + +L4_INLINE int +l4_i386_ipc_call(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)),/* EDI, 4, rcv msg -> ebp */ + "S" (&dest), /* ESI, 5, addr of dest */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1, */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_and_wait(l4_threadid_t dest, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *dest; + l4_threadid_t *src; + } addresses = { &dest, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of dest */ + + "movl %%edi, %%ebp \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> esi */ + ToLId + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 4 -> ebp rcv_msg */ + "S" (&addresses), /* ESI ,5 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_reply_deceiting_and_wait(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, + void *rcv_msg, + dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, + l4_msgdope_t *result) +{ + struct { + l4_ipc_deceit_ids_t *ids; + l4_threadid_t *src; + } addresses = { &ids, src }; + + asm volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * esi+8 is the address of true src + * $5 address of src id + */ + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%esi \n\t" + "movl (%%esi), %%esi \n\t" /* load address of ids */ + + "movl %%edi, %%ebp \n\t" + "pushl 12(%%esi) \n\t" /* ids.true_src.lh.high */ + /* ->(esp+4) */ + "pushl 8(%%esi) \n\t" /* ids.true_src.lh.low */ + /* ->(esp) */ + "movl 4(%%esi), %%edi \n\t" /* ids.dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* ids.dest.lh.low -> edi */ + ToLId + "int $0x30 \n\t" + FromLId + "addl $8, %%esp \n\t" /* remove true_src from stack*/ + + "popl %%ebp \n\t" + "movl 4(%%ebp), %%ebp \n\t" /* load address of src */ + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp)\n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=b" (*rcv_dword1) /* EBX, 2 */ + : + "S" (&addresses), /* addresses, 3 */ + "c" (timeout), /* ECX, 4 */ + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* EDI, 5 -> ebp rcv_msg */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)), /* EAX, 0 */ + "1" (snd_dword0), /* EDX, 1 */ + "2" (snd_dword1) /* EBX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + +L4_INLINE int +l4_i386_ipc_send(l4_threadid_t dest, + const void *snd_msg, dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %6 ,%%ebp \n\t" + ToLId + "int $0x30 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (dest.lh.high), /* EDI, 4 */ + "S" (dest.lh.low), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + + +L4_INLINE int +l4_i386_ipc_send_deceiting(l4_ipc_deceit_ids_t ids, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl 4(%%esi) \n\t" + "pushl (%%esi) \n\t" + "movl (%%edi), %%esi \n\t" + "movl 4(%%edi), %%edi \n\t" + + "movl %6 ,%%ebp \n\t" + + ToLId + "int $0x30 \n\t" + + /* remove true_src from stack */ + "addl $8, %%esp \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "b" (snd_dword1), /* EBX, 3 */ + "D" (&ids.dest), /* EDI, 4 */ + "S" (&ids.true_src), /* ESI, 5 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 6 */ + "0" (((int)snd_msg) & (~L4_IPC_DECEIT)) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ebx", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +}; + +L4_INLINE int +l4_i386_ipc_wait(l4_threadid_t *src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1), /* EBX,2 */ + "=D" (src->lh.high), /* EDI,3 */ + "=S" (src->lh.low) /* ESI,4 */ + : + "c" (timeout), /* ECX, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_receive(l4_threadid_t src, + void *rcv_msg, dword_t *rcv_dword0, dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + asm volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%ebx,%%ebp \n\t" + "int $0x30 \n\t" + FromLId + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=b" (*rcv_dword1) /* EBX,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src.lh.high), /* EDI, 4 */ + "S" (src.lh.low), /* ESI, 5 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* EBX, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +#endif /* __pic__ */ + + +/* IPC bindings for chiefs -- they're pic by default for now, no + optimized version for non-pic */ + +L4_INLINE int +l4_i386_ipc_chief_wait(l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi,%%ebp \n\t" + "pushl %%edx \n\t" + "pushl %%edi \n\t" + "int $0x30 \n\t" + FromLId + "xchgl %%ebp,(%%esp) \n\t" + "movl %%esi,(%%ebp) \n\t" /* store src id */ + "movl %%edi,4(%%ebp) \n\t" + "popl %%esi \n\t" /* was %ebp after int */ + "popl %%ebp \n\t" /* was %edx before int */ + "movl %%ecx,(%%ebp) \n\t" + "movl %%esi,4(%%ebp) \n\t" /* store real dest id */ + "movl %%ebx,%%esi \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) | L4_IPC_OPEN_IPC) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_receive(l4_threadid_t src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, l4_timeout_t timeout, + l4_msgdope_t *result) +{ + asm + volatile ( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %2,%%ebp \n\t" + "movl (%%edi),%%esi \n\t" + "movl 4(%%edi),%%edi \n\t" + "pushl %%edx \n\t" + ToLId + "int $0x30 \n\t" + "popl %%edi \n\t" + "movl %%ecx, 4(%%edi) \n\t" + "movl %%ebp, 4(%%edi) \n\t" + "movl %%ebx, %2 \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result), /* EAX,0 */ + "=d" (*rcv_dword0), /* EDX,1 */ + "=S" (*rcv_dword1) /* ESI,2 */ + : + "c" (timeout), /* ECX, 3 */ + "D" (&src), /* EDI, 4 */ + "0" (L4_IPC_NIL_DESCRIPTOR), /* EAX, 0 */ + "1" (real_dst), /* EDX, 1 */ + "2" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)) /* ESI, 2, rcv_msg -> EBP */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_call(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t fs; + } dwords = {snd_dword0, snd_dword1, fake_src}; + + asm + volatile( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%edx), %%ebx \n\t" + "movl (%%edx), %%edx \n\t" + + "movl %%edi, %%ebp \n\t" + + "pushl %%esi \n\t" + "pushl 12(%%esi) \n\t" + "pushl 8(%%esi) \n\t" + "movl 4(%%esi), %%edi \n\t" /* dest.lh.high -> edi */ + "movl (%%esi), %%esi \n\t" /* dest.lh.low -> edi */ + + ToLId + "int $0x30 \n\t" + "lea 8(%%esp), %%esp \n\t" + "popl %%esi \n\t" + "movl %%ecx, 8(%%esi) \n\t" + "movl %%ebp, 12(%%esi) \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) & (~L4_IPC_OPEN_IPC)), /* EDI, 3, rcv msg -> ebp */ + "S" (&dest), /* ESI, 4, addr of dest */ + "0" ((int)snd_msg), /* EAX, 0 */ + "1" (&dwords), /* EDX, 1, */ + "2" (timeout) /* ECX, 2 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = dwords.fs; + return L4_IPC_ERROR(*result); +} + +L4_INLINE int +l4_i386_ipc_chief_reply_and_wait(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, + dword_t snd_dword0, dword_t snd_dword1, + l4_threadid_t *src, l4_threadid_t *real_dst, + void *rcv_msg, dword_t *rcv_dword0, + dword_t *rcv_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + dword_t d1, d2; + l4_threadid_t *dest; + l4_threadid_t *src; + l4_threadid_t *real; + } dwords = { snd_dword0, snd_dword1, &dest, src, &fake_src }; + + asm + volatile( + /* eax, edx, ebx loaded, + * edi contains rcv buffer address, must be moved to ebp, + * esi contains address of destination id, + * $5 address of src id + */ + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl %%edi, %%ebp \n\t" /* rcv desc */ + "pushl %%edx \n\t" /* & dwords */ + + "movl 16(%%edx), %%esi \n\t" /* & real_id */ + "pushl %%esi \n\t" + "pushl 4(%%esi) \n\t" /* real_id.high */ + "pushl (%%esi) \n\t" /* real_id.low */ + + "movl 8(%%edx), %%esi \n\t" /* & dest */ + "movl 4(%%esi), %%edi \n\t" /* dest.high */ + "movl (%%esi), %%esi \n\t" /* dest.low */ + + "movl 4(%%edx), %%ebx \n\t" /* dword 2 */ + "movl (%%edx), %%edx \n\t" /* dword 1 */ + + ToLId + "int $0x30 \n\t" + FromLId + "leal 8(%%esp), %%esp \n\t" + + "xchgl %%ebp, (%%esp) \n\t" /* & real_id */ + "movl %%ecx, (%%ebp) \n\t" /* real_id.low */ + "popl %%ecx \n\t" + "movl %%ecx, 4(%%ebp) \n\t" /* real_id.high */ + + "popl %%ebp \n\t" /* & dwords */ + "movl 12(%%ebp), %%ebp \n\t" /* & src */ + + "movl %%esi, (%%ebp) \n\t" /* esi -> src.lh.low */ + "movl %%edi, 4(%%ebp) \n\t" /* edi -> src.lh.high */ + + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "movl %%ebx, %%ecx \n\t" + "popl %%ebx \n\t" + + : + "=a" (*result), /* EAX, 0 */ + "=d" (*rcv_dword0), /* EDX, 1 */ + "=c" (*rcv_dword1) /* ECX, 2 */ + : + "D" (((int)rcv_msg) | L4_IPC_OPEN_IPC), /* edi, 3 -> ebp rcv_msg */ + "1" (&dwords), /* ESI ,4 */ + "2" (timeout), /* ECX, 2 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + *real_dst = *dwords.real; + return L4_IPC_ERROR(*result); +} + + +L4_INLINE int +l4_i386_ipc_chief_send(l4_threadid_t dest, l4_threadid_t fake_src, + const void *snd_msg, dword_t snd_dword0, + dword_t snd_dword1, + l4_timeout_t timeout, l4_msgdope_t *result) +{ + struct { + l4_threadid_t *d, *fake; + } addresses = { &dest, &fake_src }; + + asm + volatile( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" + "movl %%esi, %%ebx \n\t" + "movl 4(%%edi), %%ebp \n\t" + "pushl 4(%%ebp) \n\t" + "pushl (%%ebp) \n\t" + "movl (%%edi), %%ebp \n\t" + "movl (%%ebp),%%esi \n\t" + "movl 4(%%ebp),%%edi \n\t" + "movl %5 ,%%ebp \n\t" + ToLID + "int $0x30 \n\t" + "leal 8(%%esp), %%esp \n\t" + "popl %%ebx \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=a" (*result) /* EAX,0 */ + : + "d" (snd_dword0), /* EDX, 1 */ + "c" (timeout), /* ECX, 2 */ + "S" (snd_dword1), /* EBX, 3 */ + "D" (&addresses), /* EDI, 4 */ + "i" (L4_IPC_NIL_DESCRIPTOR), /* Int, 5 */ + "0" ((int)snd_msg) /* EAX, 0 */ +#ifdef SCRATCH + : + "esi", "edi", "ecx", "edx" +#ifdef SCRATCH_MEMORY + , "memory" +#endif /* SCRATCH_MEMORY */ +#endif + ); + return L4_IPC_ERROR(*result); +} + + + + +#endif /* __L4_IPC__ */ diff --git a/l4-x86/smp/lx/c-bind/provisional/kdebug.h b/l4-x86/smp/lx/c-bind/provisional/kdebug.h new file mode 100644 index 0000000..7aa56c6 --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/kdebug.h @@ -0,0 +1,115 @@ +/* + * $Id: kdebug.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + * + * kdebug.h provides some useful makros to acces the functionality + * of the kernel debugger + */ + +#ifndef __L4_KDEBUG_H__ +#define __L4_KDEBUG_H__ + +#include + +#define enter_kdebug(text) \ +asm(\ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define asm_enter_kdebug(text) \ + "int $3 \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t" + +#define kd_display(text) \ +asm(\ + "int $3 \n\t"\ + "nop \n\t"\ + "jmp 1f \n\t"\ + ".ascii \""text "\"\n\t"\ + "1: \n\t"\ + ) + +#define ko(c) \ + asm( \ + "int $3 \n\t" \ + "cmpb %0,%%al \n\t" \ + : /* No output */ \ + : "N" (c) \ + ) + +/* + * prototypes + */ +L4_INLINE void outchar(char c); +L4_INLINE void outstring(char *text); +L4_INLINE void outhex32(int number); +L4_INLINE void outhex20(int number); +L4_INLINE void outhex16(int number); +L4_INLINE void outdec(int number); + +L4_INLINE void outchar(char c) +{ + asm( + "int $3 \n\t" + "cmpb $0,%%al \n\t" + : /* No output */ + : "a" (c) + ); +} + +/* actually outstring is outcstring */ +L4_INLINE void outstring(char *text) +{ + asm( + "int $3 \n\t" + "cmpb $2,%%al \n\t" + : /* No output */ + : "a" (text) + ); +} + +L4_INLINE void outhex32(int number) +{ + asm( + "int $3 \n\t" + "cmpb $5,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex20(int number) +{ + asm( + "int $3 \n\t" + "cmpb $6,%%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outhex16(int number) +{ + asm( + "int $3 \n\t" + "cmpb $7, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +L4_INLINE void outdec(int number) +{ + asm( + "int $3 \n\t" + "cmpb $11, %%al \n\t" + : /* No output */ + : "a" (number) + ); +} + +#endif /* __L4_KDEBUG_H__ */ diff --git a/l4-x86/smp/lx/c-bind/provisional/kernel.h b/l4-x86/smp/lx/c-bind/provisional/kernel.h new file mode 100644 index 0000000..82c86dc --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/kernel.h @@ -0,0 +1,49 @@ +/* + * $Id: kernel.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ +#ifndef __L4_KERNEL_H__ +#define __L4_KERNEL_H__ + +#include + +typedef struct +{ + dword_t magic; + dword_t version; + byte_t offset_version_strings; +#if 0 + byte_t reserved[7 + 5 * 16]; +#else + byte_t reserved[7]; + + /* the following stuff is undocumented; we assume that the kernel + info page is located at offset 0x1000 into the L4 kernel boot + image so that these declarations are consistent with section 2.9 + of the L4 Reference Manual */ + dword_t init_default_kdebug, default_kdebug_exception, + __unknown, default_kdebug_end; + dword_t sigma0_esp, sigma0_eip; + l4_low_high_t sigma0_memory; + dword_t sigma1_esp, sigma1_eip; + l4_low_high_t sigma1_memory; + dword_t root_esp, root_eip; + l4_low_high_t root_memory; +#if 0 + byte_t reserved2[16]; +#else + dword_t l4_config; + dword_t reserved2; + dword_t kdebug_config; + dword_t kdebug_permission; +#endif +#endif + l4_low_high_t main_memory; + l4_low_high_t reserved0, reserved1; + l4_low_high_t semi_reserved; + l4_low_high_t dedicated[4]; + volatile dword_t clock; +} l4_kernel_info_t; + +#define L4_KERNEL_INFO_MAGIC (0x4BE6344CL) /* "L4µK" */ + +#endif diff --git a/l4-x86/smp/lx/c-bind/provisional/syscalls.h b/l4-x86/smp/lx/c-bind/provisional/syscalls.h new file mode 100644 index 0000000..855864b --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/syscalls.h @@ -0,0 +1,416 @@ +/* + * $Id: syscalls.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_SYSCALLS_H__ +#define __L4_SYSCALLS_H__ + +#include +#include +#include + +#define L4_FP_REMAP_PAGE 0x00 /* Page is set to read only */ +#define L4_FP_FLUSH_PAGE 0x02 /* Page is flushed completly */ +#define L4_FP_OTHER_SPACES 0x00 /* Page is flushed in all other */ + /* address spaces */ +#define L4_FP_ALL_SPACES 0x80000000U + /* Page is flushed in own address */ + /* space too */ + +#define L4_NC_SAME_CLAN 0x00 /* destination resides within the */ + /* same clan */ +#define L4_NC_INNER_CLAN 0x0C /* destination is in an inner clan */ +#define L4_NC_OUTER_CLAN 0x04 /* destination is outside the */ + /* invoker's clan */ + +#define L4_CT_LIMITED_IO 0 +#define L4_CT_UNLIMITED_IO 1 +#define L4_CT_DI_FORBIDDEN 0 +#define L4_CT_DI_ALLOWED 1 + +/* + * prototypes + */ +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask); + +L4_INLINE l4_threadid_t +l4_myself(void); + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief); + +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp); +L4_INLINE void +l4_thread_switch(l4_threadid_t destination); + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param); + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager); + + +/* + * Implementation + */ + +/* + * L4 flex page unmap + */ + +L4_INLINE void +l4_fpage_unmap(l4_fpage_t fpage, dword_t map_mask) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x32 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + /* No output */ + : + "a" (fpage), + "c" (map_mask) + : +#ifndef __pic__ + "ebx", +#endif + "edx", "edi", "esi", "eax", "ecx" + ); +}; + +/* + * L4 id myself + */ + +L4_INLINE l4_threadid_t +l4_myself(void) +{ + l4_threadid_t temp_id; + + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "0" (0) /* ESI, nil id (id.low = 0) */ + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx" + ); + return temp_id; +} + +/* + * L4 id next chief + */ + + +L4_INLINE int +l4_nchief(l4_threadid_t destination, l4_threadid_t *next_chief) +{ + int type; + __asm__( +#ifdef __pic__ + "pushl %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x31 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=S" (next_chief->lh.low), /* ESI, 0 */ + "=D" (next_chief->lh.high), /* EDI, 1 */ + "=a" (type) /* EAX, 2 */ + : + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : +#ifndef __pic__ + "ebx", +#endif + "ecx", "edx" + ); + return type; +} + +/* + * L4 lthread_ex_regs + */ +L4_INLINE void +l4_thread_ex_regs(l4_threadid_t destination, dword_t eip, dword_t esp, + l4_threadid_t *preempter, l4_threadid_t *pager, + dword_t *old_eflags, dword_t *old_eip, dword_t *old_esp) +{ + __asm__ __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edi, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + + "movl 4(%%esi), %%edi \n\t" /* load new pager id */ + "movl (%%esi), %%esi \n\t" + + "movl 4(%%ebx), %%ebp \n\t" /* load new preempter id */ + "movl (%%ebx), %%ebx \n\t" + + "int $0x35 \n\t" /* execute system call */ + + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.low */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.low */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + : + "=a" (*old_eflags), /* EAX, 0 */ + "=c" (*old_esp), /* ECX, 1 */ + "=d" (*old_eip), /* EDX, 2 */ + "=S" (pager->lh.low), /* ESI, 3 */ + "=D" (pager->lh.high) /* EDI, 4 */ + : + "0" (destination.id.lthread), + "1" (esp), + "2" (eip), + "3" (pager), /* ESI */ +#ifdef __pic__ + "4" (preempter) /* EDI */ +#else + "b" (preempter) /* EBX, 5 */ +#endif +#ifndef __pic__ + : + "ebx" +#endif + ); +} + + +/* + * L4 thread switch + */ + +L4_INLINE void +l4_thread_switch(l4_threadid_t destination) +{ + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebp \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "int $0x33 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebp \n\t" +#endif + : + /* No output */ + : + "S" (destination.lh.low) + : +#ifndef __pic__ + "ebx", +#endif + "eax", "ecx", "edx", "edi", "esi" + ); +} + +/* + * L4 thread schedule + */ + +L4_INLINE cpu_time_t +l4_thread_schedule(l4_threadid_t dest, l4_sched_param_t param, + l4_threadid_t *ext_preempter, l4_threadid_t *partner, + l4_sched_param_t *old_param) +{ + cpu_time_t temp; + + __asm__ + __volatile__( +#ifdef __pic__ + "pushl %%ebx \n\t" + "movl %%edx, %%ebx \n\t" +#endif + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "pushl %%ebx \n\t" /* save address of preempter */ + "movl 4(%%ebx), %%ebp \n\t" /* load preempter id */ + "movl (%%ebx), %%ebx \n\t" +/* asm_enter_kdebug("before calling thread_schedule") */ + "int $0x34 \n\t" +/* asm_enter_kdebug("after calling thread_schedule") */ + "xchgl (%%esp), %%ebx \n\t" /* save old preempter.lh.low + and get address of + preempter */ + "movl %%ebp, 4(%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* get preempter.lh.high */ + "movl %%ebp, (%%ebx) \n\t" /* write preempter.lh.high */ + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ +#ifdef __pic__ + "popl %%ebx \n\t" +#endif + + : + "=a" (*old_param), /* EAX, 0 */ + "=c" (((l4_low_high_t *)&temp)->low), /* ECX, 1 */ + "=d" (((l4_low_high_t *)&temp)->high), /* EDX, 2 */ + "=S" (partner->lh.low), /* ESI, 3 */ + "=D" (partner->lh.high) /* EDI, 4 */ + : +#ifdef __pic__ + "2" (ext_preempter), /* EDX, 2 */ +#else + "b" (ext_preempter), /* EBX, 5 */ +#endif + "0" (param), /* EAX */ + "3" (dest.lh.low), /* ESI */ + "4" (dest.lh.high) /* EDI */ +#ifndef __pic__ + : + "ebx" +#endif + ); + return temp; +} + + + +/* + * L4 task new + */ +#ifndef __pic__ +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%ebx), %%ebp \n\t" /* load pager id */ + "movl (%%ebx), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "b" (&pager), /* EBX, 2 */ + "a" (mcp_or_new_chief), /* EAX, 3 */ + "c" (esp), /* ECX, 4 */ + "d" (eip), /* EDX, 5 */ + "0" (destination.lh.low), /* ESI */ + "1" (destination.lh.high) /* EDI */ + : + "eax", "ebx", "ecx", "edx" + ); + return temp_id; +} + +#else /* __pic__ */ + +L4_INLINE l4_taskid_t +l4_task_new(l4_taskid_t destination, dword_t mcp_or_new_chief, + dword_t esp, dword_t eip, l4_threadid_t pager) +{ + l4_taskid_t temp_id; + __asm__ + __volatile__( + "pushl %%ebx \n\t" + "pushl %%ebp \n\t" /* save ebp, no memory + references ("m") after + this point */ + "movl 4(%%esi), %%edi \n\t" + "movl (%%esi), %%esi \n\t" + + "movl 4(%%edi), %%ebp \n\t" /* load pager id */ + "movl (%%edi), %%ebx \n\t" + "int $0x36 \n\t" + "popl %%ebp \n\t" /* restore ebp, no memory + references ("m") before + this point */ + "popl %%ebx \n\t" + : + "=S" (temp_id.lh.low), /* ESI, 0 */ + "=D" (temp_id.lh.high) /* EDI, 1 */ + : + "a" (mcp_or_new_chief), /* EAX, 2 */ + "c" (esp), /* ECX, 3 */ + "d" (eip), /* EDX, 4 */ + "0" (destination), /* ESI */ + "1" (&pager) /* EDI */ + : + "eax", "ecx", "edx" + ); + return temp_id; +} +#endif /* __pic__ */ + +#endif + + + + + + diff --git a/l4-x86/smp/lx/c-bind/provisional/types.h b/l4-x86/smp/lx/c-bind/provisional/types.h new file mode 100644 index 0000000..9d937aa --- /dev/null +++ b/l4-x86/smp/lx/c-bind/provisional/types.h @@ -0,0 +1,232 @@ + /* + * $Id: types.h,v 1.1 2000/07/18 13:13:38 voelp Exp $ + */ + +#ifndef __L4_TYPES_H__ +#define __L4_TYPES_H__ + +#include + +typedef unsigned char byte_t; +typedef unsigned short int word_t; +typedef unsigned int dword_t; +typedef unsigned long long qword_t; + + +typedef signed char sbyte_t; +typedef signed short int sword_t; +typedef signed int sdword_t; +typedef signed long long sqword_t; + +typedef long long cpu_time_t; + +typedef struct { + dword_t low, high; +} l4_low_high_t; + +/* + * L4 unique identifiers + */ + +typedef struct { + unsigned version_low:10; + unsigned lthread:7; + unsigned task:11; + unsigned version_high:4; + unsigned site:17; + unsigned chief:11; + unsigned nest:4; +} l4_threadid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_threadid_struct_t id; +} l4_threadid_t; + +typedef l4_threadid_t l4_taskid_t; + +typedef struct { + unsigned intr:8; + unsigned char zero[7]; +} l4_intrid_struct_t; + +typedef union { + l4_low_high_t lh; + l4_intrid_struct_t id; +} l4_intrid_t; + +#define L4_NIL_ID ((l4_threadid_t){lh:{0,0}}) +#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}}) + +/* + * L4 flex pages + */ + +typedef struct { + unsigned grant:1; + unsigned write:1; + unsigned size:6; + unsigned zero:4; + unsigned page:20; +} l4_fpage_struct_t; + +typedef union { + dword_t fpage; + l4_fpage_struct_t fp; +} l4_fpage_t; + +#define L4_PAGESIZE (0x1000) +#define L4_PAGEMASK (~(L4_PAGESIZE - 1)) +#define L4_LOG2_PAGESIZE (12) +#define L4_SUPERPAGESIZE (0x400000) +#define L4_SUPERPAGEMASK (~(L4_SUPERPAGESIZE - 1)) +#define L4_LOG2_SUPERPAGESIZE (22) +#define L4_WHOLE_ADDRESS_SPACE (32) +#define L4_FPAGE_RO 0 +#define L4_FPAGE_RW 1 +#define L4_FPAGE_MAP 0 +#define L4_FPAGE_GRANT 1 + +typedef struct { + dword_t snd_base; + l4_fpage_t fpage; +} l4_snd_fpage_t; + +/* + * L4 message dopes + */ + +typedef struct { + unsigned msg_deceited:1; + unsigned fpage_received:1; + unsigned msg_redirected:1; + unsigned src_inside:1; + unsigned snd_error:1; + unsigned error_code:3; + unsigned strings:5; + unsigned dwords:19; +} l4_msgdope_struct_t; + +typedef union { + dword_t msgdope; + l4_msgdope_struct_t md; +} l4_msgdope_t; + +/* + * L4 string dopes + */ + +typedef struct { + dword_t snd_size; + dword_t snd_str; + dword_t rcv_size; + dword_t rcv_str; +} l4_strdope_t; + +/* + * L4 timeouts + */ + +typedef struct { + unsigned rcv_exp:4; + unsigned snd_exp:4; + unsigned rcv_pfault:4; + unsigned snd_pfault:4; + unsigned snd_man:8; + unsigned rcv_man:8; +} l4_timeout_struct_t; + +typedef union { + dword_t timeout; + l4_timeout_struct_t to; +} l4_timeout_t; + +/* + * l4_schedule param word + */ + +typedef struct { + unsigned prio:8; + unsigned small:8; + unsigned zero:4; + unsigned time_exp:4; + unsigned time_man:8; +} l4_sched_param_struct_t; + +typedef union { + dword_t sched_param; + l4_sched_param_struct_t sp; +} l4_sched_param_t; + +#define L4_INVALID_SCHED_PARAM ((l4_sched_param_t){sched_param:-1}) +#define L4_SMALL_SPACE(size_mb, nr) ((size_mb >> 2) + nr * (size_mb >> 1)) + +/* + * Some useful operations and test functions for id's and types + */ + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp); +L4_INLINE int l4_is_nil_id(l4_threadid_t id); +L4_INLINE int l4_is_invalid_id(l4_threadid_t id); +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant); +L4_INLINE l4_threadid_t get_taskid(l4_threadid_t t); +L4_INLINE int thread_equal(l4_threadid_t t1,l4_threadid_t t2); +L4_INLINE int task_equal(l4_threadid_t t1,l4_threadid_t t2); + +L4_INLINE int l4_is_invalid_sched_param(l4_sched_param_t sp) +{ + return sp.sched_param == 0xffffffff; +} +L4_INLINE int l4_is_nil_id(l4_threadid_t id) +{ + return id.lh.low == 0; +} +L4_INLINE int l4_is_invalid_id(l4_threadid_t id) +{ + return id.lh.low == 0xffffffff; +} +L4_INLINE l4_fpage_t l4_fpage(unsigned long address, unsigned int size, + unsigned char write, unsigned char grant) +{ + return ((l4_fpage_t){fp:{grant, write, size, 0, + (address & L4_PAGEMASK) >> 12 }}); +} + +L4_INLINE l4_threadid_t +get_taskid(l4_threadid_t t) +{ + t.id.lthread = 0; + return t; +} + +L4_INLINE int +thread_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) + return 0; + return 1; +} + +#define TASK_MASK 0xfffe03ff +L4_INLINE int +task_equal(l4_threadid_t t1,l4_threadid_t t2) +{ + if ( ((t1.lh.low & TASK_MASK) == (t2.lh.low & TASK_MASK)) && + (t1.lh.high == t2.lh.high) ) + return 1; + else + return 0; + +/* t1.id.lthread = 0; */ +/* t2.id.lthread = 0; */ + +/* if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) */ +/* return 0; */ +/* return 1; */ + +} + +#endif /* __L4TYPES_H__ */ + + diff --git a/l4-x86/smp/lx/doc/L4 SMP x86 17.7.00.ppt b/l4-x86/smp/lx/doc/L4 SMP x86 17.7.00.ppt new file mode 100644 index 0000000..e21f2d2 Binary files /dev/null and b/l4-x86/smp/lx/doc/L4 SMP x86 17.7.00.ppt differ diff --git a/l4-x86/smp/lx/doc/L4-86-x0.ps b/l4-x86/smp/lx/doc/L4-86-x0.ps new file mode 100644 index 0000000..1b012fe --- /dev/null +++ b/l4-x86/smp/lx/doc/L4-86-x0.ps @@ -0,0 +1,3115 @@ +%!PS-Adobe-2.0 +%%Creator: dvips 5.83 (MiKTeX 1.20b) Copyright 1998 Radical Eye Software +%%Title: l4-86-x0.dvi +%%CreationDate: Sat Aug 28 14:25:11 1999 +%%Pages: 39 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%DocumentFonts: Times-Roman Times-Bold Times-Italic Helvetica +%%+ Times-BoldItalic +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips l4-86-x0 +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 1999.08.28:1425 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "1 July 1998", +% filename = "8r.enc", +% email = "tex-fonts@@tug.org", +% docstring = "Encoding for TrueType or Type 1 fonts +% to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both +% ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 +(C:\LIEDTKE\doc\l4\nucleus/l4-86-x0.dvi) @start /Fa 141[32 +2[42 46 1[23 42 5[37 55[28 45[{TeXBase1Encoding ReEncodeFont}7 +83.022 /Times-BoldItalic rf +%DVIPSBitmapFont: Fb cmmi12 14.4 1 +/Fb 1 28 df<033FB612F00203B712FC140F143F5C49B812F84917E0499026807FF0C7FC +903A1FFC001FF8D93FF0130F02C0130749486D7E49C7FC484814010003825B485AA2485A +A2485AA2485AA21603007F5E5BA2160700FF5E90C8FCA24C5AA24C5AA24C5AA26C4B5A94 +C8FC16FE6C4A5A6D13034B5A6C6CEB0FE0000F4A5A6C6C495A6C6C01FEC9FC3901FC07FC +6CB512F0013F1380D907FCCAFC3E347CB243>27 D E +%EndDVIPSBitmapFont +/Fc 135[42 5[28 3[46 23[55 3[60 2[65 1[69 8[60 23[23 +44[{TeXBase1Encoding ReEncodeFont}9 83.022 /Helvetica +rf +%DVIPSBitmapFont: Fd cmsy10 12 1 +/Fd 1 1 df<007FB912E0BA12F0A26C18E03C04789A4D>0 D E +%EndDVIPSBitmapFont +/Fe 169[58 1[49 44 53 1[44 58 58 71 49 2[27 2[44 49 58 +53 1[58 65[{TeXBase1Encoding ReEncodeFont}15 79.701 /Times-Roman +rf /Ff 208[16 47[{TeXBase1Encoding ReEncodeFont}1 58.1154 +/Times-Italic rf +%DVIPSBitmapFont: Fg cmsy10 14.4 2 +/Fg 2 34 df<007FBA12FEBCFCA36C19FE4805769F5D>0 D<1B1E1B1FA4881B0FA2881B +07A2881B0388757EA2757E1C7EA288767E767E767E89F403FC767E9938007F80777EF51F +F0007FBE12FEC01280A36CF5FE00D0EA1FF0F53FC0535AE201FEC7FC525AF407F065525A +525A52C8FC1C7EA264515AA2515A641B0764A21B0F64A21B1F99C9FCA41B1E693F79BC78 +>33 D E +%EndDVIPSBitmapFont +/Fh 135[72 104 1[80 48 56 64 1[80 1[80 120 40 80 1[40 +80 72 48 64 80 64 1[72 97[{TeXBase1Encoding ReEncodeFont}19 +143.462 /Times-Bold rf +%DVIPSBitmapFont: Fi cmmi5 5 3 +/Fi 3 117 df<380F07E0383F8FF83833D81CEA63F038C3E03CEBC07C12031438380780 +00A448C7FCA4121E120C16127D911C>114 D<137E3801FF80EA0381380703C0380E0780 +EB0300EA0F80EA07F86CB4FC6C1380EA000FEA3003127812F8EB0700EAF00EEA7FFCEA1F +F012127C911C>I<13C0EA01E0A3EA03C0A4EAFFFCA2EA0780A2EA0F00A4121EA31304EA +3C0CA213181370EA1FE0EA0F800E1A7D9917>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj cmex10 10 4 +/Fj 4 63 df56 D58 +D60 D62 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk cmmi6 6 13 +/Fk 13 120 df60 D<12E012F812FEEA3F80EA0FE0EA03F8EA00FEEB3F80EB0FC0EB03F0EB00 +FC147FEC1FC0EC07F0EC01FCEC007FED1FC01507151FED7F00EC01FCEC07F0EC1FC0027F +C7FC14FCEB03F0EB0FC0EB3F8001FEC8FCEA03F8EA0FE0EA3F8000FEC9FC12F812E02223 +7A9D30>62 D101 D103 D<13F8EA0FF0A21200A2 +485AA4485AA4380787E0EB9FF8EBB83CEBE01C380FC01E1380A21300001E5BA35C5AA2EC +F0201530481460EB01E015C0A239F000E380ECFF000060133C1C247CA224>I<1338137C +A2137813701300A7EA0780EA1FC0EA38E01230EA60F0EAC1E0A3EA03C0A3EA0780A2EA0F +0013041306EA1E0CA21318121CEA1E70EA0FE0EA07800F237DA116>I108 D111 D<3801E01F3903F07FC0390639C1E0390C3F80F0EB3E00001814 +F8013C137815F8C65AA49038F001F0A3EC03E0D801E013C0EBF00715809038F80F003803 +DC3CEBCFF8EBC7E001C0C7FC485AA448C8FCA2EA7FF012FF1D20809520>I<380F01F038 +1FC7F83831CE1CEA61F8EBF03C00C1137C13E014383803C000A4485AA448C7FCA4121EA2 +120C16177D951D>114 DI<133013785BA4485AA4485AB51280A23803C00048 +5AA448C7FCA4121EA25B1480383C03001306A25BEA1C38EA0FF0EA07C011217D9F18>I< +D807801470260FE00313F83938F007801230006090380F007812C01638EAC1E00001011E +1330EA03C0A34848481360A316C0A2ED0180147C00039038DC03009038E1DF063901FF8F +FC39007E03F825177D952C>119 D E +%EndDVIPSBitmapFont +/Fl 133[26 3[29 33 18 26 26 1[33 33 1[48 1[29 1[18 1[33 +1[29 33 1[33 33 8[41 26[45 9[33 4[17 2[45 1[22 22 40[{ +TeXBase1Encoding ReEncodeFont}23 66.4176 /Times-Italic +rf +%DVIPSBitmapFont: Fm cmsy6 6 6 +/Fm 6 55 df0 D<0060143000E014706C14F00078EB01E06CEB +03C06CEB07806CEB0F003807801E6C6C5A6C6C5A6C6C5AEB79E0EB3FC06D5A6DC7FC497E +497EEB79E0EBF0F03801E07848487E48487E48487E001EEB078048EB03C048EB01E048EB +00F0481470006014301C1D779A30>2 D<136013701360A20040132000E0137038F861F0 +387E67E0381FFF803807FE00EA00F0EA07FE381FFF80387E67E038F861F038E060700040 +132000001300A21370136014157B9620>I20 +D<12E012F812FEEA3F80EA0FE0EA03F8EA00FEEB3F80EB0FC0EB03F0EB00FC147FEC1FC0 +EC07F0EC01FCEC007FED1FC01507151FED7F00EC01FCEC07F0EC1FC0027FC7FC14FCEB03 +F0EB0FC0EB3F8001FEC8FCEA03F8EA0FE0EA3F80007EC9FC12F812E0CAFCA9007FB61280 +B712C0A2222F7AA230>I<1570A215F015E01401EC03C01580140715005C140E141E5C14 +381478147014F05C1301495A5C130791C7FC5B130E131E131C133C5B137013F05B12015B +1203485A90C8FC5A120E121E121C123C5A127012F05A12601C2F77A300>54 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn cmsy7 7 3 +/Fn 3 55 df0 D<160E163E16FEED03F8ED0FE0ED3F80EDFE00 +EC03F8EC0FE0EC3F8002FEC7FCEB03F8EB0FE0EB3F8001FEC8FCEA03F8EA0FE0EA3F8000 +FEC9FC12F812FEEA3F80EA0FE0EA03F8EA00FEEB3F80EB0FE0EB03F8EB00FEEC3F80EC0F +E0EC03F8EC00FEED3F80ED0FE0ED03F8ED00FE163E160E1600AB007FB612FCB712FEA227 +357AA734>20 D<150EA2151E151C153C1578157015F015E0140115C0140315801407EC0F +00140E141E141C143C14381478147014F0495A5C13035C130791C7FC5B131E131C133C13 +381378137013F05B1201485A5B120790C8FC5A120E121E121C123C5A127012F05A12601F +3576A800>54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo cmr8 8 9 +/Fo 9 62 df43 +D48 D<130C133C137CEA03FC12FFEAFC7C1200B3B113FE387F +FFFEA2172C7AAB23>I<140EA2141E143EA2147E14FEA2EB01BE1303143E1306130E130C +131813381330136013E013C0EA0180120313001206120E120C5A123812305A12E0B612FC +A2C7EA3E00A9147F90381FFFFCA21E2D7EAC23>52 D<000CEB0180380FC01F90B512005C +5C14F014C0D80C7EC7FC90C8FCA8EB1FC0EB7FF8380DE07C380F801F01001380000E130F +000CEB07C0C713E0A2140315F0A4127812FCA448EB07E012E0006014C00070130F6C1480 +6CEB1F006C133E380780F83801FFE038007F801C2D7DAB23>II56 DI61 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fp cmmi8 8 25 +/Fp 25 120 df<131C013EEB0380ED07C0017E130F1680137CA201FC131F16005BA20001 +5C153E5BA20003147E157C5BA20007ECFC08EDF8185BA2000F0101133816309038E003F0 +02071370001F90380EF8609039F83C78E090397FF03FC090391FC00F0048C9FCA2123EA2 +127EA2127CA212FCA25AA21270252C7E9D2A>22 D<0103B512F0131F137F90B612E03A01 +FC1F80003903F00FC03807C00748486C7E121F1300123EA25AA2140700FC5C5AA2140F5D +141F92C7FC143E0078133C147C007C5B383C01E0381F07C0D807FFC8FCEA01F8241E7D9C +28>27 D<123C127EB4FCA21380A2127F123D1201A312031300A25A1206120E5A5A5A1260 +09157A8714>59 D<15C0140114031580A214071500A25C140EA2141E141CA2143C143814 +781470A214F05CA213015CA213035C130791C7FCA25B130EA2131E131CA2133C1338A213 +78137013F05BA212015BA212035BA2120790C8FC5A120EA2121E121CA2123C1238A21278 +1270A212F05AA21A437CB123>61 D<90383FFFFEA2010090C8FC5C5CA21301A25CA21303 +A25CA21307A25CA2130FA25CA2131FA25CA2133FA291C7EA0180A24914031700017E5C16 +0601FE140EA2495C163C12015E49EB01F84B5A0003141FB7FC5E292D7DAC30>76 +D<013FB6FC17E0903A00FE0007F0EE01FC4AEB007EA2010181A25C1880010316005F5CA2 +010715FEA24A5C4C5A010F4A5A4C5A4AEB1F8004FFC7FC91B512F84914C00280C9FCA313 +3F91CAFCA35B137EA313FE5BA312015BA21203B512E0A2312D7DAC2D>80 +D<000FB8FCA23B1FC003F8003F0100151F001C4A130E123C003801071406123000704A13 +0EA20060010F140C12E0485CA2141FC715005DA2143FA292C8FCA25CA2147EA214FEA25C +A21301A25CA21303A25CA21307A25C130F131F001FB512F0A2302D7FAC29>84 +D<90260FFFFCEB7FFFA29026007FC0EB0FF06E48148018006E6C131E1718020F5C6F5B02 +075C6F485A020349C7FCEDF8065E6E6C5A5E6E6C5A5EED7F8093C8FC6F7EA26F7E153F15 +6FEDCFE0EC018791380307F0EC0703020E7F141C4A6C7E14704A6C7E495A4948137F49C7 +FC010E6E7E5B496E7E5BD801F081D807F8143FD8FFFE0103B5FCA2382D7EAC3A>88 +D97 +D<13F8121FA21201A25BA21203A25BA21207A25BA2120FEBC7E0EB9FF8EBB83C381FF01E +EBE01F13C09038800F80EA3F00A2123EA2007E131FA2127CA2143F00FC14005AA2147EA2 +147C14FC5C387801F01303495A383C0F806C48C7FCEA0FFCEA03F0192F7DAD1E>II<151FEC03FFA2EC003FA2153EA2157EA2157CA215FCA215 +F8A21401EB07E190381FF9F0EB7C1DEBF80FEA01F03903E007E0EA07C0120FEA1F8015C0 +EA3F00140F5A007E1480A2141F12FE481400A2EC3F021506143E5AEC7E0E007CEBFE0C14 +FC0101131C393E07BE18391F0E1E38390FFC0FF03903F003C0202F7DAD24>II<157C4AB4FC913807C380EC0F +87150FEC1F1FA391383E0E0092C7FCA3147E147CA414FC90383FFFF8A2D900F8C7FCA313 +015CA413035CA413075CA5130F5CA4131F91C8FCA4133EA3EA383C12FC5BA25B12F0EAE1 +E0EA7FC0001FC9FC213D7CAE22>I<14FCEB03FF90380F839C90381F01BC013E13FCEB7C +005B1201485A15F8485A1401120F01C013F0A21403121F018013E0A21407A215C0A2000F +130F141F0007EB3F80EBC07F3803E1FF3800FF9F90383E1F0013005CA2143EA2147E0038 +137C00FC13FC5C495A38F807E038F00F80D87FFEC7FCEA1FF81E2C7E9D22>I<1307EB0F +80EB1FC0A2EB0F80EB070090C7FCA9EA01E0EA07F8EA0E3CEA1C3E123812301270EA607E +EAE07C12C013FC485A120012015B12035BA21207EBC04014C0120F13801381381F018013 +03EB0700EA0F06131EEA07F8EA01F0122E7EAC18>105 D<131FEA03FFA2EA003FA2133E +A2137EA2137CA213FCA25BA2120115F89038F003FCEC0F0E0003EB1C1EEC387EEBE07014 +E03807E1C09038E3803849C7FC13CEEA0FDC13F8A2EBFF80381F9FE0EB83F0EB01F81300 +481404150C123EA2007E141C1518007CEBF038ECF83000FC1470EC78E048EB3FC00070EB +0F801F2F7DAD25>107 D<27078007F0137E3C1FE01FFC03FF803C18F0781F0783E03B38 +78E00F1E01263079C001B87F26707F8013B00060010013F001FE14E000E015C0485A4914 +800081021F130300015F491400A200034A13076049133E170F0007027EEC808018814901 +7C131F1801000F02FCEB3F03053E130049495C180E001F0101EC1E0C183C010049EB0FF0 +000E6D48EB03E0391F7E9D3E>109 D111 D<90387C01F89038FE07FE3901CF8E0F3A03879C0780D907B813C00007 +13F000069038E003E0EB0FC0000E1380120CA2D8081F130712001400A249130F16C0133E +A2017EEB1F80A2017C14005D01FC133E5D15FC6D485A3901FF03E09038FB87C0D9F1FFC7 +FCEBF0FC000390C8FCA25BA21207A25BA2120FA2EAFFFCA2232B829D24>I<3807C01F39 +0FF07FC0391CF8E0E0383879C138307B8738707F07EA607E13FC00E0EB03804848C7FCA2 +128112015BA21203A25BA21207A25BA2120FA25BA2121FA290C8FC120E1B1F7E9D20> +114 DI<130E131FA25BA2133EA2 +137EA2137CA213FCA2B512F8A23801F800A25BA21203A25BA21207A25BA2120FA25BA200 +1F1310143013001470146014E0381E01C0EB0380381F0700EA0F0EEA07FCEA01F0152B7E +A919>I118 +DI +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fq cmmi7 7 6 +/Fq 6 120 df<12E012F812FEEA3F80EA0FE0EA03F8EA00FEEB3F80EB0FE0EB03F8EB00 +FEEC3F80EC0FE0EC03F8EC00FEED3F80ED0FE0ED03F8ED00FE163E16FEED03F8ED0FE0ED +3F80EDFE00EC03F8EC0FE0EC3F8002FEC7FCEB03F8EB0FE0EB3F8001FEC8FCEA03F8EA0F +E0EA3F8000FEC9FC12F812E027277AA134>62 D101 +D<9038F007C03901FC1FF039031E78780006EBE03C90381FC01C000CEB801E14005B0018 +141F133E1200137E153E137CA213FC157C5B1578000114F0A2EC01E0EC03C03903FC0780 +9038FE1F00EBE7FCEBE1F0D807E0C7FCA25BA2120FA25B121FEAFFF8A22025809922> +112 D115 D<131C133EA25BA45BA4485AB512E0A23801 +F000485AA4485AA4485AA448C7FC1460A214C0123EEB0180EB0300EA1E06EA1F1CEA0FF8 +EA03E013267EA419>I119 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fr cmr6 6 13 +/Fr 13 62 df<130C1338137013E0EA01C0EA038013005A120EA25AA25AA312781270A3 +12F0AB1270A312781238A37EA27EA27E7E1380EA01C0EA00E013701338130C0E317AA418 +>40 D<12C012707E7E7E7E7E1380EA01C0A2EA00E0A21370A313781338A3133CAB1338A3 +13781370A313E0A2EA01C0A2EA038013005A120E5A5A5A12C00E317CA418>I<13FF0003 +13C0380781E0380F00F0001E137848133CA248131EA400F8131FAD0078131EA2007C133E +003C133CA26C13786C13F0380781E03803FFC0C6130018227DA01E>48 +D<13E01201120712FF12F91201B3A7487EB512C0A212217AA01E>II<13FF000313C0380F03E0381C00F014F8003E13FC147CA2001E13 +FC120CC712F8A2EB01F0EB03E0EB0FC03801FF00A2380003E0EB00F01478147C143E143F +1230127812FCA2143E48137E0060137C003813F8381E03F0380FFFC00001130018227DA0 +1E>I<14E01301A213031307A2130D131D13391331136113E113C1EA01811203EA070112 +06120C121C12181230127012E0B6FCA2380001E0A6EB03F0EB3FFFA218227DA11E>I<00 +101330381E01F0381FFFE014C01480EBFE00EA1BF00018C7FCA513FE381BFF80381F03C0 +381C01E0381800F014F8C71278A2147CA21230127812F8A214784813F8006013F0387001 +E01238381E07803807FF00EA01F816227CA01E>II<1230123C003FB5FCA24813FE14FC3860001C143814704813 +E014C0EA0001EB0380EB07001306130E5BA25BA21378A35BA41201A76C5A18237CA11E> +I<137F3803FFC0380781E0380E00704813380018131C1238A3123C003F1338381FC078EB +E0F0380FF9E03807FF80120114C0000713F0380F0FF8381C03FC383801FE3870007E141F +48130F1407A314060070130E0078130C6C1338001F13F03807FFC0C6130018227DA01E> +I<13FE3803FFC0380781E0380E0070481378003C133848133CA200F8131EA3141FA40078 +133FA26C137F121C380F01DF3807FF9F3803FE1EC7FCA2143E143C001C1338003E137814 +70003C13E0381801C0381C0780380FFE00EA03F818227DA01E>I61 D E +%EndDVIPSBitmapFont +/Fs 107[46 46 24[32 37 37 55 37 42 23 32 32 42 42 42 +42 60 23 37 1[23 42 42 23 37 42 37 42 42 3[32 1[32 2[51 +69 51 1[46 42 51 1[51 1[55 69 46 55 1[28 1[60 51 51 60 +55 51 51 3[56 2[28 5[42 1[42 42 42 23 21 28 21 56 42 +28 28 28 36[42 2[{TeXBase1Encoding ReEncodeFont}64 83.022 +/Times-Italic rf /Ft 134[50 50 2[55 33 39 44 55 55 50 +55 83 28 2[28 1[50 1[44 55 44 55 50 10[72 72 66 55 72 +1[61 2[94 1[78 1[39 78 78 61 66 72 72 66 9[50 1[50 1[50 +50 50 50 2[25 33 45[{TeXBase1Encoding ReEncodeFont}43 +99.6264 /Times-Bold rf +%DVIPSBitmapFont: Fu cmr10 10 14 +/Fu 14 112 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA21207 +5B120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203 +A26C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 +D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F +A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 +5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 +F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DIII<1538A2157815F8A2140114031407A2140F +141F141B14331473146314C313011483EB030313071306130C131C131813301370136013 +C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AB4A7E0103B5 +12F8A325397EB82A>I54 D +56 D<007FB812F8B912FCA26C17F8CCFCAE007FB812F8B912FCA26C17F836167B9F41> +61 D100 D<2703F00FF0EB1FE000FFD93FFCEB7FF8913AF03F01E07E903BF1C0 +1F83803F3D0FF3800FC7001F802603F70013CE01FE14DC49D907F8EB0FC0A2495CA3495C +B3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445>109 D111 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fv cmsy10 10 7 +/Fv 7 106 df<007FB81280B912C0A26C17803204799641>0 D<0060150600F8150F6C15 +1F007E153F6C157E6C6C14FC6C6CEB01F86C6CEB03F06C6CEB07E06C6CEB0FC06C6CEB1F +80017EEB3F006D137E6D6C5A90380FC1F8903807E3F0903803F7E06DB45A6D5B6EC7FCA2 +4A7E497F903803F7E0903807E3F090380FC1F890381F80FC90383F007E017E7F49EB1F80 +4848EB0FC04848EB07E04848EB03F04848EB01F84848EB00FC48C8127E007E153F48151F +48150F00601506282874A841>2 D15 D24 +D49 D<14C0EB01E01303A214C01307A2 +1480130FA2EB1F00A2131E133EA25BA2137813F8A2485AA25B1203A25B1207A2485AA290 +C7FC5AA2123EA2123C127CA2127812F8A41278127CA2123C123EA27EA27E7FA26C7EA212 +037FA212017FA26C7EA21378137CA27FA2131E131FA2EB0F80A2130714C0A2130314E0A2 +1301EB00C0135278BD20>104 D<126012F07EA21278127CA2123C123EA27EA27E7FA26C +7EA212037FA26C7EA212007FA21378137CA27FA2131E131FA2EB0F80A2130714C0A21303 +14E0A414C01307A21480130FA2EB1F00A2131E133EA25BA2137813F8A25B1201A2485AA2 +5B1207A2485AA290C7FC5AA2123EA2123C127CA2127812F8A25A126013527CBD20>I +E +%EndDVIPSBitmapFont +/Fw 135[86 3[57 1[76 1[96 1[96 4[48 96 2[76 96 2[86 29[124 +1[124 14[86 86 49[{TeXBase1Encoding ReEncodeFont}14 172.188 +/Times-Bold rf +%DVIPSBitmapFont: Fx cmr7 7 7 +/Fx 7 62 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 +15267BA521>I<13FF000313E0380E03F0381800F848137C48137E00787F12FC6CEB1F80 +A4127CC7FC15005C143E147E147C5C495A495A5C495A010EC7FC5B5B903870018013E0EA +0180390300030012065A001FB5FC5A485BB5FCA219267DA521>I<13FF000313E0380F01 +F8381C007C0030137E003C133E007E133FA4123CC7123E147E147C5C495AEB07E03801FF +8091C7FC380001E06D7E147C80143F801580A21238127C12FEA21500485B0078133E0070 +5B6C5B381F01F03807FFC0C690C7FC19277DA521>I<0018130C001F137CEBFFF85C5C14 +80D819FCC7FC0018C8FCA7137F3819FFE0381F81F0381E0078001C7F0018133EC7FC80A2 +1580A21230127C12FCA3150012F00060133E127000305B001C5B380F03E03803FFC0C648 +C7FC19277DA521>53 DI61 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fy cmmi10 10 31 +/Fy 31 121 df22 D<027FB512C00103B612E0130F5B017F15C09026FF81FEC7FC39 +01FC007E48487F485A497F484880485AA248C7FCA2127EA2153F00FE92C7FC5AA25D157E +5A5DA24A5AA24A5A007C495A5D003C495A003E013FC8FC6C137C380F81F83803FFE0C66C +C9FC2B257DA32F>27 D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313 +005A1206120E5A5A5A12600A19798817>59 D<1760177017F01601A21603A21607160FA2 +4C7EA216331673166316C3A2ED0183A2ED0303150683150C160115181530A21560A215C0 +14011580DA03007FA202061300140E140C5C021FB5FC5CA20260C7FC5C83495A8349C8FC +1306A25BA25B13385B01F01680487E000716FFB56C013F13FF5EA2383C7DBB3E>65 +D<9339FF8001C0030F13E0037F9038F80380913A01FF807E07913A07F8000F0FDA1FE0EB +079FDA3F80903803BF0002FFC76CB4FCD901FC80495A4948157E495A495A4948153E017F +163C49C9FC5B1201484816385B1207485A1830121F4993C7FCA2485AA3127F5BA312FF90 +CCFCA41703A25F1706A26C160E170C171C5F6C7E5F001F5E6D4A5A6C6C4A5A16076C6C02 +0EC8FC6C6C143C6C6C5C6CB4495A90393FE00FC0010FB5C9FC010313FC9038007FC03A3D +7CBA3B>67 D<0103B812F05BA290260007F8C7123F4B1407F003E0020F150118005DA214 +1FA25D19C0143FA24B1330A2027F1470190092C7126017E05C16014A495A160F49B6FCA2 +5F9138FC000F01031407A24A6DC8FCA201075C18034A130660010F160693C7FC4A150E18 +0C011F161C18184A1538A2013F5E18F04A4A5AA2017F15074D5A91C8123F49913803FF80 +B9FCA295C7FC3C397DB83D>69 D<0103B500F8903807FFFC5BA290260007F8C813804BED +FC0019F0020F4B5AF003804B4AC7FC180E021F1538604B5CEF0380023F4AC8FC170E4B13 +3C1770027F5C4C5ADB0007C9FC160E4A5B167E4A13FE4B7E01015B92380E7F80ECFC1CED +383F010301E07FECFDC04A486C7EECFF00D907FC6D7E5C4A130783130F707E5C1601011F +81A24A6D7EA2013F6F7EA24A143F84137F717E91C8123F496C81B60107B512C0A2614639 +7DB847>75 D<0103B6FC5B5E90260007FCC8FC5D5D140FA25DA2141FA25DA2143FA25DA2 +147FA292C9FCA25CA25CA21301A25CA21303A25CA2130718404A15C0A2010F150118804A +1403A2011F16005F4A1406170E013F151E171C4A143C177C017F5D160391C7120F49EC7F +F0B8FCA25F32397DB839>I<0003B812FEA25A903AF8003FC00101C0913880007E484816 +3C90C7007F141C121E001C92C7FCA2485CA200305C007017180060130112E0485CA21403 +C716005DA21407A25DA2140FA25DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA2 +1301A25CA21303A25CEB0FFC003FB6FC5AA237397EB831>84 D<49B500F890387FFFF095 +B5FC1AE0D90003018090380FFC004BC713E00201ED07804EC7FC6E6C140E606F5C705B60 +6F6C485A4D5A031F91C8FCEEE0065F6F6C5A5F03075B705A16F96FB45A94C9FC6F5AA36F +7EA34B7FED037F9238063FC0150E4B6C7E1538ED700F03E07F15C04A486C7EEC03000206 +13034A805C4A6D7E14704A1300494880495A49C86C7E130E011E153F017E4B7ED803FF4B +7E007F01E0011FEBFFC0B5FC6144397EB845>88 D<147E903803FF8090390FC1C3809039 +1F00EFC0017E137F49133F485A4848EB1F8012075B000F143F48481400A2485A5D007F14 +7E90C7FCA215FE485C5AA214015D48150CA21403EDF01C16181407007C1538007E010F13 +30003E131F027B13706C01E113E03A0F83C0F9C03A03FF007F80D800FCEB1F0026267DA4 +2C>97 D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0FCEBE3FF90 +38E707C0390FFE03E09038F801F001F013F8EBE000485A15FC5BA2123F90C7FCA214015A +127EA2140312FE4814F8A2140715F05AEC0FE0A215C0EC1F80143F00781400007C137E5C +383C01F86C485A380F07C06CB4C7FCEA01FC1E3B7CB924>II<163FED1FFFA3ED007F16 +7EA216FEA216FCA21501A216F8A21503A216F0A21507A2027E13E0903803FF8790380FC1 +CF90381F00EF017EEB7FC049133F485A4848131F000715805B000F143F485A1600485A5D +127F90C7127EA215FE5A485CA21401A248ECF80CA21403161CEDF0181407007C1538007E +010F1330003E131F027B13706C01E113E03A0F83C0F9C03A03FF007F80D800FCEB1F0028 +3B7DB92B>II<16F8ED03FEED0F8792381F0F80ED3E3F167F157CA215FC170016 +1C4A48C7FCA414035DA414075DA20107B512F0A39026000FE0C7FC5DA4141F5DA4143F92 +C8FCA45C147EA514FE5CA413015CA4495AA45C1307A25C121E123F387F8F80A200FF90C9 +FC131E12FEEA7C3CEA7878EA1FF0EA07C0294C7CBA29>II<14E0EB03F8A21307A314F0EB01C090C7FCAB13F8EA03FEEA070F000E1380 +121C121812381230EA701F1260133F00E0130012C05BEA007EA213FE5B1201A25B12035B +A20007131813E01438000F133013C01470EB806014E014C01381EB838038078700EA03FE +EA00F815397EB71D>105 D107 DIIII<90390F8003F090391FE00FFC +903939F03C1F903A70F8700F80903AE0FDE007C09038C0FF80030013E000014913030180 +15F05CEA038113015CA2D800031407A25CA20107140FA24A14E0A2010F141F17C05CEE3F +80131FEE7F004A137E16FE013F5C6E485A4B5A6E485A90397F700F80DA383FC7FC90387E +1FFCEC07E001FEC9FCA25BA21201A25BA21203A25B1207B512C0A32C3583A42A>I<3903 +E001F83907F807FE390E3C1E07391C3E381F3A183F703F800038EBE07F0030EBC0FF0070 +5B00601500EC007E153CD8E07F90C7FCEAC07EA2120013FE5BA312015BA312035BA31207 +5BA3120F5BA3121F5B0007C9FC21267EA425>114 D<14FF010313C090380F80F090383E +00380178131C153C4913FC0001130113E0A33903F000F06D13007F3801FFE014FC14FF6C +14806D13C0011F13E013039038003FF014071403001E1301127FA24814E0A348EB03C012 +F800E0EB07800070EB0F006C133E001E13F83807FFE0000190C7FC1E267CA427>II<13F8D803FE1438D8070F147C +000E6D13FC121C1218003814011230D8701F5C12601503EAE03F00C001005B5BD8007E13 +07A201FE5C5B150F1201495CA2151F120349EC80C0A2153F1681EE0180A2ED7F0303FF13 +0012014A5B3A00F8079F0E90397C0E0F1C90393FFC07F8903907F001F02A267EA430>I< +01F8EB03C0D803FEEB07E0D8070F130F000E018013F0121C12180038140700301403D870 +1F130112601500D8E03F14E000C090C7FC5BEA007E16C013FE5B1501000115805B150316 +001203495B1506150E150C151C151815385D00015C6D485A6C6C485AD97E0FC7FCEB1FFE +EB07F024267EA428>I<01F816F0D803FE9138E001F8D8070F903801F003000ED9800314 +FC121C12180038020713010030EDE000D8701F167C1260030F143CD8E03F163800C00100 +5B5BD8007E131F183001FE5C5B033F1470000117604991C7FCA218E000034A14C049137E +17011880170318005F03FE1306170E000101015C01F801BF5B3B00FC039F8070903A7E0F +0FC0E0903A1FFC03FFC0902703F0007FC7FC36267EA43B>I<903907E001F090391FF807 +FC9039783E0E0F9039E01F1C1FD801C09038383F803A03800FF07F0100EBE0FF5A000E4A +1300000C157E021F133C001C4AC7FC1218A2C7123FA292C8FCA25CA2147EA214FEA24A13 +0CA20101141C001E1518003F5BD87F81143801835C00FF1560010714E03AFE0E7C01C0D8 +7C1C495A2778383E0FC7FC391FF00FFC3907C003F029267EA42F>I +E +%EndDVIPSBitmapFont +/Fz 134[42 42 60 42 46 28 32 37 1[46 42 46 69 23 46 1[23 +46 42 28 37 46 37 1[42 8[60 83 3[46 60 1[51 65 1[78 55 +2[32 1[65 4[55 60 6[28 42 42 42 42 1[42 42 42 42 1[23 +1[28 45[{TeXBase1Encoding ReEncodeFont}45 83.022 /Times-Bold +rf /FA 135[103 3[69 80 92 2[103 115 1[57 2[57 1[103 1[92 +3[103 8[149 11[138 4[161 3[149 138 9[103 1[103 1[103 +4[57 1[69 45[{TeXBase1Encoding ReEncodeFont}21 206.559 +/Times-Bold rf /FB 166[60 60 78 1[60 51 46 55 1[46 60 +60 74 51 60 1[28 60 60 46 51 60 55 1[60 8[42 42 42 42 +42 42 42 42 1[23 21 28 45[{.167 SlantFont TeXBase1Encoding ReEncodeFont} +32 83.022 /Times-Roman rf /FC 206[25 49[{TeXBase1Encoding ReEncodeFont} +1 49.8132 /Times-Roman rf /FD 206[29 1[16 47[{ +TeXBase1Encoding ReEncodeFont}2 58.1154 /Times-Roman +rf +%DVIPSBitmapFont: FE cmsy8 8 6 +/FE 6 106 df<006015C000E014016C14030078EC07806CEC0F006C141E6C5C6C6C5B6C +6C5B6C6C485A6C6C485A90387807806D48C7FCEB1E1E6D5AEB07F86D5A6D5A497E497EEB +0F3CEB1E1E497E496C7E496C7E48486C7E48486C7E4848137848C77E001E80488048EC07 +8048EC03C048140100601400222376A137>2 D13 D<01FE150C3803FF804813E0487F381F +83F8263E00FC141C003C133F486D6C131800706D6C133800606D6C137800E0D901F013F0 +913800FC014891387F07E092383FFFC06F138003071300ED01FC2E117C9837>24 +D49 D<13031307130F130EA2131E131C133C1338A2137813 +7013F013E0A2120113C01203138012071300A25A120E121E121CA2123C123812781270A2 +12F05A7E1270A212781238123C121CA2121E120E120F7EA21380120313C0120113E01200 +A213F0137013781338A2133C131C131E130EA2130F1307130310437AB11B>104 +D<12E0A27E1270A212781238123C121CA2121E120E120F7EA21380120313C0120113E012 +00A213F0137013781338A2133C131C131E130EA2130F1307130F130EA2131E131C133C13 +38A21378137013F013E0A2120113C01203138012071300A25A120E121E121CA2123C1238 +12781270A212F05AA210437CB11B>I E +%EndDVIPSBitmapFont +/FF 104[66 2[29 29 24[29 33 33 48 33 33 18 26 22 33 33 +33 33 52 18 33 1[18 33 33 22 29 33 29 33 29 8[48 1[48 +1[41 37 44 1[37 48 1[59 41 48 1[22 1[48 37 41 48 44 44 +48 7[33 33 33 33 33 33 33 33 33 33 18 17 22 17 37 33 +22 22 1[52 34[37 37 2[{TeXBase1Encoding ReEncodeFont}67 +66.4176 /Times-Roman rf /FG 173[35 82[{TeXBase1Encoding ReEncodeFont}1 +53.134 /Times-Roman rf /FH 134[60 1[86 60 66 40 47 53 +1[66 60 66 100 33 2[33 66 60 40 53 66 53 66 60 12[80 +66 86 1[73 1[86 113 80 93 1[47 93 1[73 1[86 86 10[60 +60 60 60 60 60 60 60 2[30 40 45[{TeXBase1Encoding ReEncodeFont}44 +119.552 /Times-Bold rf /FI 87[28 17[42 1[37 37 24[37 +42 42 60 42 42 23 32 28 42 42 42 42 65 23 42 23 23 42 +42 28 37 42 37 42 37 28 2[28 1[28 1[60 60 78 60 60 51 +46 55 1[46 60 60 74 51 60 32 28 60 60 46 51 60 55 55 +60 76 2[47 1[23 23 42 42 42 42 42 42 42 42 42 42 23 21 +28 21 47 42 28 28 28 3[42 1[28 29[46 46 2[{ +TeXBase1Encoding ReEncodeFont}84 83.022 /Times-Roman +rf /FJ 138[50 28 39 33 2[50 50 2[50 1[28 50 50 1[44 50 +44 13[72 8[61 1[39 6[66 1[72 7[50 50 5[50 50 1[28 2[25 +44[{TeXBase1Encoding ReEncodeFont}24 99.6264 /Times-Roman +rf /FK 140[56 48 2[72 72 4[40 3[64 12[104 1[104 37[72 +1[36 46[{TeXBase1Encoding ReEncodeFont}10 143.462 /Times-Roman +rf /FL 135[103 2[103 1[80 69 2[103 103 1[57 2[57 2[69 +92 1[92 1[92 8[149 1[149 3[138 3[149 184 126 19[103 1[103 +1[103 52[{TeXBase1Encoding ReEncodeFont}21 206.559 /Times-Roman +rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop 1202 1471 a FL(L4)52 b(Nucleus)g(V)-23 b(ersion)53 +b(X)1363 1720 y(Reference)c(Manual)1968 2135 y(x86)1780 +2551 y FK(V)-16 b(ersion)34 b(X.0)1820 2916 y FJ(Jochen)25 +b(Liedtk)o(e)1766 3032 y FI(Uni)n(v)o(ersit)5 b(\250)-33 +b(at)19 b(Karlsruhe)1808 3148 y(liedtk)o(e@ira.uka.de)1792 +3550 y FJ(August)k(28,)i(1999)1728 3666 y(Under)g(Construction)p +eop +%%Page: 2 2 +2 1 bop eop +%%Page: 3 3 +3 2 bop 3881 -290 a FI(3)322 -57 y FH(Ho)o(w)30 b(T)-11 +b(o)30 b(Read)g(This)g(Manual)322 129 y FI(This)e(reference)d(manual)i +(consists)g(of)g(tw)o(o)h(parts,)g(\(1\))f(a)h(processor)n +(-independent)22 b(description)k(of)h(the)g(principles)g(and)322 +229 y(mechanisms)17 b(of)h(L4)g(and)f(\(2\))g(a)h(more)f(detailed)h +(processor)n(-speci\002c)e(description.)23 b(P)o(art)17 +b(2)h(refers)g(to)g(the)g(Intel)f(processors,)322 328 +y(Pentium)617 296 y FG(R)600 298 y FE(\015)s FD(1)728 +328 y FI(and)j(Pentium)1163 296 y FG(R)1147 298 y FE(\015)1220 +328 y FI(Pro.)322 2740 y FH(Cr)n(edits)322 2926 y FI(Helpful)h(contrib) +n(utions)f(for)h(impro)o(ving)e(this)j(reference)e(manual)h(and)g(the)g +(L4)h(interf)o(ace)f(came)g(from)f(man)o(y)h(persons,)g(in)322 +3025 y(particular)j(from)g(Bryan)h(F)o(ord,)g(Hermann)e(H)5 +b(\250)-33 b(artig,)26 b(Michael)e(Hohmuth,)h(Sebastian)f(Sch)7 +b(\250)-35 b(onber)o(g,)23 b(Jean)j(W)-7 b(olter)m(,)26 +b(K)n(e)n(vin)322 3125 y(Elphinstone,)19 b(T)m(rent)g(Jae)o(ger)m(,)g +(Y)-9 b(oonho)18 b(P)o(ark,)i(V)-11 b(olkmar)19 b(Uhlig,)h(and)f +(Gernot)h(Heiser)-5 b(.)p 322 5328 1440 4 v 413 5387 +a FC(1)442 5410 y FF(Pentium)681 5385 y FG(R)662 5387 +y FE(\015)738 5410 y FF(is)17 b(a)g(re)o(gistered)j(trademark)e(of)f +(Intel)i(Corp.)p eop +%%Page: 4 4 +4 3 bop 156 -290 a FI(4)p eop +%%Page: 5 5 +5 4 bop 322 -290 a FB(CONTENTS)3125 b FI(5)322 608 y +FA(Contents)322 1122 y Fz(1)83 b(L4)21 b(in)g(General)2939 +b(7)322 1305 y(2)83 b(L4-X/x86)3100 b(9)447 1405 y FI(2.1)86 +b(Notational)19 b(con)m(v)o(entions)55 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.) +h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)154 b(9)447 +1504 y(2.2)86 b(Data)20 b(T)-7 b(ypes)78 b(.)42 b(.)f(.)g(.)g(.)h(.)f +(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) +h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g +(.)h(.)112 b(10)638 1604 y(2.2.1)98 b(Unique)19 b(Ids)68 +b(.)42 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)h(.)112 b(10)638 1703 y(2.2.2)98 b(Fpages)75 +b(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)g(.)h(.)f(.)g(.)h(.)112 b(10)638 1803 y(2.2.3)98 +b(Messages)50 b(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 b(11)638 1903 +y(2.2.4)98 b(T)m(imeouts)61 b(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(13)447 2002 y(2.3)86 b(L4)20 b(Calls)45 b(.)c(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)h(.)112 b(15)638 2102 y(ipc)39 b(.)i(.)h(.)f(.)g(.)g(.)h(.)f(.)g +(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)h(.)112 b(16)638 2202 y(id)p 708 2202 +25 4 v 29 w(nearest)60 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g +(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(23)638 2301 y(fpage)p 829 2301 V 28 w(unmap)73 b(.)41 +b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) +g(.)g(.)h(.)f(.)g(.)h(.)112 b(24)638 2401 y(thread)p +852 2401 V 28 w(switch)61 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) +g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(25)638 2500 y(thread)p 852 2500 V 28 w(schedule)48 +b(.)41 b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)g(.)h(.)f(.)g(.)h(.)112 b(26)638 2600 y(lthread)p +875 2600 V 28 w(e)o(x)p 981 2600 V 29 w(re)o(gs)72 b(.)41 +b(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)h(.)112 b(28)638 2700 y(task)p 777 2700 +V 30 w(ne)n(w)27 b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g +(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(30)447 2799 y(2.4)86 b(Processor)19 b(Mirroring)28 +b(.)42 b(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)h(.)112 b(32)638 2899 y(2.4.1)98 b(Se)o(gments)50 +b(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) +h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g +(.)g(.)h(.)f(.)g(.)h(.)112 b(32)638 2999 y(2.4.2)98 b(Exception)18 +b(Handling)79 b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g +(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) +f(.)g(.)h(.)112 b(32)638 3098 y(2.4.3)98 b(Deb)n(ug)19 +b(Re)o(gisters)74 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) +g(.)g(.)h(.)f(.)g(.)h(.)112 b(32)447 3198 y(2.5)86 b(The)20 +b(K)n(ernel-Info)d(P)o(age)43 b(.)e(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g +(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) +g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 b(33)447 +3297 y(2.6)86 b(P)o(age-F)o(ault)19 b(and)h(Preemption)e(RPC)59 +b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) +f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(34)447 3397 y(2.7)86 b Fy(\033)685 3409 y Fx(0)743 +3397 y FI(RPC)22 b(protocol)77 b(.)41 b(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h +(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)112 +b(35)447 3497 y(2.8)86 b(Starting)20 b(L4)75 b(.)42 b(.)f(.)g(.)g(.)h +(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) +g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f +(.)g(.)h(.)112 b(37)322 3679 y Fz(A)65 b(Booting)3114 +b(39)p eop +%%Page: 6 6 +6 5 bop 156 -290 a FI(6)3125 b FB(CONTENTS)p eop +%%Page: 7 7 +7 6 bop 322 566 a Fw(Chapter)45 b(1)322 981 y FA(L4)52 +b(in)g(General)1572 2243 y FI(Chapter)20 b(ommitted)f(in)h(this)h +(release.)2102 5620 y(7)p eop +%%Page: 8 8 +8 7 bop 156 -290 a FI(8)2442 b FB(CHAPTER)21 b(1.)46 +b(L4)20 b(IN)g(GENERAL)p eop +%%Page: 9 9 +9 8 bop 322 566 a Fw(Chapter)45 b(2)322 981 y FA(L4-X/x86)322 +1413 y FI(The)16 b(L4/x86)f(Nucleus)g(runs)h(on)g(x86-type)d +(processor')-5 b(s)16 b(that)g(of)n(fer)f(at)h(least)h(the)f +(functionality)e(of)i(an)g(Intel)g(486)f(processor)m(,)322 +1512 y(e.g.)20 b(486,)f(Pentium,)g(PentiumPro,)g(Pentium)h(II,)f(and)h +(Pentium)g(III.)322 4118 y FH(2.1)119 b(Notational)30 +b(con)-5 b(v)o(entions)1210 4534 y Fv(\030)296 b FI(If)34 +b(this)h(refers)g(to)g(an)f(input)g(parameter)m(,)j(its)f(v)n(alue)e +(is)1571 4633 y(meaningless.)52 b(If)29 b(it)h(refers)f(to)h(an)f +(output)g(parameter)m(,)1571 4733 y(its)21 b(v)n(alue)e(is)i +(unde\002ned.)1014 4916 y(EAX,ECX.)12 b(.)g(.)112 b(denote)19 +b(the)h(processor')-5 b(s)19 b(general)g(re)o(gisters.)1107 +5098 y Fv(h)p FI(SP)p Fu(+)p Fy(n)p Fv(i)193 b FI(denotes)27 +b(the)i(w)o(ord)e(on)h(the)h(user)f(stack)h(addressed)e(by)1571 +5198 y(SP)p Fu(+)p Fy(n)p FI(,)36 b(where)d(SP)h(represents)f(the)g +(user)n(-le)n(v)o(el)f(stack)1571 5297 y(pointer)-5 b(.)2102 +5620 y(9)p eop +%%Page: 10 10 +10 9 bop 156 -290 a FI(10)2663 b FB(CHAPTER)21 b(2.)46 +b(L4-X/X86)156 -57 y FH(2.2)119 b(Data)30 b(T)-9 b(ypes)156 +169 y Ft(2.2.1)99 b(Unique)26 b(Ids)156 349 y FI(Unique)c(ids)g +(identify)f(tasks,)j(threads)d(and)h(hardw)o(are)f(interrupts.)30 +b(Each)22 b(unique)e(id)j(is)g(a)g(32-bit)e(v)n(alue)g(which)h(is)h +(unique)156 449 y(in)e(time.)k(An)20 b(unique)f(id)h(in)g(x86)g(format) +f(consists)i(of)e(one)h(32-bit)f(w)o(ord:)331 682 y Fs(thr)m(ead)g(id)p +1095 574 532 4 v 1095 740 4 167 v 614 w FF(chief)1394 +696 y Fr(\(8\))p 1623 740 V 1095 743 532 4 v 1626 574 +V 1626 740 4 167 v 1788 682 a FF(task)1912 696 y Fr(\(8\))p +2154 740 V 1626 743 532 4 v 2157 574 399 4 v 2157 740 +4 167 v 2215 682 a FF(lthread)2416 696 y Fr(\(6\))p 2552 +740 V 2157 743 399 4 v 2556 574 665 4 v 2556 740 4 167 +v 2781 682 a FF(v)o(er)2882 696 y Fr(\(10\))p 3217 740 +V 2556 743 665 4 v 331 959 a Fs(task)h(id)p 1095 851 +532 4 v 1095 1017 4 167 v 694 w FF(chief)1394 973 y Fr(\(8\))p +1623 1017 V 1095 1020 532 4 v 1626 851 V 1626 1017 4 +167 v 1788 959 a FF(task)1912 973 y Fr(\(8\))p 2154 1017 +V 1626 1020 532 4 v 2157 851 399 4 v 2157 1017 4 167 +v 2290 959 a FF(0)2340 973 y Fr(\(6\))p 2552 1017 V 2157 +1020 399 4 v 2556 851 665 4 v 2556 1017 4 167 v 2781 +959 a FF(v)o(er)2882 973 y Fr(\(10\))p 3217 1017 V 2556 +1020 665 4 v 331 1235 a Fs(interrupt)g(id)p 1095 1127 +1595 4 v 1095 1293 4 167 v 1098 w FF(0)1860 1249 y Fr(\(24\))p +2685 1293 V 1095 1296 1595 4 v 2689 1127 532 4 v 2689 +1293 4 167 v 2807 1235 a FF(intr)d(+)h(1)3019 1249 y +Fr(\(8\))p 3217 1293 V 2689 1296 532 4 v 331 1512 a Fs(nil)i(id)p +1095 1404 2126 4 v 1095 1570 4 167 v 1572 w FF(0)2126 +1526 y Fr(\(32\))p 3217 1570 V 1095 1573 2126 4 v 331 +1788 a Fs(in)m(valid)f(id)p 1095 1680 V 1095 1846 4 167 +v 1301 w FF(FFFFFFFF)2257 1802 y Fr(\(32\))p 3217 1846 +V 1095 1849 2126 4 v 783 2074 2347 4 v 781 2174 4 100 +v 833 2144 a FI(a)n(v)n(ailable)h(tasks:)496 b(255)98 +b(1\226)o(255)140 b(task)20 b(0)h(does)e(not)h(e)o(xist)p +3128 2174 V 783 2177 2347 4 v 781 2277 4 100 v 833 2247 +a(a)n(v)n(ailable)g(threads)f(per)h(task:)182 b(64)99 +b(0\226)o(63)p 3128 2277 V 783 2280 2347 4 v 781 2379 +4 100 v 833 2350 a(usable)20 b(v)o(ersion)f(numbers:)152 +b(1024)98 b(0\226)o(1023)p 3128 2379 V 783 2383 2347 +4 v 156 2825 a Ft(2.2.2)h(Fpages)156 3005 y FI(Fpages)22 +b(\(Fle)o(xpages\))f(are)h(re)o(gions)f(of)h(the)g(virtual)f(address)h +(space.)31 b(An)22 b(fpage)f(consists)i(of)e(all)i(pages)f(actually)g +(mapped)156 3104 y(in)f(this)f(re)o(gion.)k(The)c(minimal)f(fpage)g +(size)i(is)g(4)g(K,)f(the)g(minimal)g(hardw)o(are-page)d(size.)281 +3217 y(An)i(fpage)f(of)h(size)h Fu(2)886 3187 y Fq(s)940 +3217 y FI(has)g(a)f Fu(2)1169 3187 y Fq(s)1204 3217 y +FI(-aligned)f(base)h(address)g Fy(b)p FI(,)g(i.e.)g Fy(b)k +Fu(mo)r(d)g(2)2412 3187 y Fq(s)2447 3209 y Fx(=)2498 +3217 y Fu(0)p FI(.)i(On)19 b(the)g(x86)f(processors,)g(the)h(smallest) +156 3316 y(possible)d(v)n(alue)g(for)g Fy(s)h FI(is)g(12,)g(since)f +(hardw)o(are)f(pages)h(are)g(at)h(least)g(4K.)f(The)h(complete)e(user)h +(address)g(space)g(\(base)g(address)156 3416 y(0,)26 +b(size)f Fu(2)441 3386 y Fx(32)532 3416 y Fv(\000)d Fy(K)6 +b FI(,)25 b(where)f Fy(K)30 b FI(is)c(the)e(size)h(of)f(the)h(k)o +(ernel)f(area\))g(is)h(denoted)e(by)h Fy(b)31 b Fu(=)f(0)p +Fy(;)14 b(s)30 b Fu(=)h(32)p FI(.)37 b(An)25 b(fpage)e(with)i(base)156 +3516 y(address)20 b Fy(b)h FI(and)e(size)i Fu(2)815 3485 +y Fq(s)871 3516 y FI(is)g(denoted)d(by)i(a)h(32-bit)e(w)o(ord:)331 +3749 y(fpage)g Fu(\()p Fy(b;)14 b Fu(2)683 3719 y Fq(s)718 +3749 y Fu(\))p 1095 3641 1329 4 v 1095 3807 4 167 v 841 +w Fp(b=)p Fo(4096)1814 3763 y Fr(\(20\))p 2420 3807 V +1095 3810 1329 4 v 2423 3641 266 4 v 2423 3807 4 167 +v 2490 3749 a FF(0)2539 3763 y Fr(\(4\))p 2685 3807 V +2423 3810 266 4 v 2689 3641 399 4 v 2689 3807 4 167 v +2822 3749 a Fp(s)2871 3763 y Fr(\(6\))p 3084 3807 V 2689 +3810 399 4 v 3087 3641 67 4 v 3087 3807 4 167 v 3093 +3749 a FE(\030)p 3150 3807 V 3087 3810 67 4 v 3153 3641 +V 3153 3807 4 167 v 11 w(\030)p 3217 3807 V 3153 3810 +67 4 v 331 4056 a FI(fpage)19 b Fu(\(0)p Fy(;)14 b Fu(2)689 +4026 y Fx(32)777 4056 y Fv(\000)k Fy(K)6 b Fu(\))p 1095 +3948 1329 4 v 1095 4114 4 167 v 708 w FF(0)1727 4070 +y Fr(\(20\))p 2420 4114 V 1095 4117 1329 4 v 2423 3948 +266 4 v 2423 4114 4 167 v 2490 4056 a FF(0)2539 4070 +y Fr(\(4\))p 2685 4114 V 2423 4117 266 4 v 2689 3948 +399 4 v 2689 4114 4 167 v 2805 4056 a FF(32)2888 4070 +y Fr(\(6\))p 3084 4114 V 2689 4117 399 4 v 3087 3948 +67 4 v 3087 4114 4 167 v 3093 4056 a FE(\030)p 3150 4114 +V 3087 4117 67 4 v 3153 3948 V 3153 4114 4 167 v 11 w(\030)p +3217 4114 V 3153 4117 67 4 v 156 4508 a Fz(IO-P)n(orts)156 +4688 y FI(x86)21 b(IO-ports)f(form)g(a)i(separate)f(address)g(space)g +(besides)g(the)h(con)m(v)o(entional)c(memory)h(address)i(space.)28 +b(Its)22 b(size)g(is)h(64)d(K)156 4787 y(and)j(its)i(granularity)c(is)k +(16)e(bytes.)34 b(Ho)n(we)n(v)o(er)m(,)22 b(IO-ports)h(can)g(only)g(be) +g(mapped)f(idempotently)-5 b(,)21 b(i.e.)35 b(physical)23 +b(port)g Fy(x)h FI(is)156 4887 y(either)c(mapped)f(at)h(the)h(address)e +Fy(x)j FI(in)e(the)g(task')-5 b(s)21 b(IO)f(address)g(space)g(or)g(it)h +(is)g(not)f(mapped.)281 4999 y(L4)j(handles)f(IO-ports)g(lik)o(e)h +(memory)-5 b(,)22 b(i.e.)33 b(as)24 b(fpages.)33 b(IO-fpages)21 +b(can)i(be)g(mapped,)f(granted)g(and)g(unmapped)f(lik)o(e)156 +5099 y(memory)c(fpages.)24 b(Ho)n(we)n(v)o(er)m(,)16 +b(since)j(IO-ports)e(can)i(only)e(mapped)g(idempotent,)g(al)o(w)o(ays)i +(the)g(complete)e(IO)i(space)f(\(64)g(K\))156 5198 y(should)i(be)g +(speci\002ed)g(as)h(recei)n(v)o(e)e(fpage.)281 5311 y(An)g(IO-fpage)f +(of)h(size)h Fu(2)1002 5281 y Fq(s)1057 5311 y FI(\()p +Fu(4)1141 5303 y Fn(\024)1206 5311 y Fy(s)1259 5303 y +Fn(\024)1325 5311 y Fu(16)p FI(\))e(has)i(a)g Fu(2)1685 +5281 y Fq(s)1720 5311 y FI(-aligned)e(base)h(address)g +Fy(p)p FI(,)h(i.e.)g Fy(p)i Fu(mo)r(d)i(2)2942 5281 y +Fq(s)2977 5303 y Fx(=)3028 5311 y Fu(0)p FI(.)g(An)c(fpage)e(with)i +(base)156 5410 y(port)g(address)g Fy(p)g FI(and)g(size)h +Fu(2)976 5380 y Fq(s)1031 5410 y FI(is)h(denoted)c(by)i(a)h(32-bit)e(w) +o(ord:)p eop +%%Page: 11 11 +11 10 bop 322 -290 a FB(2.2.)45 b(D)m(A)-9 b(T)h(A)21 +b(TYPES)2860 b FI(11)497 -28 y(IO-fpage)18 b Fu(\()p +Fy(p;)c Fu(2)970 -59 y Fq(s)1005 -28 y Fu(\))p 1261 -136 +532 4 v 1261 30 4 167 v 405 w FF(F0)1528 -14 y Fr(\(8\))p +1789 30 V 1261 33 532 4 v 1792 -136 798 4 v 1792 30 4 +167 v 2108 -28 a Fp(p)2160 -14 y Fr(\(12\))p 2586 30 +V 1792 33 798 4 v 2589 -136 266 4 v 2589 30 4 167 v 2656 +-28 a FF(0)2705 -14 y Fr(\(4\))p 2851 30 V 2589 33 266 +4 v 2855 -136 399 4 v 2855 30 4 167 v 2988 -28 a Fp(s)3037 +-14 y Fr(\(6\))p 3250 30 V 2855 33 399 4 v 3253 -136 +67 4 v 3253 30 4 167 v 3259 -28 a FE(\030)p 3316 30 V +3253 33 67 4 v 3320 -136 V 3320 30 4 167 v 12 w(\030)p +3383 30 V 3320 33 67 4 v 497 279 a FI(IO-fpage)k Fu(\(0)p +Fy(;)c Fu(2)970 249 y Fx(16)1040 279 y Fu(\))p 1261 171 +532 4 v 1261 337 4 167 v 370 w FF(F0)1528 293 y Fr(\(8\))p +1789 337 V 1261 340 532 4 v 1792 171 798 4 v 1792 337 +4 167 v 2109 279 a FF(0)2159 293 y Fr(\(12\))p 2586 337 +V 1792 340 798 4 v 2589 171 266 4 v 2589 337 4 167 v +2656 279 a FF(0)2705 293 y Fr(\(4\))p 2851 337 V 2589 +340 266 4 v 2855 171 399 4 v 2855 337 4 167 v 2971 279 +a FF(16)3054 293 y Fr(\(6\))p 3250 337 V 2855 340 399 +4 v 3253 171 67 4 v 3253 337 4 167 v 3259 279 a FE(\030)p +3316 337 V 3253 340 67 4 v 3320 171 V 3320 337 4 167 +v 12 w(\030)p 3383 337 V 3320 340 67 4 v 322 779 a Ft(2.2.3)99 +b(Messages)322 943 y Fz(Register)20 b(Messages/Buffers)322 +1107 y FI(Re)o(gister)j(messages)f(consist)g(of)g(up)g(to)g(3)g(w)o +(ords)g(of)f(32)h(bits.)31 b(Upon)21 b(sending,)h(the)g(message)g(is)h +(located)e(in)h(the)g(re)o(gisters)322 1206 y(EDX,)g(EBX,)g(and)f(EDI.) +h(Upon)e(recei)n(ving,)h(the)g(same)h(re)o(gisters)f(serv)o(e)h(as)g(a) +g(b)n(uf)n(fer)m(,)e(i.e.)i(the)g(re)o(gisters)f(EDX,)h(EBX,)g(and)322 +1306 y(EDI)f(contain)e(the)h(recei)n(v)o(ed)f(message)h(\(where)f(send) +h(EDX)g(is)h(recei)n(v)o(ed)e(EDX,)h(etc.\).)p 1302 1423 +2126 4 v 1302 1589 4 167 v 2191 1531 a FF(dw)o(ord)d(2)2426 +1545 y Fr(\(32\))p 3424 1589 V 1302 1592 2126 4 v 3559 +1531 a FI(EDI)p 1302 1596 V 1302 1762 4 167 v 2191 1704 +a FF(dw)o(ord)g(1)2426 1718 y Fr(\(32\))p 3424 1762 V +1302 1765 2126 4 v 3532 1704 a FI(EBX)p 1302 1768 V 1302 +1934 4 167 v 2191 1876 a FF(dw)o(ord)g(0)2426 1890 y +Fr(\(32\))p 3424 1934 V 1302 1937 2126 4 v 3527 1876 +a FI(EDX)322 2314 y Fz(Simple)22 b(Memory)e(Messages/Buffers)322 +2478 y FI(If)d(messages)f(are)g(longer)f(than)h(3)g(dw)o(ords,)g +(memory)f(messages)h(ha)n(v)o(e)g(to)g(be)g(used.)24 +b(Such)16 b(messages)g(consist)g(of)g(a)h(message)322 +2577 y(descriptor)23 b(\(dope\))g(that,)i(e.g.,)g(speci\002es)g(the)f +(current)f(message)h(length)g(in)g(dw)o(ords)g(\(msg)g(snd)g(dope\))f +(for)g(messages)i(to)322 2677 y(be)c(sent.)447 2781 y(A)32 +b(message)g(recei)n(v)o(e)e(b)n(uf)n(fer)g(is)j(structured)d(similarly) +i(b)n(ut)f(the)h(size)g(of)g(the)f(recei)n(v)o(e)g(b)n(uf)n(fer)m(,)h +(i.e.)g(the)g(maximum)322 2880 y(message)21 b(length)f(than)h(can)f(be) +h(recei)n(v)o(ed)f(in)h(this)g(b)n(uf)n(fer)m(,)e(is)j(speci\002ed)f +(by)f(the)h(msg)g(size)h(dope,)d(also)j(in)f(dw)o(ords.)26 +b(After)21 b(a)322 2980 y(message)h(w)o(as)h(recei)n(v)o(ed,)d(the)i +Fs(msg)g(snd)g(dope)f FI(contains)g(the)g(current)g(length)g(of)g(the)h +(recei)n(v)o(ed)e(message.)30 b Fs(msg)22 b(size)h(dope)322 +3080 y FI(is)f(unchanged.)2354 3168 y(.)2354 3202 y(.)2354 +3235 y(.)p 1302 3268 V 1302 3434 4 167 v 2191 3376 a +FF(dw)o(ord)17 b(3)2426 3390 y Fr(\(32\))p 3424 3434 +V 1302 3437 2126 4 v 3527 3376 a FI(+32)p 1302 3441 V +1302 3607 4 167 v 1924 3549 a FF(\(dw)o(ord)h(2)f(\227)g(not)g +(transferred\))2693 3563 y Fr(\(32\))p 3424 3607 V 1302 +3610 2126 4 v 3527 3549 a FI(+24)p 1302 3613 V 1302 3779 +4 167 v 1924 3721 a FF(\(dw)o(ord)h(1)f(\227)g(not)g(transferred\))2693 +3735 y Fr(\(32\))p 3424 3779 V 1302 3782 2126 4 v 3527 +3721 a FI(+16)372 3894 y(msg)j(dw)o(ords:)p 1302 3786 +V 1302 3952 4 167 v 1125 w FF(\(dw)o(ord)e(0)f(\227)g(not)g +(transferred\))2693 3908 y Fr(\(32\))p 3424 3952 V 1302 +3955 2126 4 v 3527 3894 a FI(+12)372 4067 y(msg)j(snd)g(dope:)p +1302 3959 1262 4 v 1302 4125 4 167 v 918 w FF(dw)o(ords)1982 +4081 y Fr(\(19\))p 2561 4125 V 1302 4128 1262 4 v 2564 +3959 333 4 v 2564 4125 4 167 v 2664 4067 a FF(0)2714 +4081 y Fr(\(5\))p 2893 4125 V 2564 4128 333 4 v 2896 +3959 532 4 v 2896 4125 4 167 v 3085 4067 a FE(\030)3156 +4081 y Fr(\(8\))p 3424 4125 V 2896 4128 532 4 v 3569 +4067 a FI(+8)372 4239 y(msg)g(size)h(dope:)p 1302 4131 +1262 4 v 1302 4297 4 167 v 904 w FF(dw)o(ords)1982 4253 +y Fr(\(19\))p 2561 4297 V 1302 4300 1262 4 v 2564 4131 +333 4 v 2564 4297 4 167 v 2664 4239 a FF(0)2714 4253 +y Fr(\(5\))p 2893 4297 V 2564 4300 333 4 v 2896 4131 +532 4 v 2896 4297 4 167 v 3085 4239 a FE(\030)3156 4253 +y Fr(\(8\))p 3424 4297 V 2896 4300 532 4 v 3569 4239 +a FI(+4)372 4412 y(msg)f(rcv)g(fpage)f(option:)p 1302 +4304 2126 4 v 1302 4470 4 167 v 1126 w FF(fpage)2390 +4426 y Fr(\(32\))p 3424 4470 V 1302 4473 2126 4 v 3615 +4412 a FI(0)322 4709 y(Using)f(dif)n(ferent)f(send)h(and)f(size)i +(dopes)e(permits)h(to)g(specify)g(not)g(only)f(pure)g(send)h(messages)g +(and)g(pure)f(recei)n(v)o(e)g(message)322 4808 y(b)n(uf)n(fers.)25 +b(It)20 b(is)h(as)g(well)g(possibe)f(to)h(send)f(a)g(message)h(and)e +(recei)n(v)o(e)h(the)g(reply)f(using)h(the)g(same)h(data)f(structure.)k +(And,)c(you)322 4908 y(can)i(also)g(recei)n(v)o(e)e(a)i(message)f(in)h +(a)g(message)f(b)n(uf)n(fer)g(and)g(then)g(forrw)o(ard)e(this)j(b)n(uf) +n(fer)f(as)h(a)g(message)f(without)g(changing)322 5008 +y(the)g(data)f(structure.)447 5111 y(A)g(further)e(simpli\002cation)g +(for)h(user)n(-le)n(v)o(el)f(programming)e(is)21 b(that)e +Fs(the)h(\002r)o(st)g(thr)m(ee)f(dwor)m(ds)h(of)f(a)h(messa)o(g)o(e)f +(ar)m(e)h(always)322 5211 y(tr)o(ansferr)m(ed)i(via)f(r)m(e)m(gister)-9 +b(.)30 b FI(This)22 b(permits)f(to)g(handle)g(long)g(\(memory\))e(and)i +(short)g(\(re)o(gister\))f(messages)i(basically)f(in)h(the)322 +5311 y(same)d(w)o(ay)f(\(the)g(\002rst)h(three)f(dw)o(ords)f(are)h(al)o +(w)o(ays)h(in)f(re)o(gisters\).)23 b(Note)c(that)f(loading/storing)d +(those)j(re)o(gisters)g(from/to)f(the)322 5410 y(message/b)n(uf)n(fer)i +(data)h(structure)f(is)i Fs(not)f FI(handled)f(by)g(the)i(Nucleus.)j +(It)d(can)f(be)g(done)f(at)i(user)f(le)n(v)o(el.)p eop +%%Page: 12 12 +12 11 bop 156 -290 a FI(12)2663 b FB(CHAPTER)21 b(2.)46 +b(L4-X/X86)156 -57 y Fz(Memory)20 b(Messages/Buffers)h(W)o(ith)f(Indir) +o(ect)g(P)o(arts)156 129 y FI(Comple)o(x)j(messages)h(or)g(b)n(uf)n +(fers)f(can)g(contain)g(up)h(to)g(31)f(indirect)g(parts.)36 +b(The)24 b(number)e(of)i(those)f(parts)h(is)h(speci\002ed)f(in)156 +228 y(the)h Fs(parts)g FI(\002elds.)38 b(F)o(or)24 b(b)n(uf)n(fers,)h +(the)f Fs(msg)h(size)h(dope)d FI(de\002nes)h(the)h(maximum)e(number)g +(of)h(accepted)f(indirect)h(parts)h(for)156 328 y(recei)n(ving.)h(F)o +(or)20 b(messages,)h Fs(msg)g(snd)g(dope)f FI(de\002nes)h(the)g +(current)e(indirect)h(parts)h(for)f(sending,)g(and)g(the)h +Fs(dwor)m(ds)g FI(\002eld)g(of)156 427 y Fs(msg)f(size)g(dope)d +FI(de\002nes)i(the)g(position)f Fy(X)26 b FI(where)18 +b(the)h(\002rst)h(indirect)e(part)g(is)i(located.)k Fs(Ther)m(efor)m(e) +o(,)19 b(the)g(dwor)m(ds)f(\002eld)h(of)g(the)156 527 +y(msg)i(size)g(dope)e(must)i(be)f(set)h(corr)m(ectly)-5 +b(,)21 b(e)o(ven)e(if)i(it)g(is)g(a)f(pur)m(e)g(send)g(messa)o(g)o(e)o +(.)2188 709 y FI(.)2188 742 y(.)2188 776 y(.)1152 b(+)p +Fy(X)7 b FI(+16)206 1033 y(part0)20 b(dope:)p 1136 809 +2126 4 v 1136 1091 4 283 v 2111 1047 a Fr(\(4)p Fm(\002)p +Fr(32\))p 3258 1091 V 1136 1094 2126 4 v 3403 1033 a +FI(+)p Fy(X)7 b FI(+0)2409 1183 y Fl(X)16 b(=)h(\(msg)g(size)g(dope)o +(.parts+3\))p FE(\002)p Fo(4)2188 1171 y FI(.)2188 1204 +y(.)2188 1237 y(.)2188 1325 y(.)2188 1359 y(.)2188 1392 +y(.)p 1136 1425 V 1136 1591 4 167 v 2002 1533 a FF(\(dw)o(ord)h(1\)) +2282 1547 y Fr(\(32\))p 3258 1591 V 1136 1594 2126 4 +v 3483 1533 a FI(+16)206 1706 y(msg)i(dw)o(ords:)p 1136 +1598 V 1136 1764 4 167 v 1369 w FF(\(dw)o(ord)e(0\))2282 +1720 y Fr(\(32\))p 3258 1764 V 1136 1767 2126 4 v 3483 +1706 a FI(+12)206 1878 y(msg)i(snd)g(dope:)p 1136 1770 +1262 4 v 1136 1937 4 167 v 918 w FF(dw)o(ords)1816 1892 +y Fr(\(19\))p 2395 1937 V 1136 1940 1262 4 v 2398 1770 +333 4 v 2398 1937 4 167 v 2450 1878 a FF(parts)2596 1892 +y Fr(\(5\))p 2727 1937 V 2398 1940 333 4 v 2730 1770 +532 4 v 2730 1937 4 167 v 2919 1878 a FE(\030)2990 1892 +y Fr(\(8\))p 3258 1937 V 2730 1940 532 4 v 3525 1878 +a FI(+8)206 2051 y(msg)g(size)h(dope:)p 1136 1943 1262 +4 v 1136 2109 4 167 v 904 w FF(dw)o(ords)1816 2065 y +Fr(\(19\))p 2395 2109 V 1136 2112 1262 4 v 2398 1943 +333 4 v 2398 2109 4 167 v 2450 2051 a FF(parts)2596 2065 +y Fr(\(5\))p 2727 2109 V 2398 2112 333 4 v 2730 1943 +532 4 v 2730 2109 4 167 v 2919 2051 a FE(\030)2990 2065 +y Fr(\(8\))p 3258 2109 V 2730 2112 532 4 v 3525 2051 +a FI(+4)206 2224 y(msg)f(rcv)g(fpage)f(option:)p 1136 +2116 2126 4 v 1136 2282 4 167 v 1126 w FF(fpage)2224 +2238 y Fr(\(32\))p 3258 2282 V 1136 2285 2126 4 v 3572 +2224 a FI(0)156 2465 y(Ev)o(ery)g(indirect)h(part)g(dope)f(can)h +(specify)g(an)g(indirect)g(send)g(part)g(and)g(an)g(indirect)g(recei)n +(v)o(e)f(b)n(uf)n(fer)-5 b(.)24 b(F)o(or)c(a)h(send)f(message,)156 +2565 y(the)28 b(recei)n(v)o(e)f(b)n(uf)n(fer)g(part)h(is)h(ignored.)46 +b(F)o(or)28 b(a)g(recei)n(v)o(e)f(b)n(uf)n(fer)m(,)h(the)g(recei)n(v)o +(e)f(b)n(uf)n(fer)g(speci\002es)h(the)g(b)n(uf)n(fer)f(address)h(and) +156 2665 y(maximum)23 b(length;)j(after)e(a)h(message)f(w)o(as)h(recei) +n(v)o(ed,)f(the)g(send)g(part)g(address)g(is)i(set)f(to)f(the)h(be)o +(ginning)d(of)i(the)g(recei)n(v)o(e)156 2764 y(b)n(uf)n(fer)30 +b(and)g(the)h(send)f(part)g(length)g(speci\002es)h(the)g(current)f +(length.)55 b(Thus,)33 b(recei)n(v)o(ed)c(parts)i(can)f(be)h(forw)o +(arded)d(by)j(a)156 2864 y(successi)n(v)o(e)20 b(send)g(operation)f +(without)g(an)o(y)g(change.)p 1136 3009 V 1136 3175 4 +167 v 2015 3117 a FF(*rcv)f(part)2269 3131 y Fr(\(32\))p +3258 3175 V 1136 3178 2126 4 v 3361 3117 a FI(+12)p 1136 +3181 67 4 v 1136 3347 4 167 v 1155 3289 a FF(c)p 1199 +3347 V 1136 3350 67 4 v 1202 3181 2059 4 v 1202 3347 +4 167 v 821 w(rcv)f(part)h(size)2346 3303 y Fr(\(31\))p +3258 3347 V 1202 3350 2059 4 v 3403 3289 a FI(+8)p 1136 +3354 2126 4 v 1136 3520 4 167 v 2011 3462 a FF(*snd)f(part)2273 +3476 y Fr(\(32\))p 3258 3520 V 1136 3523 2126 4 v 3403 +3462 a FI(+4)206 3635 y(part)j(dope:)p 1136 3527 67 4 +v 1136 3693 4 167 v 613 w FF(c)p 1199 3693 V 1136 3696 +67 4 v 1202 3527 2059 4 v 1202 3693 4 167 v 817 w(snd)d(part)h(size) +2350 3649 y Fr(\(31\))p 3258 3693 V 1202 3696 2059 4 +v 3449 3635 a FI(0)156 3876 y(The)24 b Fy(c)h FI(bits)g(enable)e +Fs(scatter/gather)h FI(functionality)-5 b(.)34 b Fy(c)c +Fu(=)g(0)25 b FI(speci\002es)f(the)h(be)o(gin)e(of)g(a)i(logical)f +(string;)i Fy(c)k Fu(=)g(1)24 b FI(speci\002es)156 3976 +y(that)19 b(this)g(is)g(a)g(continuation)d(of)i(the)h(last)g(logical)f +(string.)24 b(On)19 b(the)f(sender)g(side,)h Fs(lo)o(gical)e(string)i +FI(means)f(a)h(sequence)e(of)i(one)156 4076 y(or)i(more)e(parts)h(that) +h(are)f(transferred)f(as)i(if)g(the)o(y)e(were)i(one)e(contiguous)g +(string)h(\(gather\).)j(On)e(the)f(recei)n(v)o(er)f(side,)i +Fs(lo)o(gical)156 4175 y(string)31 b FI(means)f(a)g(sequence)f(of)h +(one)g(or)g(more)f(b)n(uf)n(fers)g(that)h(are)h(treated)e(as)i(one)f +(logical)f(b)n(uf)n(fer;)34 b(the)c(corresponding)156 +4275 y(recei)n(v)o(ed)24 b(string)g(is)h(scattered)g(among)e(them.)38 +b(Continuations)23 b(can)i(be)f(arbitrarily)f(combined)g(on)h(sender)g +(and)g(recei)n(v)o(er)156 4374 y(side.)i(Note)20 b(that)g(length)f(and) +h(size)h(\002elds)g(are)f(al)o(w)o(ays)g(per)g(part.)156 +4681 y Fz(Map)h(Messages/Buffers)156 4866 y FI(Map)j(messages)h(are)f +(dif)n(ferentiated)d(from)j(cop)o(y)f(messages)h(in)g(the)h +Fs(ipc)f FI(system)g(call.)37 b(The)24 b(format)f(of)h(a)g(map)g +(message)156 4966 y(is)f(lik)o(e)e(a)h(re)o(gister)f(message)g(or)h +(memory)d(message)j(where)e(the)i(direct)f(message)g(part)g(\(not)g +(the)h(optional)e(indirect)g(parts\))156 5065 y(consists)h(of)f +Fs(snd)g(fpa)o(g)o(es)p FI(:)p 1136 5110 1993 4 v 1136 +5276 4 167 v 1939 5218 a FF(snd)d(fpage)2212 5232 y Fr(\(30\))p +3125 5276 V 1136 5279 1993 4 v 3129 5110 67 4 v 3129 +5276 4 167 v 3137 5218 a Fp(w)p 3192 5276 V 3129 5279 +67 4 v 3195 5110 V 3195 5276 4 167 v 22 w(g)p 3258 5276 +V 3195 5279 67 4 v 117 w FI(+4)206 5390 y(snd)j(fpage:)p +1136 5282 2126 4 v 1136 5449 4 167 v 1469 w FF(snd)d(base)2264 +5404 y Fr(\(32\))p 3258 5449 V 1136 5452 2126 4 v 3408 +5390 a FI(0)p eop +%%Page: 13 13 +13 12 bop 322 -290 a FB(2.2.)45 b(D)m(A)-9 b(T)h(A)21 +b(TYPES)2860 b FI(13)945 -161 y Fy(w)1006 -169 y Fx(=)1058 +-161 y Fu(0)194 b FI(The)20 b(fpage)f(will)i(be)f(mapped/granted)d +(read)i(only)-5 b(.)945 -62 y Fy(w)1006 -70 y Fx(=)1058 +-62 y Fu(1)194 b FI(The)41 b(fpage)g(will)h(be)g(mapped/granted)c(with) +k(the)f(full)h(access)g(right)f(the)h(mapper)1294 38 +y(possesses.)945 204 y Fy(g)988 196 y Fx(=)1039 204 y +Fu(0)213 b FI(The)20 b(fpage)f(will)i(be)f(mapped.)945 +304 y Fy(g)988 296 y Fx(=)1039 304 y Fu(1)213 b FI(The)20 +b(fpage)f(will)i(be)f(granted.)322 646 y Ft(2.2.4)99 +b(T)n(imeouts)322 827 y FI(T)m(imeouts)22 b(are)g(used)g(to)g(control)f +(ipc)h(operations.)29 b(The)21 b Fs(send)h(timeout)g +FI(determines)f(ho)n(w)g(long)h(ipc)g(should)f(try)h(to)g(send)g(a)322 +927 y(message.)27 b(If)21 b(the)g(speci\002ed)g(period)e(is)j(e)o +(xhausted)d(without)h(that)h(message)g(transfer)f(could)g(start,)i(ipc) +e(f)o(ails.)28 b(The)21 b Fs(r)m(eceive)322 1027 y(timeout)27 +b FI(speci\002es)h(ho)n(w)e(long)g(ipc)h(should)f(w)o(ait)i(for)e(an)h +(incoming)e(message.)46 b(Both)27 b(timouts)f(specify)h(the)g(maximum) +322 1126 y(period)19 b(of)h(time)g Fs(befor)m(e)f(messa)o(g)o(e)h(tr)o +(ansfer)g(starts)p FI(.)26 b(Once)20 b(started,)f(message)h(transfer)f +(is)i(no)e(longer)g(in\003uenced)f(by)h(send)322 1226 +y(or)h(recei)n(v)o(e)f(timeout.)447 1339 y(P)o(agef)o(aults)32 +b(occuring)e(during)g(ipc)j(are)f(controlled)e(by)i Fs(send)g +FI(and)g Fs(r)m(eceive)g(pa)o(g)o(efault)f(timeout)p +FI(.)60 b(A)33 b(pagef)o(ault)e(is)322 1438 y(translated)16 +b(to)g(an)g(RPC)h(by)f(the)f(k)o(ernel.)23 b(In)16 b(the)g(case)g(of)g +(a)g(pagef)o(ault)f(in)h(the)g(recei)n(v)o(er')-5 b(s)15 +b(address)g(space,)i(the)e(corresponding)322 1538 y(RPC)23 +b(to)d(the)h(pager)f(uses)h Fs(send)f(pa)o(g)o(efault)g(timeout)g +FI(\(speci\002ed)g(by)g(the)h(sender\))f(for)g(both)f(send)i(and)f +(recei)n(v)o(e)g(timeout.)25 b(In)322 1638 y(the)h(case)h(of)f(a)g +(pagef)o(ault)f(in)h(the)g(sender')-5 b(s)25 b(address)h(space,)h +Fs(r)m(eceive)f(pa)o(g)o(efault)f(timeout)g FI(speci\002ed)h(by)g(the)g +(recei)n(v)o(er)e(is)322 1737 y(tak)o(en.)447 1850 y(Besides)d(the)f +(special)g(timeouts)g(0)g(\(do)f(not)h(w)o(ait)h(at)f(all\))g(and)g +Fv(1)g FI(\(w)o(ait)h(fore)n(v)o(er\),)c(periods)i(from)g(1)h +Fy(\026)p FI(s)h(up)f(to)g(approxi-)322 1950 y(mately)g(19)g(hours)f +(can)h(be)g(speci\002ed.)25 b(The)20 b(complete)f(quadruple)f(is)j +(pack)o(ed)e(into)h(one)f(32-bit)g(w)o(ord:)p 1060 2253 +532 4 v 1060 2419 4 167 v 1227 2361 a Fp(m)1289 2369 +y Fk(r)1341 2375 y Fr(\(8\))p 1588 2419 V 1060 2422 532 +4 v 1591 2253 V 1591 2419 4 167 v 1759 2361 a Fp(m)1821 +2369 y Fk(s)1872 2375 y Fr(\(8\))p 2119 2419 V 1591 2422 +532 4 v 2122 2253 266 4 v 2122 2419 4 167 v 2171 2361 +a Fp(p)2207 2369 y Fk(s)2257 2375 y Fr(\(4\))p 2385 2419 +V 2122 2422 266 4 v 2388 2253 V 2388 2419 4 167 v 2436 +2361 a Fp(p)2472 2369 y Fk(r)2523 2375 y Fr(\(4\))p 2650 +2419 V 2388 2422 266 4 v 2654 2253 V 2654 2419 4 167 +v 2704 2361 a Fp(e)2737 2369 y Fk(s)2787 2375 y Fr(\(4\))p +2916 2419 V 2654 2422 266 4 v 2919 2253 V 2919 2419 4 +167 v 2969 2361 a Fp(e)3002 2369 y Fk(r)3053 2375 y Fr(\(4\))p +3182 2419 V 2919 2422 266 4 v 447 2748 a FI(Note)h(that)g(for)g(ef)n +(\002cienc)o(y)f(reasons)g(the)i(highest)e(bit)i(of)f(an)o(y)f +(mantissa)h Fy(m)h Fs(must)g FI(be)f(1,)g(e)o(xcept)f(for)g +Fy(m)3418 2740 y Fx(=)3469 2748 y Fu(0)p FI(.)1390 3279 +y FF(snd)e(timeout)85 b Fo(=)1923 3063 y Fj(8)1923 3138 +y(>)1923 3163 y(>)1923 3188 y(<)1923 3337 y(>)1923 3362 +y(>)1923 3387 y(:)2038 3116 y FE(1)476 b FF(if)67 b Fp(e)2725 +3124 y Fk(s)2758 3108 y Fr(=)2804 3116 y Fo(0)2038 3279 +y(4)2073 3255 y Fr(15)p Fm(\000)p Fk(e)2210 3263 y Fi(s)2248 +3279 y Fp(m)2310 3287 y Fk(s)2360 3279 y Fp(\026s)150 +b FF(if)67 b Fp(e)2725 3287 y Fk(s)2758 3271 y(>)2806 +3279 y Fo(0)2038 3440 y(0)512 b FF(if)67 b Fp(m)2754 +3448 y Fk(s)2788 3432 y Fr(=)2834 3440 y Fo(0)p Fp(;)12 +b(e)2934 3448 y Fk(s)2967 3432 y Fm(6)p Fr(=)3013 3440 +y Fo(0)1398 3857 y FF(rcv)17 b(timeout)85 b Fo(=)1923 +3641 y Fj(8)1923 3715 y(>)1923 3740 y(>)1923 3765 y(<)1923 +3915 y(>)1923 3940 y(>)1923 3965 y(:)2038 3694 y FE(1)479 +b FF(if)67 b Fp(e)2728 3702 y Fk(r)2762 3686 y Fr(=)2809 +3694 y Fo(0)2038 3856 y(4)2073 3833 y Fr(15)p Fm(\000)p +Fk(e)2210 3841 y Fi(r)2250 3856 y Fp(m)2312 3864 y Fk(r)2363 +3856 y Fp(\026s)150 b FF(if)67 b Fp(e)2728 3864 y Fk(r)2762 +3848 y(>)2810 3856 y Fo(0)2038 4018 y(0)515 b FF(if)67 +b Fp(m)2757 4026 y Fk(r)2792 4010 y Fr(=)2838 4018 y +Fo(0)p Fp(;)12 b(e)2938 4026 y Fk(r)2972 4010 y Fm(6)p +Fr(=)3019 4018 y Fo(0)1127 4434 y FF(snd)17 b(pagef)o(ault)j(timeout)85 +b Fo(=)1923 4218 y Fj(8)1923 4293 y(>)1923 4318 y(>)1923 +4343 y(<)1923 4492 y(>)1923 4517 y(>)1923 4542 y(:)2038 +4271 y FE(1)449 b FF(if)67 b Fp(p)2701 4279 y Fk(s)2734 +4263 y Fr(=)2781 4271 y Fo(0)2038 4433 y(4)2073 4410 +y Fr(15)p Fm(\000)p Fk(p)2213 4418 y Fi(s)2251 4433 y +Fp(\026s)232 b FF(if)67 b Fo(0)2700 4425 y Fk(<)2749 +4433 y Fp(p)2785 4441 y Fk(s)2817 4425 y(<)2865 4433 +y Fo(15)2038 4595 y(0)485 b FF(if)67 b Fp(p)2701 4603 +y Fk(s)2734 4587 y Fr(=)2781 4595 y Fo(15)1135 5011 y +FF(rcv)17 b(pagef)o(ault)j(timeout)85 b Fo(=)1923 4795 +y Fj(8)1923 4870 y(>)1923 4895 y(>)1923 4920 y(<)1923 +5069 y(>)1923 5094 y(>)1923 5119 y(:)2038 4848 y FE(1)434 +b FF(if)67 b Fp(p)2686 4856 y Fk(r)2720 4840 y Fr(=)2767 +4848 y Fo(0)2038 5011 y(4)2073 4987 y Fr(16)p Fm(\000)p +Fk(p)2213 4995 y Fi(r)2252 5011 y Fp(\026s)216 b FF(if)67 +b Fo(0)2685 5003 y Fk(<)2733 5011 y Fp(p)2769 5019 y +Fk(r)2804 5003 y(<)2852 5011 y Fo(15)2038 5173 y(0)470 +b FF(if)67 b Fp(p)2686 5181 y Fk(r)2720 5165 y Fr(=)2767 +5173 y Fo(15)p eop +%%Page: 14 14 +14 13 bop 156 -290 a FI(14)2663 b FB(CHAPTER)21 b(2.)46 +b(L4-X/X86)p 1235 -136 1443 4 v 1233 -57 4 79 v 2676 +-57 V 1233 55 4 162 v 1586 -52 a FF(approximate)19 b(timeout)g(ranges)p +2676 55 V 1235 58 1443 4 v 1233 223 4 165 v 1285 158 +a Fp(e)1318 166 y Fk(s)1351 158 y Fp(;)11 b(e)1415 166 +y Fk(r)1450 158 y Fp(;)g(p)1517 166 y Fk(s)1550 158 y +Fp(;)g(p)1617 166 y Fk(r)p 1700 223 V 1700 223 V 1785 +158 a FF(snd/rcv)19 b(timeout)p 2283 223 V 2283 223 V +145 w(pf)e(timeout)p 2676 223 V 1235 226 1443 4 v 1233 +391 4 165 v 1452 326 a(0)p 1700 391 V 1700 391 V 473 +w FE(1)p 2283 391 V 2283 391 V 417 w(1)p 2676 391 V 1233 +470 4 79 v 1452 446 a FF(1)p 1700 470 V 266 w(256)g(s)68 +b(.)10 b(.)g(.)42 b(19)17 b(h)p 2283 470 V 244 w(256)g(s)p +2676 470 V 1233 549 V 1452 525 a(2)p 1700 549 V 299 w(64)g(s)68 +b(.)10 b(.)g(.)42 b(55)17 b(h)p 2283 549 V 277 w(64)g(s)p +2676 549 V 1233 627 V 1452 604 a(3)p 1700 627 V 299 w(16)g(s)68 +b(.)10 b(.)g(.)42 b(71)17 b(m)p 2283 627 V 258 w(16)g(s)p +2676 627 V 1233 706 V 1452 683 a(4)p 1700 706 V 332 w(4)g(s)68 +b(.)10 b(.)g(.)42 b(17)17 b(m)p 2283 706 V 291 w(4)g(s)p +2676 706 V 1233 785 V 1452 762 a(5)p 1700 785 V 332 w(1)g(s)68 +b(.)10 b(.)g(.)76 b(4)16 b(m)p 2283 785 V 291 w(1)h(s)p +2676 785 V 1233 864 V 1452 840 a(6)p 1700 864 V 266 w(262)g(ms)f(.)10 +b(.)g(.)42 b(67)17 b(s)p 2283 864 V 251 w(256)g(ms)p +2676 864 V 1233 943 V 1452 919 a(7)p 1700 943 V 299 w(65)g(ms)f(.)10 +b(.)g(.)42 b(17)17 b(s)p 2283 943 V 284 w(64)g(ms)p 2676 +943 V 1233 1022 V 1452 998 a(8)p 1700 1022 V 299 w(16)g(ms)f(.)10 +b(.)g(.)76 b(4)16 b(s)p 2283 1022 V 284 w(16)h(ms)p 2676 +1022 V 1233 1101 V 1452 1077 a(9)p 1700 1101 V 332 w(4)g(ms)f(.)10 +b(.)g(.)76 b(1)16 b(s)p 2283 1101 V 317 w(4)h(ms)p 2676 +1101 V 1233 1180 V 1435 1156 a(10)p 1700 1180 V 316 w(1)g(ms)f(.)10 +b(.)g(.)f(261)17 b(ms)p 2283 1180 V 265 w(1)g(ms)p 2676 +1180 V 1233 1258 V 1435 1235 a(11)p 1700 1258 V 250 w(256)g +Fp(\026)p FF(s)26 b(.)10 b(.)g(.)42 b(65)17 b(ms)p 2283 +1258 V 199 w(256)g Fp(\026)p FF(s)p 2676 1258 V 1233 +1337 V 1435 1314 a(12)p 1700 1337 V 283 w(64)g Fp(\026)p +FF(s)26 b(.)10 b(.)g(.)42 b(16)17 b(ms)p 2283 1337 V +232 w(64)g Fp(\026)p FF(s)p 2676 1337 V 1233 1416 V 1435 +1393 a(13)p 1700 1416 V 283 w(16)g Fp(\026)p FF(s)26 +b(.)10 b(.)g(.)76 b(4)16 b(ms)p 2283 1416 V 232 w(16)h +Fp(\026)p FF(s)p 2676 1416 V 1233 1495 V 1435 1471 a(14)p +1700 1495 V 316 w(4)g Fp(\026)p FF(s)26 b(.)10 b(.)g(.)76 +b(1)16 b(ms)p 2283 1495 V 265 w(4)h Fp(\026)p FF(s)p +2676 1495 V 1233 1615 4 121 v 1435 1550 a(15)p 1700 1615 +V 316 w(1)g Fp(\026)p FF(s)26 b(.)10 b(.)g(.)f(255)17 +b Fp(\026)p FF(s)p 2283 1615 V 275 w(0)p 2676 1615 V +1233 1736 V 1322 1671 a Fp(m)1384 1663 y Fr(=)1431 1671 +y Fo(0)p Fp(;)12 b(e)1531 1663 y Fk(>)1579 1671 y Fo(0)p +1700 1736 V 1700 1736 V 362 w FF(0)p 2283 1736 V 458 +w(\227)p 2676 1736 V 1235 1739 1443 4 v eop +%%Page: 15 15 +15 14 bop 322 -290 a FB(2.3.)45 b(L4)20 b(CALLS)2970 +b FI(15)322 -57 y FH(2.3)119 b(L4)30 b(Calls)322 129 +y FI(This)21 b(section)f(describes)f(the)i(7)f(system)g(calls)h(of)f +(L4:)1417 295 y Fv(\017)41 b FI(ipc)1159 b(int)21 b(30)1417 +461 y Fv(\017)41 b FI(id)p 1570 461 25 4 v 29 w(nearest)931 +b(int)21 b(31)1417 627 y Fv(\017)41 b FI(fpage)p 1691 +627 V 28 w(unmap)819 b(int)21 b(32)1417 793 y Fv(\017)41 +b FI(thread)p 1714 793 V 28 w(switch)807 b(int)21 b(33)1417 +959 y Fv(\017)41 b FI(thread)p 1714 959 V 28 w(schedule)732 +b(int)21 b(34)1417 1125 y Fv(\017)41 b FI(lthread)p 1737 +1125 V 28 w(e)o(x)p 1843 1125 V 29 w(re)o(gs)756 b(int)21 +b(35)1417 1291 y Fv(\017)41 b FI(task)p 1639 1291 V 29 +w(ne)n(w)961 b(int)21 b(36)p eop +%%Page: 16 16 +16 15 bop 156 -290 a FI(16)3387 b FB(IPC)156 338 y Fh(ipc)p +1765 376 4 100 v 2423 376 V 1765 475 V 2423 475 V 1765 +575 V 2423 575 V 1765 675 V 1816 645 a Fg(\000)21 b FI(INT)f(0x30)p +Fg(!)p 2423 675 V 1003 346 a Fs(snd)g(descriptor)99 b +FF(EAX)p 1765 376 V 2423 376 V 757 w(EAX)g Fs(msg)o(.dope)19 +b(+)i Fy(cc)41 b FD(/)62 b Fy(cc)1199 446 y Fs(timeouts)99 +b FF(ECX)p 1765 475 V 2423 475 V 761 w(ECX)k Fv(\030)461 +b FD(/)62 b Fv(\030)1230 545 y Fs(msg)o(.w0)99 b FF(EDX)p +1765 575 V 2423 575 V 757 w(EDX)g Fs(msg)o(.w0)275 b +FD(/)62 b Fv(\030)1230 645 y Fs(msg)o(.w1)99 b FF(EBX)p +1765 675 V 2423 675 V 761 w(EBX)k Fs(msg)o(.w1)275 b +FD(/)62 b Fv(\030)1015 744 y Fs(r)m(cv)21 b(descriptor)99 +b FF(EBP)p 1765 774 V 2423 774 V 772 w(EBP)114 b Fv(\030)461 +b FD(/)62 b Fv(\030)1347 844 y Fs(dest)99 b FF(ESI)p +1765 874 V 2423 874 V 794 w(ESI)136 b Fs(sour)m(ce)307 +b FD(/)62 b Fv(\030)1230 944 y Fs(msg)o(.w2)99 b FF(EDI)p +1765 974 V 2423 974 V 783 w(EDI)125 b Fs(msg)o(.w2)275 +b FD(/)62 b Fv(\030)943 1077 y Fs(pr)l(opa)o(gatee)39 +b Ff(/)j Fv(\030)99 b FE(h)p FF(SP)p FE(i)156 1384 y +FI(This)22 b(is)h(the)e(basic)h(system)g(call)g(for)f(inter)n(-process) +f(communication)f(and)i(synchronization.)26 b(It)c(may)f(be)g(used)h +(for)f(intra-)156 1483 y(as)31 b(inter)n(-address-space)d +(communication.)53 b(All)31 b(communication)c(is)k(synchronous)d(and)i +(unb)n(uf)n(fered:)42 b(a)31 b(message)f(is)156 1583 +y(transferred)h(from)g(the)h(sender)g(to)g(the)g(recipient)g(if)g(and)g +(only)f(if)i(the)f(recipient)g(has)g(in)m(v)n(ok)o(ed)e(a)j +(corresponding)c(ipc)156 1683 y(operation.)d(The)21 b(sender)f(blocks)g +(until)h(this)h(happens)e(or)g(a)i(period)e(speci\002ed)g(by)h(the)g +(sender)f(elapsed)h(whithout)f(that)h(the)156 1782 y(destination)f +(became)f(ready)g(to)h(recei)n(v)o(e.)281 1928 y(Ipc)j(can)g(be)g(used) +g(to)g(cop)o(y)g(data)g(as)h(well)f(as)h(to)g Fs(map)f +FI(or)g Fs(gr)o(ant)f FI(fpages)g(from)h(the)g(sender)f(to)i(the)f +(recipient.)33 b(F)o(or)23 b(the)156 2028 y(description)c(of)h +(messages)g(see)h(section)f(2.2.3.)281 2174 y(12-byte)f(messages)i +(\(plus)g(32-bit)f(sender)g(id\))h(can)g(be)g(transferred)e(solely)i +(via)g(the)g(re)o(gisters)g(and)f(are)h(thus)g(specially)156 +2273 y(optimized.)j(If)c(possible,)g(short)f(messages)i(should)e +(therefore)f(be)i(reduced)f(to)h(12-byte)f(messages.)156 +2502 y(A)g(single)f(ipc)h(call)g(combines)e(an)h(optional)f(send)h +(operation)e(with)j(an)f(optional)f(recei)n(v)o(e)g(operation.)23 +b(Whether)18 b(it)h(includes)156 2602 y(a)f(send)f(respecti)n(v)o(ely)f +(a)i(recei)n(v)o(e)e(is)i(determined)e(by)h(the)g(actual)g(parameters.) +23 b(If)17 b(the)h(send)f(or)g(recei)n(v)o(e)f(address)h(is)h +(speci\002ed)156 2701 y(as)j Fy(nil)h FI(\(0xFFFFFFFF\),)e(the)g +(corresponding)d(operation)h(is)j(skipped.)281 2847 y(No)f(time)h(is)g +(required)d(for)i(the)g(transition)f(between)h(send)g(and)f(recei)n(v)o +(e)g(phase)h(of)g(one)g(ipc)g(operation.)156 3340 y Ft(P)o(arameters) +156 3592 y Fs(snd)g(descriptor)779 3629 y(\223nil\224)p +1128 3521 2126 4 v 1128 3687 4 167 v 986 w FF(0xFFFFFFFF)2323 +3643 y Fr(\(32\))p 3250 3687 V 1128 3690 2126 4 v 1128 +3795 a FI(Ipc)g(does)f(not)h(include)f(a)i(send)f(operation.)779 +4019 y Fs(\223mem\224)p 1128 3911 1993 4 v 1128 4077 +4 167 v 879 w FF(*snd)d(msg/4)2228 4033 y Fr(\(30\))p +3117 4077 V 1128 4080 1993 4 v 3120 3911 67 4 v 3120 +4077 4 167 v 3123 4019 a Fp(m)p 3183 4077 V 3120 4080 +67 4 v 3187 3911 V 3187 4077 4 167 v 17 w(p)p 3250 4077 +V 3187 4080 67 4 v 1128 4185 a FI(Ipc)27 b(includes)g(sending)g(a)h +(message)g(to)f(the)h(destination)f(speci\002ed)g(by)h +Fs(dest)g(id)p FI(.)48 b(*snd)1128 4285 y(msg)22 b(must)h(point)e(to)i +(a)g(v)n(alid)f(message.)31 b(The)22 b(\002rst)i(tw)o(o)e(32-bit)g(w)o +(ords)g(of)g(the)g(message)1128 4384 y(\()p Fs(msg)o(.w0)i +FI(and)g Fs(msg)o(.w1)p FI(\))g(are)h Fs(not)f FI(tak)o(en)g(from)g +(the)h(message)f(data)h(structure)e(b)n(ut)i(must)1128 +4484 y(be)20 b(contained)e(in)j(re)o(gisters)f(EDX)g(and)g(EBX.)779 +4708 y Fs(\223r)m(e)m(g\224)p 1128 4600 1993 4 v 1128 +4766 4 167 v 1067 w FF(0)2092 4722 y Fr(\(30\))p 3117 +4766 V 1128 4769 1993 4 v 3120 4600 67 4 v 3120 4766 +4 167 v 3137 4708 a FF(0)p 3183 4766 V 3120 4769 67 4 +v 3187 4600 V 3187 4766 4 167 v 32 w Fp(p)p 3250 4766 +V 3187 4769 67 4 v 1128 4874 a FI(Ipc)29 b(includes)g(sending)g(a)h +(message)f(to)h(the)g(destination)f(speci\002ed)g(by)h +Fs(dest)g(id)p FI(.)53 b(The)1128 4974 y(message)16 b(consists)h +(solely)f(of)g(the)g(tw)o(o)g(32-bit)g(w)o(ords)f Fs(msg)o(.w0)h +FI(and)g Fs(msg)o(.w1)g FI(in)g(re)o(gisters)1128 5073 +y(EDX)k(and)g(EBX.)779 5256 y Fy(m)852 5248 y Fx(=)903 +5256 y Fu(0)183 b FI(V)-9 b(alue-cop)o(ying)16 b(send)j(operation;)f +(the)i(dw)o(ords)f(or)g(the)g(message)h(are)f(simply)g(copied)g(to)1128 +5356 y(the)h(recipient.)p eop +%%Page: 17 17 +17 16 bop 322 -290 a FB(IPC)3388 b FI(17)322 -83 y Fs(snd)21 +b(descriptor)945 -87 y Fy(m)1018 -95 y Fx(=)1069 -87 +y Fu(1)183 b FI(Fpage-mapping)29 b(send)j(operation.)60 +b(The)32 b(dw)o(ords)g(of)g(the)h(message)f(to)h(be)f(sent)h(are)1294 +12 y(treated)40 b(as)h(')-5 b(send)40 b(fpages'.)85 b(The)40 +b(described)f(fpages)h(are)g(mapped)f(\(respecti)n(v)o(ely)1294 +112 y(granted\))24 b(into)i(the)h(recipient')-5 b(s)25 +b(address)h(space.)43 b(Mapping/granting)23 b(stops)j(when)g(ei-)1294 +212 y(ther)17 b(the)g(end)g(of)g(the)h(dw)o(ords)e(is)j(reached)d(or)h +(when)g(an)g(in)m(v)n(alid)f(fpage)h(denoter)f(is)i(found,)1294 +311 y(in)j(particular)f(0.)29 b(The)21 b(send)g(fpage)f(descriptors)g +(and)h(all)h(potentially)e(follo)n(wing)f(w)o(ords)1294 +411 y(are)i(also)h(transferred)d(by)i(simple)g(cop)o(y)g(to)g(the)h +(recipient.)27 b(Thus)21 b(a)h(message)f(may)g(con-)1294 +510 y(tain)27 b(some)g(fpages)g(and)g(additional)f(v)n(alue)g +(parameters.)45 b(The)27 b(recipient)f(can)i(use)f(the)1294 +610 y(recei)n(v)o(ed)20 b(fpage)g(descriptors)g(to)i(determine)e(what)h +(has)h(been)e(mapped)g(or)h(granted)f(into)1294 710 y(its)h(address)f +(space,)g(including)e(location)h(and)h(access)h(rights.)945 +892 y Fy(p)987 884 y Fx(=)1038 892 y Fu(0)214 b FI(Normal)17 +b(\(unpropagated\))c(send)k(operation.)23 b(The)17 b(recipient)g(gets)h +(the)g(original)e(sender')-5 b(s)1294 992 y(id.)945 1158 +y Fy(p)987 1150 y Fx(=)1038 1158 y Fu(1)214 b FI(Propagating)18 +b(send)i(operation.)k(The)c(additional)f Fs(pr)l(opa)o(gatee)f +FI(parameter)h(on)h(the)h(stack)1294 1258 y(speci\002es)f(the)h(id)f +(of)g(the)g(propagatee)e(thread.)1294 1357 y(If)h(propagatee)d(and)i +(current)g(sender)g(or)g(propagatee)f(and)h(recei)n(v)o(er)g(belong)f +(to)i(the)g(same)1294 1457 y(task,)30 b(propagation)c(is)j(al)o(w)o +(ays)g(permitted.)49 b(Otherwise,)30 b(the)e(current)f(sender)h(is)i +(sup-)1294 1557 y(posed)21 b(to)h(be)g(a)g(chief)f(that)h(uses)g +(deceiting)f(and)g(it)i(is)g(check)o(ed)d(whether)h(it)i(is)f +(direction)1294 1656 y(preserving.)h(If)d(not,)f Fy(p)i +FI(and)f(the)g Fs(pr)l(opa)o(gatee)e FI(parameter)h(are)h(ignored.)1294 +1756 y(If)27 b(propagation)d(\(or)j(decei)n(ving\))f(is)i(permitted,)g +(the)g(recei)n(v)o(er)e(recei)n(v)o(es)g(the)i(propaga-)1294 +1855 y(tee')-5 b(s)22 b(id)g(instead)f(of)h(the)g(current)e(sender')-5 +b(s)21 b(id.)30 b(If)21 b(the)h(propagatee)d(is)k(w)o(aiting)e +(\(closed\))1294 1955 y(for)d(a)h(reply)f(from)f(the)i(current)e +(sender)m(,)h(the)g(propagatee')-5 b(s)17 b(status)i(is)g(additionally) +e(mod-)1294 2055 y(i\002ed)25 b(such)g(that)g(the)g(propagatee)d(no)n +(w)j(w)o(aits)h(for)e(a)h(the)g(ne)n(w)g(recei)n(v)o(er)f(instead)g(of) +h(the)1294 2154 y(current)19 b(sender)-5 b(.)1294 2254 +y(The)20 b Fs(pr)l(opa)o(gatee)e FI(parameter)h(on)g(the)i(user)f +(stack)g(is)h(only)f(required)e(if)i Fy(p)3422 2246 y +Fx(=)3473 2254 y Fu(1)p FI(.)322 2969 y Fs(r)m(cv)h(descriptor)945 +3006 y(\223nil\224)p 1312 2898 2126 4 v 1312 3064 4 167 +v 1004 w FF(0xFFFFFFFF)2508 3020 y Fr(\(32\))p 3434 3064 +V 1312 3067 2126 4 v 1312 3172 a FI(Ipc)f(does)g(not)g(include)f(a)i +(recei)n(v)o(e)e(operation.)945 3396 y Fs(\223mem\224)p +1312 3288 1993 4 v 1312 3454 4 167 v 898 w FF(*snd)e(msg/4)2413 +3410 y Fr(\(30\))p 3302 3454 V 1312 3457 1993 4 v 3305 +3288 67 4 v 3305 3454 4 167 v 3321 3396 a FF(0)p 3368 +3454 V 3305 3457 67 4 v 3371 3288 V 3371 3454 4 167 v +33 w Fp(o)p 3434 3454 V 3371 3457 67 4 v 1312 3562 a +FI(Ipc)30 b(includes)g(recei)n(ving)f(a)i(message)f(respecti)n(v)o(ely) +f(w)o(aiting)h(to)h(recei)n(v)o(e)e(a)i(message.)1312 +3662 y(*rcv)23 b(msg)g(must)h(point)f(to)g(a)h(v)n(alid)f(message.)35 +b(The)23 b(\002rst)i(tw)o(o)f(32-bit)e(w)o(ords)h(of)g(the)h(re-)1312 +3762 y(cei)n(v)o(ed)19 b(message)h(\()p Fs(msg)o(.w0)g +FI(and)f Fs(msg)o(.w1)p FI(\))h(are)g Fs(not)g FI(stored)g(in)g(the)g +(message)g(data)g(struc-)1312 3861 y(ture)g(b)n(ut)g(are)g(returned)f +(in)h(re)o(gisters)g(EDX)g(and)g(EBX.)945 4085 y Fs(\223r)m(e)m(g\224)p +1312 3977 1993 4 v 1312 4143 4 167 v 1085 w FF(0)2277 +4099 y Fr(\(30\))p 3302 4143 V 1312 4146 1993 4 v 3305 +3977 67 4 v 3305 4143 4 167 v 3321 4085 a FF(0)p 3368 +4143 V 3305 4146 67 4 v 3371 3977 V 3371 4143 4 167 v +33 w Fp(o)p 3434 4143 V 3371 4146 67 4 v 1312 4251 a +FI(Ipc)30 b(includes)g(recei)n(ving)f(a)i(message)f(respecti)n(v)o(ely) +f(w)o(aiting)h(to)h(recei)n(v)o(e)e(a)i(message.)1312 +4351 y(Ho)n(we)n(v)o(er)m(,)c(only)f(messages)h(up)f(to)i(tw)o(o)f +(32-bit)f(w)o(ords)g Fs(msg)o(.w0)h FI(and)f Fs(msg)o(.w1)h +FI(are)g(ac-)1312 4451 y(cepted.)d(The)c(recei)n(v)o(ed)f(message)h(is) +h(returned)e(in)h(re)o(gisters)g(EDX)g(and)g(EBX.)945 +4675 y Fs(\223rmap\224)p 1312 4567 1993 4 v 1312 4733 +4 167 v 906 w FF(rcv)e(fpage)2385 4689 y Fr(\(30\))p +3302 4733 V 1312 4736 1993 4 v 3305 4567 67 4 v 3305 +4733 4 167 v 3321 4675 a FF(1)p 3368 4733 V 3305 4736 +67 4 v 3371 4567 V 3371 4733 4 167 v 33 w Fp(o)p 3434 +4733 V 3371 4736 67 4 v 1312 4841 a FI(Ipc)30 b(includes)g(recei)n +(ving)f(a)i(message)f(respecti)n(v)o(ely)f(w)o(aiting)h(to)h(recei)n(v) +o(e)e(a)i(message.)1312 4940 y(Ho)n(we)n(v)o(er)m(,)h(only)e +(send-fpage)f(messages)i(or)g(up)g(to)g(tw)o(o)h(32-bit)e(w)o(ords)g +Fs(msg)o(.w0)h FI(and)1312 5040 y Fs(msg)o(.w1)24 b FI(are)g(accepted.) +36 b(The)24 b(recei)n(v)o(ed)f(message)h(is)h(returned)e(in)h(re)o +(gisters)g(EDX)g(and)1312 5140 y(EBX.)29 b(If)g(a)g(map)f(message)g(is) +h(recei)n(v)o(ed,)g(\223rcv)f(fpage\224)g(describes)g(the)g(recei)n(v)o +(e)g(fpage)1312 5239 y(\(instead)23 b(of)f(\223rcv)g(fpage)g +(option\224)f(in)i(a)h(memory)d(message)h(b)n(uf)n(fer\).)31 +b(Thus)23 b(fpages)f(can)1312 5339 y(also)f(be)f(recei)n(v)o(ed)f +(without)g(a)i(message)f(b)n(uf)n(fer)f(in)h(memory)-5 +b(.)p eop +%%Page: 18 18 +18 17 bop 156 -290 a FI(18)3387 b FB(IPC)156 -83 y Fs(r)m(cv)21 +b(descriptor)779 -87 y Fy(o)819 -95 y Fx(=)870 -87 y +Fu(0)216 b FI(Only)15 b(messages)h(from)f(the)g(thread)g(speci\002ed)h +(as)g Fs(dest)g(id)g FI(are)f(accepted)g(\(\223closed)g(w)o(ait\224\).) +1128 12 y(An)o(y)j(send)h(operation)e(from)g(a)j(dif)n(ferent)d(thread) +h(\(or)g(hardw)o(are)g(interrupt\))f(will)i(be)g(han-)1128 +112 y(dled)g(e)o(xactly)h(as)h(if)f(the)g(actual)g(thread)g(w)o(ould)f +(be)h(b)n(usy)-5 b(.)779 278 y Fy(o)819 270 y Fx(=)870 +278 y Fu(1)216 b FI(Messages)22 b(from)f(an)o(y)g(thread)g(will)i(be)f +(accepted)f(\(\223open)g(w)o(ait\224\).)30 b(If)22 b(the)g(actual)g +(thread)1128 378 y(is)j(associated)g(with)g(a)g(hardw)o(are)e +(interrupt,)h(also)h(messages)g(from)f(this)h(hardw)o(are)e(in-)1128 +477 y(terrupt)c(can)h(arri)n(v)o(e.)156 676 y Fs(dest)h(id)779 +648 y Fn(6)p Fx(=)830 656 y Fy(nil)194 b FI(Sending)21 +b(is)j(directed)e(to)h(the)g(speci\002ed)g(thread,)f(if)h(it)h(resides) +f(in)g(the)g(sender')-5 b(s)22 b(clan.)33 b(If)1128 755 +y(the)22 b(destination)g(is)h(outside)f(the)g(sender')-5 +b(s)23 b(clan,)f(the)h(message)f(is)i(sent)e(to)h(the)f(sender')-5 +b(s)1128 855 y(chief.)41 b(If)26 b(the)f(destination)g(is)i(in)f(an)f +(inner)g(clan)h(\(a)g(clan)f(whose)h(chief)f(resides)h(in)g(the)1128 +955 y(sender')-5 b(s)20 b(clan\),)g(it)h(is)h(redirected)d(to)i(that)f +(chief.)26 b(\(See)21 b(also)g(`nchief)5 b(')18 b(operation.\))24 +b(If)c(no)1128 1054 y(send)f(part)h(w)o(as)h(speci\002ed)f(\()p +Fs(snd)f(descriptor)2440 1046 y Fx(=)2491 1054 y Fy(nil)r +FI(\),)g Fs(dest)h(id)g FI(speci\002es)h(the)f(source)f(from)1128 +1154 y(which)g(messages)h(can)g(be)f(recei)n(v)o(ed.)24 +b(\(Ho)n(we)n(v)o(er)18 b(recall)h(that)h(the)g(recei)n(v)o(e)f +(restriction)g(is)1128 1253 y(only)g(ef)n(fecti)n(v)o(e)g(if)h +Fy(o)1734 1245 y Fx(=)1806 1253 y Fu(0)p FI(.\))779 1345 +y Fx(=)830 1353 y Fy(nil)194 b Fu(\()p Fy(nil)1266 1345 +y Fx(=)1316 1353 y Fu(0\))21 b FI(Although)e(specifying)g +Fy(nil)j FI(as)f(the)g(destination)e(for)h(a)h(send)f(operation)f(is)j +(ille-)1128 1453 y(gal)h(\(error:)31 b(`destination)23 +b(not)g(e)o(xistent'\),)h(it)g(can)g(be)g(le)o(gally)e(speci\002ed)i +(for)f(a)h(recei)n(v)o(e-)1128 1552 y(only)29 b(operation.)51 +b(In)30 b(this)g(case,)i(ipc)e(will)h(not)e(recei)n(v)o(e)g(an)o(y)g +(message)g(b)n(ut)h(will)g(w)o(ait)1128 1652 y(the)22 +b(speci\002ed)f Fs(r)m(cv)i(timeout)e FI(and)g(then)h(terminate)f(with) +h(error)f(code)g(`recei)n(v)o(e)f(timeout'.)1128 1752 +y(\(Ho)n(we)n(v)o(er)e(recall)i(that)g(the)h(recei)n(v)o(e)e +(restriction)g(is)i(only)f(ef)n(fecti)n(v)o(e)e(if)j +Fy(o)3245 1744 y Fx(=)3317 1752 y Fu(0)p FI(.\))156 1950 +y Fs(sour)m(ce)f(id)1128 1930 y FI(If)k(a)h(message)f(w)o(as)h(recei)n +(v)o(ed)e(this)i(is)h(the)e(id)h(of)f(its)h(sender)-5 +b(.)38 b(\(If)24 b(a)h(hardw)o(are)e(interrupt)1128 2030 +y(w)o(as)d(recei)n(v)o(ed)d(this)j(is)g(the)g(interrupt)d(id.\))25 +b(The)19 b(parameter)e(is)k(unde\002ned)c(if)i(no)g(message)1128 +2129 y(w)o(as)i(recei)n(v)o(ed.)156 2327 y Fs(msg)o(.w0,)f(w1,)g(w2)779 +2322 y(\223snd\224)141 b FI(First)21 b(three)f(32-bit)f(w)o(ords)h(of)f +(message)i(to)f(be)g(sent.)25 b(These)20 b(message)g(w)o(ords)g(are)g +(tak)o(en)1128 2422 y(directly)j(from)g(re)o(gisters)g(EDX,)h(EBX,)g +(and)g(EDI.)f Fs(The)n(y)h(ar)m(e)g(not)g(r)m(ead)f(fr)l(om)i(the)f +(mes-)1128 2522 y(sa)o(g)o(e)c(data)f(structur)m(e)o(.)779 +2663 y(\223r)m(cv\224)154 b FI(First)33 b(three)f(32-bit)f(w)o(ords)h +(of)g(recei)n(v)o(ed)f(message,)k(unde\002ned)30 b(if)j(no)f(message)g +(w)o(as)1128 2762 y(recei)n(v)o(ed.)26 b Fs(These)21 +b(messa)o(g)o(e)g(wor)m(ds)h(ar)m(e)f(available)f(only)g(in)i(r)m(e)m +(gister)o(s)g(EDX,)e(EBX,)h(and)1128 2862 y(EDI.)29 b +FI(The)g(Nucleus)g(does)g(not)g(store)g(it)h(in)f(the)h(recei)n(v)o(e)e +(message)h(b)n(uf)n(fer)-5 b(.)51 b(The)29 b(user)1128 +2962 y(program)18 b(may)i(store)g(it)h(or)e(use)i(it)g(directly)e(in)i +(the)f(re)o(gisters.)156 3160 y Fs(msg)o(.dope)f(+)i(cc)p +1128 3090 1262 4 v 1128 3256 4 167 v 1587 3198 a FF(mw)o(ords)1817 +3212 y Fr(\(19\))p 2386 3256 V 1128 3259 1262 4 v 2390 +3090 333 4 v 2390 3256 4 167 v 2442 3198 a FF(parts)2587 +3212 y Fr(\(5\))p 2718 3256 V 2390 3259 333 4 v 2722 +3090 532 4 v 2722 3256 4 167 v 2907 3198 a Fp(cc)2985 +3212 y Fr(\(8\))p 3250 3256 V 2722 3259 532 4 v 1128 +3364 a FI(Message)h(dope)e(describing)h(recei)n(v)o(ed)f(message.)29 +b(If)22 b(no)f(message)h(w)o(as)h(recei)n(v)o(ed,)d(only)1128 +3463 y Fy(cc)e FI(is)i(deli)n(v)o(ered.)i Fs(The)c(dope)f(wor)m(d)i(of) +f(the)g(r)m(eceived)g(messa)o(g)o(e)h(is)g(available)d(only)i(in)h(r)m +(e)m(g-)1128 3563 y(ister)f(EAX.)e FI(The)g(Nucleus)h(does)f(not)h +(store)f(it)i(in)f(the)g(recei)n(v)o(e)e(message)i(b)n(uf)n(fer)-5 +b(.)23 b(The)16 b(user)1128 3662 y(program)i(may)i(store)g(it)h(or)g +(use)f(it)h(directly)f(in)g(the)h(re)o(gister)-5 b(.)25 +b(\(Note)20 b(that)h(the)f(lo)n(wermost)1128 3762 y(8)j(bits)h(of)g +(msg)f(dope)g(and)g(size)h(dope)e(in)i(the)f(message)h(data)f +(structure)g(are)g(unde\002ned.)1128 3862 y(So)d(it)h(is)g(le)o(gal)f +(to)g(store)g(EAX)h(in)f(the)g(msg-dope)e(\002eld,)i(e)n(v)o(en)g(if)g +Fy(cc)3081 3854 y Fn(6)p Fx(=)3132 3862 y Fu(0)p FI(.\))156 +4040 y Fs(cc)p 1128 3952 266 4 v 1128 4119 4 167 v 1179 +4060 a Fp(ec)1259 4074 y Fr(\(4\))p 1390 4119 V 1128 +4122 266 4 v 1393 3952 67 4 v 1393 4119 4 167 v 1415 +4060 a Fp(i)p 1457 4119 V 1393 4122 67 4 v 1460 3952 +V 1460 4119 4 167 v 37 w(r)p 1523 4119 V 1460 4122 67 +4 v 1526 3952 V 1526 4119 4 167 v 21 w(m)p 1589 4119 +V 1526 4122 67 4 v 1593 3952 V 1593 4119 4 167 v 17 w(d)p +1656 4119 V 1593 4122 67 4 v 779 4226 a Fy(d)822 4218 +y Fx(=)873 4226 y Fu(0)213 b FI(The)20 b(recei)n(v)o(ed)e(message)i(is) +h(transferred)e(directly)g(\(\223undeceited\224\))f(from)h +Fs(sour)m(ce)h(id)p FI(.)779 4326 y Fy(d)822 4318 y Fx(=)873 +4326 y Fu(1)213 b FI(The)23 b(recei)n(v)o(ed)g(message)g(is)i +(\223deceited\224)e(by)g(a)i(chief.)35 b Fs(sour)m(ce)24 +b(id)g FI(is)h(the)f(virtual)f(source)1128 4426 y(id)d(which)g(w)o(as)h +(speci\002ed)f(by)f(the)i(sending)e(chief.)779 4525 y +Fy(m)852 4517 y Fx(=)903 4525 y Fu(0)183 b FI(The)20 +b(recei)n(v)o(ed)e(message)i(did)g(not)g(contain)f(fpages.)779 +4625 y Fy(m)852 4617 y Fx(=)903 4625 y Fu(1)183 b FI(The)16 +b(sender)g(mapped)e(or)j(granted)e(fpages.)23 b(The)16 +b(sender')-5 b(s)16 b(fpage)f(descriptors)g(were)i(also)1128 +4725 y(\(besides)j(mapping/granting\))15 b(transferred)k(as)i(mw)o +(ords.)779 4824 y Fy(r)818 4816 y Fx(=)870 4824 y Fu(0)216 +b FI(The)24 b(recei)n(v)o(ed)f(message)i(w)o(as)g(directed)f(to)h(the)g +(actual)f(recipient,)h(not)g(redirected)e(to)i(a)1128 +4924 y(chief.)e(I.e.)18 b(sender)f(and)h(recei)n(v)o(er)e(a)j(part)f +(of)f(the)h(same)g(clan.)25 b(The)17 b Fy(i)p FI(-bit)h(has)g(no)g +(meaning)1128 5023 y(in)i(this)h(case)f(and)g(is)h(zero.)779 +5123 y Fy(r)818 5115 y Fx(=)870 5123 y Fu(1)216 b FI(The)17 +b(recei)n(v)o(ed)g(message)g(w)o(as)i(redirected)d(to)j(the)e(chief)h +(which)f(w)o(as)i(ne)o(xt)e(on)h(the)f(path)h(to)1128 +5223 y(the)i(true)g(destination.)k(Sender)19 b(and)h(addressed)f +(recipient)g(belong)g(to)h(dif)n(ferent)f(clans.)779 +5322 y Fy(i)808 5314 y Fx(=)859 5322 y Fu(0)227 b FI(If)20 +b Fy(r)1243 5314 y Fx(=)1295 5322 y Fu(1)p FI(:)25 b(the)20 +b(recei)n(v)o(ed)f(message)h(comes)g(from)f(outside)g(the)i(o)n(wn)e +(clan.)779 5422 y Fy(i)808 5414 y Fx(=)859 5422 y Fu(1)227 +b FI(If)20 b Fy(r)1243 5414 y Fx(=)1295 5422 y Fu(1)p +FI(:)25 b(the)20 b(recei)n(v)o(ed)f(message)h(comes)g(from)f(an)h +(inner)f(clan.)p eop +%%Page: 19 19 +19 18 bop 322 -290 a FB(IPC)3388 b FI(19)322 -104 y Fs(ec)945 +-132 y Fx(=)1017 -124 y Fu(0)235 b Fs(ok)p FI(:)30 b(the)23 +b(optional)e(send)h(operation)f(w)o(as)j(successful,)f(and)f(if)h(a)g +(recei)n(v)o(e)e(operation)g(w)o(as)1294 -25 y(also)f(speci\002ed)g(\() +p Fs(r)m(cv)h(descriptor)2278 -33 y Fn(6)p Fx(=)2329 +-25 y Fy(nil)r FI(\))e(a)h(message)g(w)o(as)h(also)g(recei)n(v)o(ed)e +(correctly)-5 b(.)945 108 y Fn(6)p Fx(=)1017 116 y Fu(0)235 +b FI(If)22 b(ipc)g(f)o(ails)h(the)f(completion)f(code)g(is)i(in)g(the)f +(range)f(0x10.)12 b(.)g(.)g(0xF0.)29 b(If)22 b(the)g(send)g(oper)n(-) +1294 216 y(ation)g(already)f(f)o(ailed,)i(ipc)f(is)i(terminated)d +(without)g(the)i(potentially)e(speci\002ed)h(recei)n(v)o(e)1294 +316 y(operation.)56 b Fy(s)32 b FI(speci\002es)g(whether)e(the)h(error) +f(occurred)g(during)f(the)j(recei)n(v)o(e)e Fu(\()p Fy(s)3759 +308 y Fx(=)3824 316 y Fu(0\))1294 415 y FI(operation)18 +b(or)i(during)f(the)h(send)g Fu(\()p Fy(s)2336 407 y +Fx(=)2401 415 y Fu(1\))g FI(operation:)1153 556 y(1)99 +b Fs(Non-e)n(xisting)19 b FI(destination)g(or)h(source.)1012 +697 y Fu(2)e(+)g Fy(s)100 b Fs(T)-5 b(imeout)p FI(.)1012 +839 y Fu(4)18 b(+)g Fy(s)100 b Fs(Cancelled)19 b FI(by)h(another)f +(thread)g(\(system)h(call)h(lthread)p 2910 839 25 4 v +28 w(e)o(x)p 3016 839 V 29 w(re)o(gs\).)1012 980 y Fu(6)d(+)g +Fy(s)100 b Fs(Map)20 b(failed)g FI(due)f(to)i(a)f(shortage)f(of)h(page) +g(tables.)1012 1121 y Fu(8)e(+)g Fy(s)100 b Fs(Send)19 +b(pa)o(g)o(efault)g(timeout)p FI(.)992 1262 y Fy(A)f +Fu(+)g Fy(s)100 b Fs(Receive)20 b(pa)o(g)o(efault)e(timeout)p +FI(.)989 1403 y Fy(C)24 b Fu(+)18 b Fy(s)100 b Fs(Aborted)19 +b FI(by)h(another)f(thread)g(\(system)h(call)g(lthread)p +2840 1403 V 29 w(e)o(x)p 2947 1403 V 29 w(re)o(gs\).)988 +1544 y Fy(E)j Fu(+)18 b Fy(s)100 b Fs(Cut)16 b FI(message.)23 +b(Potential)15 b(reasons)g(are)g(\(a\))g(the)g(recipient')-5 +b(s)15 b(mw)o(ord)f(b)n(uf)n(fer)g(is)j(too)e(small;)1294 +1644 y(\(b\))j(the)h(recipient)f(does)h(not)g(accept)g(enough)e(parts;) +i(\(c\))g(at)g(least)h(one)f(of)g(the)g(recipient')-5 +b(s)1294 1744 y(part)20 b(b)n(uf)n(fers)f(is)i(too)f(small.)1012 +1910 y(1.)12 b(.)g(.)g(5)99 b(The)19 b(according)e(operation)h(w)o(as)i +(terminated)e(before)g(a)i(real)g(message)f(transfer)f(started.)1294 +2009 y(No)i(partner)f(w)o(as)i(directly)e(in)m(v)n(olv)o(ed.)1007 +2150 y(6.)12 b(.)g(.)g(F)100 b(The)18 b(according)e(operation)g(w)o(as) +j(terminated)e(while)h(a)g(message)g(transfer)g(w)o(as)g(running.)1294 +2250 y(The)f(message)h(transfer)f(w)o(as)i(aborted.)j(The)c(current)e +(partner)h(\(sender)g(or)g(recei)n(v)o(er\))f(w)o(as)1294 +2350 y(in)m(v)n(olv)o(ed)j(and)h(got)h(the)g(corresponding)d(error)i +(code.)27 b(It)21 b(is)h(not)f(de\002ned)f(which)g(parts)h(of)1294 +2449 y(the)f(message)g(are)g(already)f(transferred)g(and)g(which)h +(parts)g(are)g(not)g(yet)g(transferred.)322 3573 y Fs(timeouts)1294 +3552 y FI(This)f(32-bit)f(w)o(ord)h(speci\002es)g(all)h(4)f(timouts,)g +(the)g(quadruple)e(\()p Fs(snd,)i(r)m(cv)-6 b(,)19 b(snd)g(pf)o(,)h(r)m +(cv)g(pf)p FI(\).)1294 3652 y(F)o(or)g(A)g(detailed)g(description)f +(see)h(section)g(2.2.4.)k(Frequently)18 b(used)i(v)n(alues)g(are)p +1932 3713 1329 4 v 1930 3792 4 79 v 2362 3792 V 2413 +3769 a FF(snd)100 b(rcv)g(snd)17 b(pf)100 b(rcv)18 b(pf)p +3258 3792 V 1932 3796 1329 4 v 1930 3874 4 79 v 1981 +3851 a(0x00000000)p 2362 3874 V 113 w FE(1)117 b(1)153 +b(1)189 b(1)p 3258 3874 V 1930 3953 V 1981 3930 a FF(0x00000001)p +2362 3953 V 131 w Fo(0)135 b FE(1)153 b(1)189 b(1)p 3258 +3953 V 1930 4032 V 1981 4009 a FF(0x00000011)p 2362 4032 +V 131 w Fo(0)153 b(0)171 b FE(1)189 b(1)p 3258 4032 V +1932 4035 1329 4 v 945 4143 a Fs(\223snd\224)141 b FI(If)30 +b(the)g(required)f(send)h(operation)e(cannot)i(start)g(transfer)g(data) +g(within)g(the)g(speci\002ed)1294 4243 y(time,)c(ipc)f(is)g(terminated) +f(and)g(f)o(ails)h(with)g(completion)e(code)i(`send)f(timeout')f +(\(0x18\).)1294 4343 y(If)d(ipc)g(does)g(not)g(include)f(a)i(send)f +(operation,)e(this)i(parameter)f(is)i(meaningless.)945 +4442 y Fs(\223r)m(cv\224)154 b FI(If)29 b(ipc)g(includes)f(a)i(recei)n +(v)o(e)e(operation)f(and)i(no)g(message)g(transfer)f(starts)i(within)f +(the)1294 4542 y(speci\002ed)22 b(time,)g(ipc)g(is)h(terminated)e(and)g +(f)o(ails)i(with)f(completion)e(code)i(`recei)n(v)o(e)e(time-)1294 +4642 y(out')15 b(\(0xA0\).)22 b(If)17 b(ipc)f(does)g(not)g(include)f(a) +i(recei)n(v)o(e)e(operation,)g(this)i(parameter)e(is)i(mean-)1294 +4741 y(ingless.)945 4841 y Fs(\223spf)8 b(\224)152 b +FI(If)24 b(during)f(sending)g(data)i(a)g(pagef)o(ault)e +Fs(in)h(the)h(r)m(eceiver')m(s)f(addr)m(ess)h(space)f +FI(occurs,)g Fs(snd)1294 4940 y(pf)d FI(speci\002ed)f(by)g(the)h +(sender)f(is)i(used)e(as)h(send)g(and)f(recei)n(v)o(e)g(timeout)g(for)g +(the)g(pagef)o(ault)1294 5040 y(RPC.)945 5140 y Fs(\223rpf)8 +b(\224)152 b FI(If)18 b(during)f(recei)n(ving)g(data)h(a)h(pagef)o +(ault)e Fs(in)i(the)g(sender')m(s)f(addr)m(ess)g(space)g +FI(occurs,)g Fs(r)m(cv)h(pf)1294 5239 y FI(speci\002ed)k(by)g(the)h +(recei)n(v)o(er)e(is)j(used)e(as)i(send)e(and)g(recei)n(v)o(e)g +(timeout)g(for)g(the)g(pagef)o(ault)1294 5339 y(RPC.)p +eop +%%Page: 20 20 +20 19 bop 156 -290 a FI(20)3387 b FB(IPC)156 -57 y Ft(Basic)25 +b(Ipc)h(T)-7 b(ypes)158 323 y Fe(C)t(A)t(L)t(L)p 1985 +333 4 100 v 2627 333 V 1985 432 V 2627 432 V 1985 532 +V 2627 532 V 1985 631 V 2036 602 a Fd(\000)22 b FI(INT)e(0x30)p +Fg(!)p 2627 631 V 1283 303 a Fs(*snd)g(msg)g(/)h(0)99 +b FF(EAX)p 1985 333 V 2627 333 V 742 w(EAX)g Fs(msg)o(.dope)18 +b(+)j Fy(cc)1419 402 y Fs(timeouts)99 b FF(ECX)p 1985 +432 V 2627 432 V 746 w(ECX)k Fv(\030)1450 502 y Fs(msg)o(.w0)c +FF(EDX)p 1985 532 V 2627 532 V 742 w(EDX)g Fs(msg)o(.w0)1450 +602 y(msg)o(.w1)g FF(EBX)p 1985 631 V 2627 631 V 746 +w(EBX)k Fs(msg)o(.w1)1296 701 y(*r)m(cv)20 b(msg)g(/)h(0)99 +b FF(EBP)p 1985 731 V 2627 731 V 757 w(EBP)114 b Fv(\030)1482 +801 y Fs(dest)20 b(id)99 b FF(ESI)p 1985 831 V 2627 831 +V 779 w(ESI)136 b Fs(unc)o(hang)o(ed)1450 900 y(msg)o(.w2)99 +b FF(EDI)p 1985 930 V 2627 930 V 768 w(EDI)125 b Fs(msg)o(.w2)156 +1201 y FI(This)28 b(is)h(the)f(usual)f(blocking)f(RPC.)j +Fs(snd)f(msg)g FI(is)g(sent)h(to)e Fs(dest)h(id)g FI(and)g(the)f(in)m +(v)n(ok)o(er)f(w)o(aits)j(for)e(a)h(reply)f(from)g Fs(dest)h(id)p +FI(.)156 1301 y(Messages)22 b(from)e(other)g(sources)h(are)g(not)f +(accepted.)27 b(Note)21 b(that)g(since)g(the)g(send/recei)n(v)o(e)e +(transition)i(needs)f(no)h(time,)g(the)156 1401 y(destination)f(can)g +(reply)f(with)h Fs(snd)g(timeout)1443 1393 y Fx(=)1515 +1401 y FI(0.)281 1540 y(This)h(operation)e(can)h(also)h(be)g(used)f +(for)g(a)h(serv)o(er)f(with)h(one)f(dedicated)g(client.)26 +b(It)21 b(sends)g(the)f(reply)g(to)h(the)g(client)g(and)156 +1640 y(w)o(aits)h(for)d(the)h(client')-5 b(s)21 b(ne)o(xt)e(order)-5 +b(.)158 1923 y Fe(S)t(E)t(N)t(D)t FJ(/)t Fe(R)t(E)t(C)5 +b(E)g(I)t(V)g(E)p 1985 1932 V 2627 1932 V 1985 2032 V +2627 2032 V 1985 2131 V 2627 2131 V 1985 2231 V 2036 +2201 a Fd(\000)22 b FI(INT)e(0x30)p Fg(!)p 2627 2231 +V 1283 1902 a Fs(*snd)g(msg)g(/)h(0)99 b FF(EAX)p 1985 +1932 V 2627 1932 V 742 w(EAX)g Fs(msg)o(.dope)18 b(+)j +Fy(cc)1419 2002 y Fs(timeouts)99 b FF(ECX)p 1985 2032 +V 2627 2032 V 746 w(ECX)k Fv(\030)1450 2102 y Fs(msg)o(.w0)c +FF(EDX)p 1985 2131 V 2627 2131 V 742 w(EDX)g Fs(msg)o(.w0)1450 +2201 y(msg)o(.w1)g FF(EBX)p 1985 2231 V 2627 2231 V 746 +w(EBX)k Fs(msg)o(.w1)1100 2301 y(*r)m(cv)21 b(msg+1)f(/)h(0+1)98 +b FF(EBP)p 1985 2331 V 2627 2331 V 757 w(EBP)114 b Fv(\030)1482 +2400 y Fs(dest)20 b(id)99 b FF(ESI)p 1985 2430 V 2627 +2430 V 779 w(ESI)136 b Fs(sour)m(ce)20 b(id)1450 2500 +y(msg)o(.w2)99 b FF(EDI)p 1985 2530 V 2627 2530 V 768 +w(EDI)125 b Fs(msg)o(.w2)156 2801 y(snd)29 b(msg)h FI(is)g(sent)f(to)h +Fs(dest)f(id)g FI(and)g(the)g(in)m(v)n(ok)o(er)f(w)o(aits)i(for)e(a)i +(reply)e(from)g(an)o(y)g(source.)51 b(This)30 b(is)g(the)f(standard)f +(serv)o(er)156 2901 y(operation:)g(it)22 b(sends)g(a)h(reply)e(to)h +(the)g(actual)g(client)g(and)g(w)o(aits)h(for)e(the)h(ne)o(xt)g(order)f +(which)g(may)h(come)f(from)g(a)i(dif)n(ferent)156 3000 +y(client.)158 3269 y Fe(S)t(E)t(N)t(D)p 1985 3278 V 2627 +3278 V 1985 3378 V 2627 3378 V 1985 3477 V 2627 3477 +V 1985 3577 V 2036 3547 a Fd(\000)f FI(INT)e(0x30)p Fg(!)p +2627 3577 V 1283 3248 a Fs(*snd)g(msg)g(/)h(0)99 b FF(EAX)p +1985 3278 V 2627 3278 V 742 w(EAX)g Fy(cc)1419 3348 y +Fs(timeouts)g FF(ECX)p 1985 3378 V 2627 3378 V 746 w(ECX)k +Fv(\030)1450 3448 y Fs(msg)o(.w0)c FF(EDX)p 1985 3477 +V 2627 3477 V 742 w(EDX)g Fv(\030)1450 3547 y Fs(msg)o(.w1)g +FF(EBX)p 1985 3577 V 2627 3577 V 746 w(EBX)k Fv(\030)1216 +3647 y Fs(0xFFFFFFFF)97 b FF(EBP)p 1985 3677 V 2627 3677 +V 757 w(EBP)114 b Fv(\030)1482 3746 y Fs(dest)20 b(id)99 +b FF(ESI)p 1985 3776 V 2627 3776 V 779 w(ESI)136 b Fv(\030)1450 +3846 y Fs(msg)o(.w2)99 b FF(EDI)p 1985 3876 V 2627 3876 +V 768 w(EDI)125 b Fv(\030)156 4147 y Fs(snd)23 b(msg)f +FI(is)i(sent)f(to)f Fs(dest)h(id)p FI(.)32 b(There)21 +b(is)j(no)e(recei)n(v)o(e)f(phase)h(included.)30 b(The)22 +b(in)m(v)n(ok)o(er)f(continues)g(w)o(orking)g(after)h(sending)156 +4247 y(the)f(message.)158 4532 y Fe(R)t(E)t(C)t(E)t(I)t(V)t(E)34 +b(F)t(R)q(O)t(M)p 1985 4542 V 2627 4542 V 1985 4641 V +2627 4641 V 1985 4741 V 2627 4741 V 1985 4840 V 2036 +4811 a Fd(\000)22 b FI(INT)e(0x30)p Fg(!)p 2627 4840 +V 1216 4512 a Fs(0xFFFFFFFF)97 b FF(EAX)p 1985 4542 V +2627 4542 V 742 w(EAX)i Fs(msg)o(.dope)18 b(+)j Fy(cc)1419 +4611 y Fs(timeouts)99 b FF(ECX)p 1985 4641 V 2627 4641 +V 746 w(ECX)k Fv(\030)1636 4711 y(\030)c FF(EDX)p 1985 +4741 V 2627 4741 V 742 w(EDX)g Fs(msg)o(.w0)1636 4811 +y Fv(\030)g FF(EBX)p 1985 4840 V 2627 4840 V 746 w(EBX)k +Fs(msg)o(.w1)1296 4910 y(*r)m(cv)20 b(msg)g(/)h(0)99 +b FF(EBP)p 1985 4940 V 2627 4940 V 757 w(EBP)114 b Fv(\030)1482 +5010 y Fs(dest)20 b(id)99 b FF(ESI)p 1985 5040 V 2627 +5040 V 779 w(ESI)136 b Fs(unc)o(hang)o(ed)1636 5109 y +Fv(\030)99 b FF(EDI)p 1985 5139 V 2627 5139 V 768 w(EDI)125 +b Fs(msg)o(.w2)156 5410 y FI(This)19 b(operation)d(includes)h(no)h +(send)g(phase.)24 b(The)18 b(in)m(v)n(ok)o(er)e(w)o(aits)k(for)d(a)i +(message)f(from)f Fs(sour)m(ce)h(id)p FI(.)24 b(Messages)19 +b(from)e(other)p eop +%%Page: 21 21 +21 20 bop 322 -290 a FB(IPC)3388 b FI(21)322 -57 y(sources)20 +b(are)g(not)g(accepted.)k(Note)c(that)g(also)h(a)g(hardw)o(are)d +(interrupt)h(might)h(be)g(speci\002ed)g(as)h(source.)324 +200 y Fe(R)t(E)t(C)t(E)t(I)t(V)t(E)p 2151 210 4 100 v +2793 210 V 2151 309 V 2793 309 V 2151 409 V 2793 409 +V 2151 509 V 2202 479 a Fd(\000)h FI(INT)e(0x30)p Fg(!)p +2793 509 V 1382 180 a Fs(0xFFFFFFFF)97 b FF(EAX)p 2151 +210 V 2793 210 V 742 w(EAX)i Fs(msg)o(.dope)18 b(+)j +Fy(cc)1585 279 y Fs(timeouts)99 b FF(ECX)p 2151 309 V +2793 309 V 746 w(ECX)k Fv(\030)1802 379 y(\030)c FF(EDX)p +2151 409 V 2793 409 V 742 w(EDX)g Fs(msg)o(.w0)1802 479 +y Fv(\030)g FF(EBX)p 2151 509 V 2793 509 V 746 w(EBX)k +Fs(msg)o(.w1)1266 578 y(*r)m(cv)21 b(msg+1)f(/)h(0+1)98 +b FF(EBP)p 2151 608 V 2793 608 V 757 w(EBP)114 b Fv(\030)1802 +678 y(\030)99 b FF(ESI)p 2151 708 V 2793 708 V 779 w(ESI)136 +b Fs(sour)m(ce)20 b(id)1802 778 y Fv(\030)99 b FF(EDI)p +2151 807 V 2793 807 V 768 w(EDI)125 b Fs(msg)o(.w2)322 +1050 y FI(This)23 b(operation)e(includes)g(no)h(send)h(phase.)31 +b(The)22 b(in)m(v)n(ok)o(er)f(w)o(aits)i(for)f(a)h(message)f(from)g(an) +o(y)f(source)h(\(including)e(a)j(hard-)322 1149 y(w)o(are)e +(interrupt\).)324 1406 y Fe(R)t(E)t(C)t(E)t(I)t(V)t(E)34 +b(I)t(N)t(T)t(R)p 2151 1416 V 2793 1416 V 2151 1515 V +2793 1515 V 2151 1615 V 2793 1615 V 2151 1714 V 2202 +1685 a Fd(\000)22 b FI(INT)e(0x30)p Fg(!)p 2793 1714 +V 1382 1386 a Fs(0xFFFFFFFF)97 b FF(EAX)p 2151 1416 V +2793 1416 V 742 w(EAX)i Fs(msg)o(.dope)18 b(+)j Fy(cc)1585 +1485 y Fs(timeouts)99 b FF(ECX)p 2151 1515 V 2793 1515 +V 746 w(ECX)k Fv(\030)1802 1585 y(\030)c FF(EDX)p 2151 +1615 V 2793 1615 V 742 w(EDX)g Fv(\030)1802 1685 y(\030)g +FF(EBX)p 2151 1714 V 2793 1714 V 746 w(EBX)k Fv(\030)1462 +1784 y Fs(*r)m(cv)20 b(msg)g(/)h(0)99 b FF(EBP)p 2151 +1814 V 2793 1814 V 757 w(EBP)114 b Fv(\030)1608 1884 +y Fs(intr)20 b(+)h(1)99 b FF(ESI)p 2151 1914 V 2793 1914 +V 779 w(ESI)136 b Fs(unc)o(hang)o(ed)1802 1983 y Fv(\030)99 +b FF(EDI)p 2151 2013 V 2793 2013 V 768 w(EDI)125 b Fv(\030)322 +2256 y FI(This)27 b(operation)e(includes)h(no)g(send)h(phase.)44 +b(The)26 b(in)m(v)n(ok)o(er)f(w)o(aits)j(for)e(an)h(interrupt)e +(message)i(coming)e(from)h(interrupt)322 2355 y(source)19 +b Fs(intr)p FI(.)25 b(Note)19 b(that)g(interrupt)e(messages)i(come)g +Fs(only)f FI(from)g(the)h(interrupt)f(which)g(is)i(currently)e +(associated)g(with)h(this)322 2455 y(thread.)447 2566 +y(The)h Fs(intr)h FI(parameter)d(is)j(only)f(e)n(v)n(aluated)e(if)j +Fs(r)m(cv)g(timeout)2134 2558 y Fx(=)2206 2566 y FI(0)f(is)i +(speci\002ed,)d(see)i(`associate)f(intr'.)324 2822 y +Fe(A)t(S)t(S)t(O)t(C)t(I)t(A)-5 b(T)5 b(E)35 b(I)t(N)t(T)t(R)p +2151 2832 V 2793 2832 V 2151 2932 V 2793 2932 V 2151 +3031 V 2793 3031 V 2151 3131 V 2202 3101 a Fd(\000)22 +b FI(INT)e(0x30)p Fg(!)p 2793 3131 V 1382 2802 a Fs(0xFFFFFFFF)97 +b FF(EAX)p 2151 2832 V 2793 2832 V 742 w(EAX)i Fs(msg)o(.dope)18 +b(+)j Fy(cc)1355 2902 y Fs(r)m(cv)g(timeout)e(=)i(0)99 +b FF(ECX)p 2151 2932 V 2793 2932 V 746 w(ECX)k Fv(\030)1802 +3001 y(\030)c FF(EDX)p 2151 3031 V 2793 3031 V 742 w(EDX)g +Fv(\030)1802 3101 y(\030)g FF(EBX)p 2151 3131 V 2793 +3131 V 746 w(EBX)k Fv(\030)1462 3201 y Fs(*r)m(cv)20 +b(msg)g(/)h(0)99 b FF(EBP)p 2151 3230 V 2793 3230 V 757 +w(EBP)114 b Fv(\030)1608 3300 y Fs(intr)20 b(+)h(1)99 +b FF(ESI)p 2151 3330 V 2793 3330 V 779 w(ESI)136 b Fs(unc)o(hang)o(ed) +1802 3400 y Fv(\030)99 b FF(EDI)p 2151 3430 V 2793 3430 +V 768 w(EDI)125 b Fv(\030)322 3672 y FI(The)17 b Fs(intr)g +FI(parameter)e(is)j(e)n(v)n(aluated)d(if)i Fs(r)m(cv)h(timeout)1814 +3664 y Fx(=)1882 3672 y FI(0)f(is)h(speci\002ed.)23 b(If)17 +b(no)f(\(currently)f(associated\))h(interrupt)f(is)j(pending,)322 +3772 y(the)24 b(current)e(thread)h(is)h(\(1\))f(detached)g(from)f(its)j +(currently)d(associated)h(interrupt)f(\(if)h(an)o(y\))g(and)g(\(2\))g +(associated)g(with)h(the)322 3871 y(speci\002ed)j(interrupt)e(pro)o +(vided)f(that)j(this)g(one)f(is)i(free,)g(i.e.)f(not)f(associated)g +(with)h(another)f(thread.)43 b(If)27 b(the)f(association)322 +3971 y(succeeds,)20 b(the)g(completion)f(code)g(is)i +Fs(r)m(eceive)g(timeout)e FI(\(0x20\))f(and)i(no)g(interrupt)f(is)i +(recei)n(v)o(ed.)447 4082 y(If)28 b(an)g(interrupt)e(from)h(the)h +(currently)e(associated)i(interrupt)e(w)o(as)j(pending,)f(this)g(one)f +(is)i(deli)n(v)o(ered)d(together)h(with)322 4181 y(completion)17 +b(code)i Fs(ok)f FI(\(0x00\);)g(the)g(interrupt)g(association)g(is)i +Fs(not)e FI(modi\002ed.)23 b(If)c(the)g(requested)e(ne)n(w)i(interrupt) +e(is)j(already)322 4281 y(associated)31 b(to)h(another)d(thread)h(or)h +(is)h(not)f(e)o(xisting,)i(completion)c(code)i Fs(non)f(e)n(xisting)h +FI(\(0x10\))e(is)j(deli)n(v)o(ered)d(and)i(the)322 4381 +y(interrupt)19 b(association)h(is)h(not)f(modi\002ed.)447 +4491 y(Getting)27 b(rid)g(of)g(an)g(associated)g(interrupt)f(without)h +(associating)g(a)g(ne)n(w)h(one)e(is)j(done)d(by)h(issuing)g(a)h(recei) +n(v)o(e)e(from)322 4591 y Fs(nilthr)m(ead)20 b FI(\(0\))f(with)h +Fs(r)m(cv)h(timeout)1324 4583 y Fx(=)1396 4591 y FI(0.)324 +4845 y Fe(S)t(L)t(E)t(E)t(P)p 2151 4854 V 2793 4854 V +2151 4954 V 2793 4954 V 2151 5053 V 2793 5053 V 2151 +5153 V 2202 5123 a Fd(\000)h FI(INT)e(0x30)p Fg(!)p 2793 +5153 V 1382 4824 a Fs(0xFFFFFFFF)97 b FF(EAX)p 2151 4854 +V 2793 4854 V 742 w(EAX)i Fy(cc)3174 4816 y Fx(=)3245 +4824 y Fu(0)p Fy(xA)p Fu(0)1585 4924 y Fs(timeouts)g +FF(ECX)p 2151 4954 V 2793 4954 V 746 w(ECX)k Fv(\030)1802 +5023 y(\030)c FF(EDX)p 2151 5053 V 2793 5053 V 742 w(EDX)g +Fv(\030)1802 5123 y(\030)g FF(EBX)p 2151 5153 V 2793 +5153 V 746 w(EBX)k Fv(\030)1825 5223 y Fs(0)c FF(EBP)p +2151 5253 V 2793 5253 V 757 w(EBP)114 b Fv(\030)1825 +5322 y Fs(0)99 b FF(ESI)p 2151 5352 V 2793 5352 V 779 +w(ESI)136 b Fv(\030)1802 5422 y(\030)99 b FF(EDI)p 2151 +5452 V 2793 5452 V 768 w(EDI)125 b Fv(\030)p eop +%%Page: 22 22 +22 21 bop 156 -290 a FI(22)3387 b FB(IPC)156 -57 y FI(This)20 +b(operation)d(includes)i(no)f(send)h(phase.)24 b(Since)c +Fy(nil)g FI(\(0\))f(is)h(speci\002ed)f(as)h(source,)e(no)h(message)g +(can)g(arri)n(v)o(e)f(and)h(the)g(ipc)156 43 y(will)i(be)f(terminated)f +(with)i(`recei)n(v)o(e)d(timeout')i(after)f(the)i(time)f(speci\002ed)g +(by)g(the)g Fs(r)m(cv-timeout)f FI(parameter)g(is)i(elapsed.)p +eop +%%Page: 23 23 +23 22 bop 322 -290 a FB(ID)p 415 -290 25 4 v 30 w(NEAREST)3025 +b FI(23)322 292 y Fh(id)p 451 292 44 4 v 52 w(near)m(est)p +2317 302 4 100 v 2975 302 V 2317 402 V 2975 402 V 2317 +502 V 2975 502 V 2317 601 V 2368 571 a Fg(\000)21 b FI(INT)f(0x31)p +Fg(!)p 2975 601 V 1968 272 a Fv(\030)99 b FF(EAX)p 2317 +302 V 2975 302 V 757 w(EAX)h Fs(type)1968 372 y Fv(\030)f +FF(ECX)p 2317 402 V 2975 402 V 761 w(ECX)104 b Fv(\030)1968 +472 y(\030)99 b FF(EDX)p 2317 502 V 2975 502 V 757 w(EDX)h +Fv(\030)1968 571 y(\030)f FF(EBX)p 2317 601 V 2975 601 +V 761 w(EBX)104 b Fv(\030)1968 671 y(\030)99 b FF(EBP)p +2317 701 V 2975 701 V 772 w(EBP)115 b Fv(\030)1814 771 +y Fs(dest)20 b(id)99 b FF(ESI)p 2317 800 V 2975 800 V +794 w(ESI)137 b Fs(near)m(est)20 b(id)1968 870 y Fv(\030)99 +b FF(EDI)p 2317 900 V 2975 900 V 783 w(EDI)126 b Fv(\030)322 +1131 y FI(If)21 b Fs(nil)g FI(is)h(speci\002ed)f(as)h(destination,)e +(the)h(system)g(call)g(deli)n(v)o(ers)f(the)h(uid)g(of)g(the)g(current) +e(thread.)27 b(Otherwise,)20 b(it)i(deli)n(v)o(eres)322 +1231 y(the)30 b(nearest)f(partner)f(which)h(w)o(ould)g(be)h(engaged)d +(when)i(sending)f(a)i(message)f(to)h(the)g(speci\002ed)f(destination.) +52 b(If)29 b(the)322 1331 y(destination)22 b(does)h(not)f(belong)f(to)i +(the)g(in)m(v)n(ok)o(er')-5 b(s)22 b(clan,)h(this)g(call)g(deli)n(v)o +(ers)f(the)h(chief)f(that)h(is)h(nearest)e(to)h(the)g(in)m(v)n(ok)o(er) +e(on)322 1430 y(the)g(path)e(from)h(the)g(in)m(v)n(ok)o(er)e(to)j(the)f +(destination.)447 1613 y Fv(\017)41 b FI(If)20 b(the)g(destination)f +(resides)i(outside)e(the)h(in)m(v)n(ok)o(er')-5 b(s)19 +b(clan,)h(it)h(deli)n(v)o(ers)e(the)i(in)m(v)n(ok)o(er')-5 +b(s)19 b(o)n(wn)g(chief.)447 1779 y Fv(\017)41 b FI(If)18 +b(the)f(destination)g(is)i(inside)e(a)h(clan)g(or)f(a)i(clan)e(nesting) +g(whose)h(chief)f Fy(C)24 b FI(is)19 b(direct)e(member)g(of)g(the)h(in) +m(v)n(ok)o(er')-5 b(s)16 b(clan,)530 1878 y(the)k(call)h(deli)n(v)o +(ers)e Fy(C)6 b FI(.)447 2045 y Fv(\017)41 b FI(If)20 +b(the)g(destination)f(is)j(a)e(direct)g(member)f(of)h(the)g(in)m(v)n +(ok)o(er')-5 b(s)19 b(clan,)h(the)g(call)g(deli)n(v)o(ers)g(the)g +(destination)f(itself.)447 2211 y Fv(\017)41 b FI(If)20 +b(the)g(destination)f(is)j Fs(nil)p FI(,)e(the)g(call)h(deli)n(v)o(ers) +e(the)h(current)f(thread')-5 b(s)19 b(id.)322 2393 y(Concluding:)31 +b(nchief)22 b(\()p Fs(dest)i(id)1272 2385 y Fn(6)p Fx(=)1347 +2393 y Fs(nil)p FI(\))f(deli)n(v)o(ers)g(e)o(xactly)g(that)h(partner)e +(to)i(which)f(the)g(k)o(ernel)g(w)o(ould)g(physically)f(send)i(a)322 +2493 y(message)c(which)f(is)h(tar)o(geted)f(to)g Fs(dest)h(id)p +FI(.)25 b(On)20 b(the)f(other)g(hand,)f(a)j(message)e(from)f +Fs(dest)i(id)g FI(w)o(ould)f(physically)f(come)h(from)322 +2592 y(e)o(xactly)h(this)g(partner)-5 b(.)322 2830 y +Ft(P)o(arameters)322 3020 y Fs(dest)21 b(id)1294 3019 +y FI(Id)f(of)g(the)g(destination.)322 3186 y Fs(type)1294 +3182 y FI(Note)g(that)g(the)g Fs(type)h FI(v)n(alues)e(correspond)f(e)o +(xactly)h(to)i(the)f(completion)e(codes)i(of)g(ipc.)945 +3274 y Fx(=)996 3282 y Fu(0)256 b FI(Destination)19 b(resides)i(in)f +(the)g(same)h(clan.)j Fs(dest)d(id)f FI(is)h(deli)n(v)o(ered)e(as)i +Fs(near)m(est)f(id)p FI(.)945 3373 y Fx(=)996 3381 y +Fy(C)239 b FI(Destination)16 b(is)h(in)f(an)h(inner)e(clan.)24 +b(The)16 b(chief)g(of)g(this)h(clan)f(or)g(clan)h(nesting)f(is)h(deli)n +(v)o(ered)1294 3481 y(as)k Fs(near)m(est)f(id)p FI(.)945 +3573 y Fx(=)996 3581 y Fu(4)256 b FI(Destination)27 b(is)i(outside)e +(the)h(in)m(v)n(ok)o(er')-5 b(s)27 b(clan.)48 b(The)27 +b(in)m(v)n(ok)o(er')-5 b(s)27 b(chief)g(is)i(deli)n(v)o(ered)d(as)1294 +3680 y Fs(near)m(est)20 b(id)p FI(.)322 3858 y Fs(near)m(est)h(id)1294 +3857 y FI(Either)e(the)i(current)e(thread')-5 b(s)19 +b(id)h(or)g(the)h(id)f(of)g(the)g(nearest)g(partner)f(to)n(w)o(ards)h +Fs(dest)g(id)p FI(.)p eop +%%Page: 24 24 +24 23 bop 156 -290 a FI(24)2935 b FB(FP)-8 b(A)m(GE)p +3432 -290 25 4 v 30 w(UNMAP)156 292 y Fh(fpage)p 501 +292 44 4 v 51 w(unmap)p 2151 330 4 100 v 2809 330 V 2151 +429 V 2809 429 V 2151 529 V 2809 529 V 2151 628 V 2202 +599 a Fg(\000)21 b FI(INT)f(0x32)p Fg(!)p 2809 628 V +1684 300 a Fs(fpa)o(g)o(e)98 b FF(EAX)p 2151 330 V 2809 +330 V 757 w(EAX)i Fv(\030)1532 399 y Fs(map)20 b(mask)99 +b FF(ECX)p 2151 429 V 2809 429 V 761 w(ECX)104 b Fv(\030)1802 +499 y(\030)99 b FF(EDX)p 2151 529 V 2809 529 V 757 w(EDX)h +Fv(\030)1802 599 y(\030)f FF(EBX)p 2151 628 V 2809 628 +V 761 w(EBX)104 b Fv(\030)1802 698 y(\030)99 b FF(EBP)p +2151 728 V 2809 728 V 772 w(EBP)115 b Fv(\030)1802 798 +y(\030)99 b FF(ESI)p 2151 828 V 2809 828 V 794 w(ESI)137 +b Fv(\030)1802 897 y(\030)99 b FF(EDI)p 2151 927 V 2809 +927 V 783 w(EDI)126 b Fv(\030)156 1158 y FI(The)19 b(speci\002ed)g +Fs(fpa)o(g)o(e)f FI(is)i(unmapped)c(in)j(all)h(address)e(spaces)i(into) +e(which)h(the)g(in)m(v)n(ok)o(er)e(mapped)g(it)j(directly)e(or)h +(indirectly)-5 b(.)156 1396 y Ft(P)o(arameters)156 1586 +y Fs(fpa)o(g)o(e)1128 1585 y FI(Fpage)19 b(to)i(be)f(unmapped.)156 +1764 y Fs(map)g(mask)p 1128 1693 67 4 v 1128 1859 4 167 +v 1141 1801 a Fp(f)p 1191 1859 V 1128 1862 67 4 v 1194 +1693 1927 4 v 1194 1859 4 167 v 901 w FF(0)2126 1815 +y Fr(\(29\))p 3117 1859 V 1194 1862 1927 4 v 3120 1693 +67 4 v 3120 1859 4 167 v 3128 1801 a Fp(w)p 3183 1859 +V 3120 1862 67 4 v 3187 1693 V 3187 1859 4 167 v 24 w +FF(0)p 3250 1859 V 3187 1862 67 4 v 779 1967 a Fy(w)840 +1959 y Fx(=)892 1967 y Fu(0)194 b FI(Fpage)20 b(will)h(partially)e +(unmapped.)k(Already)d(read/write)f(mapped)g(parts)h(will)h(be)g(set)g +(to)1128 2066 y(read)e(only)-5 b(.)24 b(Read)c(only)g(mapped)e(parts)j +(are)f(not)g(af)n(fected.)779 2166 y Fy(w)840 2158 y +Fx(=)892 2166 y Fu(1)194 b FI(Fpage)19 b(will)i(be)f(completely)f +(unmapped.)779 2291 y Fy(f)829 2283 y Fx(=)880 2291 y +Fu(0)206 b FI(Unmapping)28 b(happens)h(in)h(all)h(address)f(spaces)g +(into)g(which)g(pages)g(of)g(the)g(speci\002ed)1128 2390 +y(fpage)22 b(ha)n(v)o(e)h(been)f(mapped)g(directly)g(or)h(indirectly)-5 +b(.)33 b(The)23 b Fs(original)f FI(pages)h(in)g(the)h(o)n(wn)1128 +2490 y(task)c(remain)g(mapped.)779 2589 y Fy(f)829 2581 +y Fx(=)880 2589 y Fu(1)206 b FI(Additionally)-5 b(,)18 +b(also)i(the)g(original)f(pages)h(in)h(the)f(o)n(wn)f(task)i(are)f +(unmapped)e(\(\003ushing\).)p eop +%%Page: 25 25 +25 24 bop 322 -290 a FB(THREAD)p 664 -290 25 4 v 30 w(SWITCH)2832 +b FI(25)322 292 y Fh(thr)m(ead)p 736 292 44 4 v 51 w(switch)p +2317 302 4 100 v 2975 302 V 2317 402 V 2975 402 V 2317 +502 V 2975 502 V 2317 601 V 2368 571 a Fg(\000)21 b FI(INT)f(0x33)p +Fg(!)p 2975 601 V 1968 272 a Fv(\030)99 b FF(EAX)p 2317 +302 V 2975 302 V 757 w(EAX)h Fv(\030)1968 372 y(\030)f +FF(ECX)p 2317 402 V 2975 402 V 761 w(ECX)104 b Fv(\030)1968 +472 y(\030)99 b FF(EDX)p 2317 502 V 2975 502 V 757 w(EDX)h +Fv(\030)1968 571 y(\030)f FF(EBX)p 2317 601 V 2975 601 +V 761 w(EBX)104 b Fv(\030)1968 671 y(\030)99 b FF(EBP)p +2317 701 V 2975 701 V 772 w(EBP)115 b Fv(\030)1814 771 +y Fs(dest)20 b(id)99 b FF(ESI)p 2317 800 V 2975 800 V +794 w(ESI)137 b Fv(\030)1968 870 y(\030)99 b FF(EDI)p +2317 900 V 2975 900 V 783 w(EDI)126 b Fv(\030)322 1131 +y FI(The)20 b(in)m(v)n(oking)e(thread)i(releases)g(the)g(processor)f +(\(non-preemti)n(v)o(ely\))d(so)k(that)g(another)f(ready)g(thread)h +(can)g(be)g(processed.)322 1369 y Ft(P)o(arameters)322 +1533 y Fs(dest)h(id)945 1504 y Fx(=)996 1512 y Fy(nil)194 +b FI(\()1322 1504 y Fx(=)1372 1512 y Fu(0)p FI(\))19 +b(Processing)g(switches)h(to)f(an)g(unde\002ned)f(ready)g(thread)g +(which)h(is)h(selected)f(by)g(the)1294 1612 y(scheduler)-5 +b(.)31 b(\(It)23 b(might)f(be)g(the)h(in)m(v)n(oking)e(thread.\))31 +b(Since)22 b(this)h(is)h(\223ordinary\224)c(schedul-)1294 +1712 y(ing,)f(the)i(thread)e(gets)h(a)h(ne)n(w)f(timeslice.)945 +1803 y Fn(6)p Fx(=)996 1811 y Fy(nil)194 b FI(If)25 b +Fs(dest)h(id)g FI(is)h(ready)-5 b(,)25 b(processing)g(switches)h(to)g +(this)g(thread.)40 b(In)26 b(this)g(\223e)o(xtraordinary\224)1294 +1911 y(scheduling,)20 b(the)i(in)m(v)n(oking)e(thread)h(donates)h(its)h +(remaining)d(timeslice)i(to)h(the)f(destina-)1294 2011 +y(tion)h(thread.)33 b(\(This)23 b(one)f(gets)i(the)f(donation)e +(additionally)h(to)h(its)h(ordinary)e(scheduled)1294 +2110 y(timeslices.\))1294 2210 y(If)g(the)h(destination)e(thread)h(is)h +(not)g(ready)-5 b(,)21 b(the)i(system)f(call)h(operates)f(as)h +(described)f(for)1294 2309 y Fs(dest)e(id)1534 2301 y +Fx(=)1585 2309 y Fy(nil)r FI(.)p eop +%%Page: 26 26 +26 25 bop 156 -290 a FI(26)2716 b FB(THREAD)p 3298 -290 +25 4 v 30 w(SCHEDULE)156 353 y Fh(thr)m(ead)p 570 353 +44 4 v 51 w(schedule)p 2151 363 4 100 v 2809 363 V 2151 +463 V 2809 463 V 2151 562 V 2809 562 V 2151 662 V 2202 +632 a Fg(\000)21 b FI(INT)f(0x34)p Fg(!)p 2809 662 V +1463 333 a Fs(par)o(am)f(wor)m(d)99 b FF(EAX)p 2151 363 +V 2809 363 V 757 w(EAX)h Fs(old)19 b(par)o(am)h(wor)m(d)1802 +433 y Fv(\030)99 b FF(ECX)p 2151 463 V 2809 463 V 761 +w(ECX)104 b Fs(time)o(.low)1802 532 y Fv(\030)99 b FF(EDX)p +2151 562 V 2809 562 V 757 w(EDX)h Fs(time)o(.high)1413 +632 y(e)n(xt)21 b(pr)m(eempter)98 b FF(EBX)p 2151 662 +V 2809 662 V 761 w(EBX)104 b Fs(old)19 b(pr)m(eempter)1802 +732 y Fv(\030)99 b FF(EBP)p 2151 761 V 2809 761 V 772 +w(EBP)115 b Fv(\030)1648 831 y Fs(dest)20 b(id)99 b FF(ESI)p +2151 861 V 2809 861 V 794 w(ESI)137 b Fs(partner)1802 +931 y Fv(\030)99 b FF(EDI)p 2151 961 V 2809 961 V 783 +w(EDI)126 b Fv(\030)156 1252 y FI(The)23 b(system)g(call)g(can)g(be)f +(used)h(by)f(schedulers)g(to)h(de\002ne)f(the)h Fs(priority)p +FI(,)g Fs(timeslice)h(length)e FI(and)g Fs(e)n(xternal)h(pr)m(eempter)f +FI(of)156 1352 y(other)17 b(threads.)23 b(Furthermore,)15 +b(it)j(deli)n(v)o(ers)e(thread)h(states.)25 b(Note)17 +b(that)g(due)g(to)g(security)f(reasons)h(thread)f(state)i(information) +156 1452 y(must)j(be)f(retrie)n(v)o(ed)e(through)g(the)i(appropriate)e +(scheduler)-5 b(.)281 1612 y(The)24 b(system)g(call)h(is)g(only)f(ef)n +(fecti)n(v)o(e,)g(if)g(the)g(current)f(priority)g(of)h(the)h +(speci\002ed)f(destination)f(is)i(less)h(or)e(equal)f(than)156 +1711 y(the)e(current)d(task')-5 b(s)21 b Fs(maximum)f(contr)l(olled)f +(priority)i(\(mcp\))p FI(.)156 2282 y Ft(P)o(arameters)156 +2561 y Fs(dest)g(id)1128 2541 y FI(Destination)j(thread)g(id.)40 +b(The)25 b(destination)f(thread)g(must)h(currently)e(e)o(xist)j(and)e +(run)g(on)1128 2640 y(a)i(priority)e(le)n(v)o(el)h(less)i(than)e(or)g +(equal)g(to)h(the)f(current)g(thread')-5 b(s)25 b Fs(mcp)p +FI(.)41 b(Otherwise,)26 b(the)1128 2740 y(destination)d(thread)h(is)h +(not)f(af)n(fected)f(by)h(this)h(system)g(call)g(and)f(all)h(result)f +(parameters)1128 2840 y(e)o(xcept)19 b Fs(old)h(par)o(am)f(wor)m(d)h +FI(are)h(unde\002ned.)156 3078 y Fs(par)o(am)f(wor)m(d)779 +3115 y FI(v)n(alid)p 1128 3007 532 4 v 1128 3173 4 167 +v 355 w Fp(m)1361 3123 y Fk(t)1406 3129 y Fr(\(8\))p +1656 3173 V 1128 3176 532 4 v 1659 3007 266 4 v 1659 +3173 4 167 v 1712 3115 a Fp(e)1745 3123 y Fk(t)1789 3129 +y Fr(\(4\))p 1921 3173 V 1659 3176 266 4 v 1925 3007 +V 1925 3173 4 167 v 1991 3115 a FF(0)2041 3129 y Fr(\(4\))p +2187 3173 V 1925 3176 266 4 v 2190 3007 532 4 v 2190 +3173 4 167 v 2335 3115 a FF(small)2495 3129 y Fr(\(8\))p +2718 3173 V 2190 3176 532 4 v 2722 3007 V 2722 3173 4 +167 v 2884 3115 a FF(prio)3008 3129 y Fr(\(8\))p 3250 +3173 V 2722 3176 532 4 v 779 3314 a Fs(prio)210 b FI(Ne)n(w)34 +b(priority)e(for)i(destination)e(thread.)65 b(Must)34 +b(be)g(less)h(than)f(or)f(equal)g(to)h(current)1128 3414 +y(thread')-5 b(s)19 b Fs(mcp)p FI(.)779 3555 y Fs(small)169 +b FI(\(Only)31 b(ef)n(fecti)n(v)o(e)g(for)g(Pentium.\))59 +b(Sets)33 b(the)f Fs(small)h(addr)m(ess)f(space)f(number)h +FI(for)f(the)1128 3655 y(addressed)f Fs(task)p FI(.)60 +b(On)32 b(Pentium,)h(small)g(address)e(spaces)h(from)e(1)i(to)g(127)f +(currently)1128 3754 y(a)n(v)n(ailable.)h(A)24 b(v)n(alue)e(of)g(0)h +(or)g(255)f(in)h(this)g(\002eld)g(does)g(not)f(change)g(the)h(current)e +(setting)1128 3854 y(for)e(the)i(task.)k(This)20 b(\002eld)g(is)i +(currently)c(ignored)g(for)i(486)f(and)h(PPro.)779 3995 +y Fy(m)852 4007 y Fq(t)881 3995 y Fy(;)14 b(e)957 4007 +y Fq(t)1128 3995 y FI(Ne)n(w)23 b(timeslice)g(length)g(for)f(the)h +(destination)f(thread.)32 b(The)23 b(timeslice)g(quantum)f(is)h(en-) +1128 4095 y(coded)c(lik)o(e)h(a)h(timeout:)j Fu(4)1893 +4065 y Fx(15)p Fn(\000)p Fq(e)2042 4073 y Fi(t)2074 4095 +y Fy(m)2147 4107 y Fq(t)2197 4095 y Fy(\026s)p FI(.)1128 +4194 y(The)h(k)o(ernel)f(rounds)g(this)i(v)n(alue)f(up)g(to)n(w)o(ards) +g(the)g(nearest)g(possible)g(v)n(alue.)40 b(Thus)25 b(the)1128 +4294 y(timeslice)f(granularity)f(can)h(be)g(determined)f(by)g(trying)h +(to)g(set)h(the)g(timeslice)f(to)h(1)f Fy(\026)p FI(s.)1128 +4394 y(Ho)n(we)n(v)o(er)18 b(note)i(that)g(the)h(timeslice)f +(granularity)e(may)i(depend)e(on)i(the)g(priority)-5 +b(.)1128 4493 y(T)m(imeslice)19 b(length)g(0)h(\()p Fy(m)1863 +4505 y Fq(t)1905 4485 y Fx(=)1970 4493 y Fu(0)p Fy(;)14 +b(e)2088 4505 y Fq(t)2130 4485 y Fn(6)p Fx(=)2195 4493 +y Fu(0)p FI(\))19 b(is)i(al)o(w)o(ays)f(a)g(possible)f(v)n(alue.)24 +b(It)c(means)f(that)h(the)1128 4593 y(thread)g(will)i(get)f(no)f +(ordinary)f(timeslice,)i(i.e.)28 b(is)22 b(block)o(ed.)k(Ho)n(we)n(v)o +(er)m(,)19 b(e)n(v)o(en)h(a)h(block)o(ed)1128 4693 y(thread)e(may)h(e)o +(x)o(ecute)f(in)h(a)g(timeslice)h(donated)e(to)h(it)h(by)f(ipc.)779 +4859 y Fs(\223in)m(v\224)158 b FI(\(0xFFFFFFFF\))28 b(The)g(current)f +(priority)g(and)g(timeslice)i(length)e(of)h(the)g(thread)f(is)i(not) +1128 4958 y(modi\002ed.)156 5186 y Fs(e)n(xt)21 b(pr)m(eempter)779 +5181 y FI(v)n(alid)184 b(De\002nes)22 b(the)g(e)o(xternal)f(preempter)f +(for)i(the)g(destination)f(thread.)29 b(\(Nilthread)21 +b(is)i(a)g(v)n(alid)1128 5281 y(id.\))779 5422 y Fs(\223in)m(v\224)158 +b FI(\(0xFFFFFFFF)-7 b(,)p Fv(\030)p FI(\))20 b(The)g(current)f(e)o +(xternal)f(preempter)h(of)h(the)g(thread)f(is)i(not)f(changed.)p +eop +%%Page: 27 27 +27 26 bop 322 -290 a FB(THREAD)p 664 -290 25 4 v 30 w(SCHEDULE)2716 +b FI(27)322 -83 y Fs(old)20 b(par)o(am)g(wor)m(d)945 +-46 y FI(v)n(alid)p 1349 -154 532 4 v 1349 12 4 167 v +410 w Fp(m)1582 -38 y Fk(t)1627 -32 y Fr(\(8\))p 1877 +12 V 1349 15 532 4 v 1880 -154 266 4 v 1880 12 4 167 +v 1933 -46 a Fp(e)1966 -38 y Fk(t)2011 -32 y Fr(\(4\))p +2143 12 V 1880 15 266 4 v 2146 -154 V 2146 12 4 167 v +2200 -46 a Fp(ts)2275 -32 y Fr(\(4\))p 2408 12 V 2146 +15 266 4 v 2412 -154 532 4 v 2412 12 4 167 v 2600 -46 +a FE(\030)2672 -32 y Fr(\(8\))p 2940 12 V 2412 15 532 +4 v 2943 -154 V 2943 12 4 167 v 3106 -46 a FF(prio)3229 +-32 y Fr(\(8\))p 3471 12 V 2943 15 532 4 v 945 153 a +Fs(prio)265 b FI(Old)20 b(priority)f(of)h(destination)f(thread.)945 +295 y Fy(m)1018 307 y Fq(t)1047 295 y Fy(;)14 b(e)1123 +307 y Fq(t)1349 295 y FI(Old)20 b(timeslice)h(length)e(of)h(the)g +(destination)f(thread:)25 b Fu(4)2939 264 y Fx(15)p Fn(\000)p +Fq(e)3088 272 y Fi(t)3120 295 y Fy(m)3193 307 y Fq(t)3242 +295 y Fy(\026s)p FI(.)945 436 y Fy(ts)1035 428 y Fx(=)1349 +436 y FI(Thread)19 b(state:)1028 535 y Fu(0)f(+)g Fy(k)135 +b Fs(Running)o(.)23 b FI(The)d(thread)f(is)i(ready)e(to)h(e)o(x)o +(ecute)f(at)i(user)n(-le)n(v)o(el.)1028 635 y Fu(4)d(+)g +Fy(k)135 b Fs(Sending)o(.)54 b FI(A)30 b(user)n(-in)m(v)n(ok)o(ed)e +(ipc)j(send)f(operation)f(currently)f(transfers)i(an)h(outgoing)1349 +735 y(message.)1028 834 y Fu(8)18 b(+)g Fy(k)135 b Fs(Receiving)o(.)30 +b FI(A)23 b(user)n(-in)m(v)n(ok)o(ed)c(ipc)k(recei)n(v)o(e)e(operation) +f(currently)h(recei)n(v)o(es)g(an)i(imcom-)1349 934 y(ing)d(message.) +1028 1034 y(C)266 b Fs(W)-8 b(aiting)18 b FI(for)f(recei)n(v)o(e.)23 +b(A)18 b(user)n(-in)m(v)n(ok)o(ed)d(ipc)j(recei)n(v)o(e)f(operation)f +(currently)g(w)o(aits)i(for)f(an)1349 1133 y(incoming)h(message.)1028 +1233 y(D)261 b Fs(P)-7 b(ending)20 b FI(send.)29 b(A)22 +b(user)n(-in)m(v)n(ok)o(ed)d(ipc)j(send)f(operation)f(currently)f(w)o +(aits)k(for)e(the)g(desti-)1349 1332 y(nation)e(\(recipient\))g(to)h +(become)f(ready)g(to)i(recei)n(v)o(e.)1028 1432 y(E)270 +b(Reserv)o(ed.)1028 1532 y(F)275 b Fs(Dead.)24 b FI(The)c(thread)f(is)j +(unable)d(to)h(e)o(x)o(ecute.)1070 1698 y Fy(k)1136 1690 +y Fx(=)1208 1698 y FI(0)99 b Fs(K)m(ernel)21 b(inactive)o(.)j +FI(The)c(k)o(ernel)f(does)h(not)g(e)o(x)o(ecute)f(an)h(automatic)f(RPC) +j(for)d(the)i(thread.)1208 1797 y(1)99 b Fs(P)-7 b(a)o(g)o(er)p +FI(.)25 b(The)20 b(k)o(ernel)f(e)o(x)o(ecutes)h(a)g(pagef)o(ault)f(RPC) +j(to)e(the)g(thread')-5 b(s)20 b(pager)-5 b(.)1208 1897 +y(2)99 b Fs(Internal)23 b(pr)m(eempter)-9 b(.)33 b FI(The)23 +b(k)o(ernel)g(e)o(x)o(ecutes)f(a)i(preemption)d(RPC)k(to)e(the)h +(thread')-5 b(s)23 b(in-)1349 1997 y(ternal)d(preempter)-5 +b(.)1208 2096 y(3)99 b Fs(External)31 b(pr)m(eempter)-9 +b(.)58 b FI(The)32 b(k)o(ernel)e(e)o(x)o(ecutes)h(a)h(preemption)d(RPC) +k(to)e(the)h(thread')-5 b(s)1349 2196 y(e)o(xternal)19 +b(preempter)-5 b(.)945 2362 y Fs(\223in)m(v\224)213 b +FI(\(0xFFFFFFFF\))33 b(The)f(addressed)f(thread)h(does)g(either)g(not)g +(e)o(xist)h(or)f(has)h(a)g(priority)1349 2461 y(which)21 +b(e)o(xceeds)g(the)g(current)g(thread')-5 b(s)21 b Fs(mcp)p +FI(.)29 b(All)22 b(other)f(return)f(parameters)g(are)i(unde-)1349 +2561 y(\002ned)e(\()p Fv(\030)p FI(\).)322 2739 y Fs(old)g(e)n(xt)h(pr) +m(eempter)1294 2738 y FI(Old)f(e)o(xternal)f(preempter)f(of)i(the)g +(destination)g(thread.)322 2905 y Fs(partner)1294 2901 +y FI(P)o(artner)k(of)g(an)h(acti)n(v)o(e)f(user)n(-in)m(v)n(ok)o(ed)f +(ipc)i(operation.)37 b(This)25 b(parameter)e(is)j(only)e(v)n(alid,)1294 +3000 y(if)e(the)h(thread')-5 b(s)21 b(user)h(state)h(is)g +Fs(sending)o(,)f(r)m(eceiving)o(,)g(pending)e FI(or)i +Fs(waiting)g FI(\(4.)12 b(.)g(.)g(D\).)22 b(An)1294 3100 +y(in)m(v)n(alid)j(thread)h(id)g(\(0xFFFFFFFF)-7 b(,)p +Fv(\030)p FI(\))27 b(is)g(deli)n(v)o(ered)e(if)i(there)f(is)h(no)f +(speci\002c)h(partner)m(,)1294 3200 y(i.e.)20 b(if)g(the)h(thread)e(is) +i(in)f(an)h(open)e(recei)n(v)o(e)g(state.)322 3375 y +Fs(time)p 1301 3288 V 1301 3454 4 167 v 1461 3396 a Fp(m)1523 +3404 y Fk(w)1590 3410 y Fr(\(8\))p 1829 3454 V 1301 3457 +532 4 v 1832 3288 266 4 v 1832 3454 4 167 v 1874 3396 +a Fp(e)1907 3404 y Fk(w)1973 3410 y Fr(\(4\))p 2094 3454 +V 1832 3457 266 4 v 2098 3288 V 2098 3454 4 167 v 2146 +3396 a Fp(e)2179 3404 y Fk(p)2232 3410 y Fr(\(4\))p 2360 +3454 V 2098 3457 266 4 v 2363 3288 1063 4 v 2363 3454 +4 167 v 2744 3396 a Fp(T)2785 3408 y Fk(hig)r(h)2932 +3410 y Fr(\(16\))p 3423 3454 V 2363 3457 1063 4 v 3509 +3396 a FI(EDX)p 1301 3461 2126 4 v 1301 3627 4 167 v +2228 3569 a Fp(T)2269 3581 y Fk(low)2386 3583 y Fr(\(32\))p +3423 3627 V 1301 3630 2126 4 v 3509 3569 a FI(ECX)945 +3735 y Fy(T)307 b FI(Cpu)19 b(time)g(\(48-bit)f(v)n(alue\))g(in)h +(microseconds)e(which)h(has)i(been)e(consumed)f(by)i(the)g(des-)1301 +3834 y(tination)g(thread.)945 4000 y Fy(m)1018 4012 y +Fq(w)1072 4000 y Fy(;)14 b(e)1148 4012 y Fq(w)1301 4000 +y FI(Current)28 b(user)n(-le)n(v)o(el)g(w)o(ak)o(eup)f(of)i(the)g +(destination)f(thread,)h(encoded)f(lik)o(e)h(a)g(timeout.)1301 +4100 y(The)d(v)n(alue)f(denotes)h(the)h(still)g(remaining)e(timeout)g +(interv)n(al.)43 b(V)-9 b(alid)26 b(only)g(if)h(the)f(user)1301 +4200 y(state)21 b(is)g Fs(waiting)f FI(\(C\))g(or)g Fs(pending)e +FI(\(D\).)945 4366 y Fy(e)984 4378 y Fq(p)1301 4366 y +FI(Ef)n(fecti)n(v)o(e)e(pagef)o(ault)g(w)o(ak)o(eup)g(of)h(the)h +(destination)e(thread,)h(encoded)f(lik)o(e)h(a)h(4-bit)f(page-)1301 +4465 y(f)o(ault)f(timeout.)24 b(The)16 b(v)n(alue)g(denotes)g(the)h +(still)h(remaining)d(timeout)h(interv)n(al.)23 b(V)-9 +b(alid)17 b(only)1301 4565 y(if)j(the)g(k)o(ernel)g(state)h(is)g +Fs(pa)o(g)o(er)f FI(\()p Fy(k)2271 4557 y Fx(=)2336 4565 +y Fu(1)p FI(\).)p eop +%%Page: 28 28 +28 27 bop 156 -290 a FI(28)2754 b FB(L)-8 b(THREAD)p +3379 -290 25 4 v 30 w(EX)p 3520 -290 V 29 w(REGS)156 +310 y Fh(lthr)m(ead)p 610 310 44 4 v 51 w(ex)p 797 310 +V 51 w(r)m(egs)p 2151 347 4 100 v 2809 347 V 2151 447 +V 2809 447 V 2151 547 V 2809 547 V 2151 646 V 2202 616 +a Fg(\000)21 b FI(INT)f(0x35)p Fg(!)p 2809 646 V 1526 +318 a Fs(lthr)m(ead)g(no)98 b FF(EAX)p 2151 347 V 2809 +347 V 757 w(EAX)i Fs(old)19 b(EFLA)m(GS)1724 417 y(ESP)98 +b FF(ECX)p 2151 447 V 2809 447 V 761 w(ECX)104 b Fs(old)19 +b(ESP)1738 517 y(EIP)98 b FF(EDX)p 2151 547 V 2809 547 +V 757 w(EDX)i Fs(old)19 b(EIP)1420 616 y(int)i(pr)m(eempter)98 +b FF(EBX)p 2151 646 V 2809 646 V 761 w(EBX)104 b Fs(old)19 +b(pr)m(eempter)1802 716 y Fv(\030)99 b FF(EBP)p 2151 +746 V 2809 746 V 772 w(EBP)115 b Fv(\030)1675 816 y Fs(pa)o(g)o(er)98 +b FF(ESI)p 2151 846 V 2809 846 V 794 w(ESI)137 b Fs(old)19 +b(pa)o(g)o(er)1802 915 y Fv(\030)99 b FF(EDI)p 2151 945 +V 2809 945 V 783 w(EDI)126 b Fv(\030)156 1194 y FI(This)21 +b(function)d(reads)i(and)g(writes)g(some)g(re)o(gister)g(v)n(alues)g +(of)g(a)g(thread)g(in)g(the)g(current)f(task.)281 1312 +y(It)i(also)f(creates)h(threads.)j(Conceptually)-5 b(,)18 +b(creating)i(a)g(task)h(includes)f(creating)f(all)i(of)f(its)h +(threads.)k(Except)20 b(lthread)f(0,)156 1411 y(all)25 +b(these)f(threads)g(run)f(an)h(idle)g(loop.)35 b(Of)25 +b(course,)e(the)i(k)o(ernel)e(does)g(neither)h(allocate)f(control)g +(blocks)g(nor)h(time)g(slices)156 1511 y(etc.)h(to)g(them.)37 +b(Setting)24 b(stack)h(and)f(instruction)f(pointer)g(of)h(such)g(a)h +(thread)f(to)g(v)n(alid)g(v)n(alues)g(then)g(really)g(generates)g(the) +156 1610 y(thread.)281 1728 y(Note)17 b(that)h(this)g(operation)d +(reads)i(and)g(writes)h(the)g Fs(user)n(-le)o(vel)f FI(re)o(gisters)g +(\(ESP)-9 b(,)17 b(EIP)h(and)f(EFLA)m(GS\).)f(Ongoing)g(k)o(ernel)156 +1828 y(acti)n(vities)26 b(are)f(not)g(af)n(fected.)39 +b(Ho)n(we)n(v)o(er)23 b(an)i(ipc)g(operation)f(is)i(cancelled)e(or)h +(aborted.)38 b(If)26 b(the)f(ipc)g(is)h(either)f(w)o(aiting)g(to)156 +1927 y(send)g(a)g(message)g(or)g(w)o(aiting)g(to)g(recei)n(v)o(e)f(a)h +(message,)h(i.e.)f(a)g(message)g(transfer)f(is)i(not)e(yet)h(running,)f +(ipc)h(is)h(cancelled)156 2027 y(\(completion)20 b(code)h(0x40)g(or)g +(0x50\).)28 b(If)22 b(a)g(message)g(transfer)f(is)i(currently)d +(running,)g(ipc)i(is)h(aborted)d(\(completion)g(code)156 +2126 y(0xC0)g(or)g(0xD0\).)156 2462 y Ft(P)o(arameters)156 +2660 y Fs(lthr)m(ead)g(no)p 1128 2574 67 4 v 1128 2740 +4 167 v 1144 2681 a Fp(v)p 1191 2740 V 1128 2743 67 4 +v 1194 2574 1595 4 v 1194 2740 4 167 v 732 w FF(0)1960 +2695 y Fr(\(24\))p 2785 2740 V 1194 2743 1595 4 v 2788 +2574 465 4 v 2788 2740 4 167 v 2879 2681 a FF(lthread)3080 +2695 y Fr(\(7\))p 3250 2740 V 2788 2743 465 4 v 1128 +2848 a FI(Number)f(of)g(addressed)h(lthread)f(\(0.)12 +b(.)g(.)g(127\))19 b(inside)h(the)g(current)f(task.)779 +3014 y Fy(v)836 3006 y Fx(=)901 3014 y Fu(0)185 b FI(If)24 +b(ESP)g(and)g(EIP)g(are)g(v)n(alid,)g(the)o(y)f(specify)g(32-bit)g +(protected-mode)e(v)n(alues.)36 b(The)23 b(ad-)1128 3113 +y(dressed)c(thread)h(will)h(e)o(x)o(ecute)d(in)j(32-bit)e(protected)g +(mode)g(afterw)o(ards.)779 3254 y Fy(v)836 3246 y Fx(=)901 +3254 y Fu(1)185 b FI(If)20 b(ESP)g(and)g(EIP)g(are)g(v)n(alid,)f(the)o +(y)h(specify)f(16-bit)g(V86-mode)f(v)n(alues.)24 b(The)c(addressed)1128 +3354 y(thread)f(will)i(e)o(x)o(ecute)e(in)h(V86)g(mode)f(afterw)o +(ards.)779 3520 y Fy(u)841 3512 y Fx(=)905 3520 y Fu(0)181 +b FI(The)20 b(thread')-5 b(s)19 b Fs(auto-pr)l(opa)o(gating)d +FI(status)21 b(is)g(not)f(updated.)779 3661 y Fy(u)841 +3653 y Fx(=)905 3661 y Fu(1)181 b FI(The)20 b(thread')-5 +b(s)19 b Fs(auto-pr)l(opa)o(gating)d FI(status)21 b(is)g(updated)e(by)h +Fy(a)p FI(.)779 3827 y Fy(a)837 3819 y Fx(=)902 3827 +y Fu(0)184 b FI(If)20 b Fy(u)1266 3819 y Fx(=)1330 3827 +y Fu(1)p FI(,)g(the)g(thread)f(is)j(set)f(to)f Fs(non)f(auto-pr)l(opa)o +(gating)p FI(.)779 3968 y Fy(a)837 3960 y Fx(=)902 3968 +y Fu(1)184 b FI(If)20 b Fy(u)1266 3960 y Fx(=)1330 3968 +y Fu(1)p FI(,)g(the)g(thread)f(is)j(set)f(to)f Fs(auto-pr)l(opa)o +(gating)p FI(.)156 4163 y Fs(ESP)779 4143 y FI(v)n(alid)184 +b(Ne)n(w)24 b(stack)g(pointer)e(\(ESP\))i(for)f(the)h(thread.)34 +b(It)25 b(must)e(point)g(into)h(the)g(user)n(-accessible)1128 +4243 y(part)c(of)g(the)g(address)f(space.)779 4384 y +Fs(\223in)m(v\224)158 b FI(\(0xFFFFFFFF\))20 b(The)g(e)o(xisting)f +(stack)i(pointer)e(is)i(not)f(modi\002ed.)156 4577 y +Fs(EIP)779 4556 y FI(v)n(alid)184 b(Ne)n(w)36 b(instruction)f(pointer)f +(\(EIP\))i(for)f(the)h(thread.)71 b(It)36 b(must)g(point)g(into)f(the)h +(user)n(-)1128 4655 y(accessible)20 b(part)g(of)g(the)g(address)g +(space.)779 4796 y Fs(\223in)m(v\224)158 b FI(\(0xFFFFFFFF\))20 +b(The)g(e)o(xisting)f(instruction)g(pointer)g(is)i(not)f(modi\002ed.) +156 4990 y Fs(int)h(pr)m(eempter)779 4986 y FI(v)n(alid)184 +b(De\002nes)20 b(the)g(internal)g(preempter)e(used)i(by)g(the)g +(thread.)k(\()p Fs(Nil)d FI(is)g(a)g(v)n(alid)e(id.\))779 +5118 y Fs(\223in)m(v\224)158 b FI(\(0xFFFFFFFF)-7 b(,)p +Fv(\030)p FI(\))20 b(The)g(e)o(xisting)f(internal)g(preempter)g(id)h +(is)h(not)f(modi\002ed.)156 5294 y Fs(pa)o(g)o(er)779 +5289 y FI(v)n(alid)184 b(De\002nes)20 b(the)g(pager)f(used)h(by)g(the)g +(thread.)779 5422 y Fs(\223in)m(v\224)158 b FI(\(0xFFFFFFFF)-7 +b(,)p Fv(\030)p FI(\))20 b(The)g(e)o(xisting)f(pager)g(id)i(is)g(not)f +(modi\002ed.)p eop +%%Page: 29 29 +29 28 bop 322 -290 a FB(L)-8 b(THREAD)p 707 -290 25 4 +v 30 w(EX)p 848 -290 V 30 w(REGS)2754 b FI(29)322 -83 +y Fs(old)20 b(EFLA)m(GS)1294 -103 y FI(Flags)h(of)f(the)h(thread.)k +(The)c Fs(VM)g FI(\003ag)g(speci\002es)g(whether)e(the)i(thread)f +(currently)f(runs)h(in)1294 -3 y(32-bit)j(protected)f(mode)i(\()p +Fs(VM)2222 -11 y Fx(=)2286 -3 y Fu(0)p FI(\))g(or)f(in)i(V86)e(mode)g +(\()p Fs(VM)3101 -11 y Fx(=)3166 -3 y Fu(1)p FI(\).)36 +b(Note)24 b(that)g(this)h(\003ag)1294 96 y(determines)19 +b(the)h(format)f(of)h(the)g(deli)n(v)o(ered)f(old)g(ESP)i(and)f(EIP)-9 +b(.)322 274 y Fs(old)20 b(ESP)1294 273 y FI(Old)g(stack)g(pointer)f +(\(ESP\))h(of)g(the)h(thread.)322 457 y Fs(old)f(ESP)1294 +456 y FI(Old)g(instruction)f(pointer)g(\(EIP\))h(of)f(the)i(thread.)322 +640 y Fs(old)f(int)h(pr)m(eempter)1294 639 y FI(Id)f(of)g(the)g +(thread')-5 b(s)19 b(old)h(internal)g(preempter)e(\(may)h(be)h +(nilthread\).)322 822 y Fs(old)g(pa)o(g)o(er)1294 821 +y FI(Id)g(of)g(the)g(thread')-5 b(s)19 b(old)h(pager)-5 +b(.)322 1274 y Ft(V86-mode)26 b(P)n(ointers)322 1682 +y Fs(ESP)-11 b(,)20 b(old)g(ESP)p 1294 1605 1063 4 v +1294 1771 4 167 v 1723 1713 a FF(SS)1814 1727 y Fr(\(16\))p +2353 1771 V 1294 1774 1063 4 v 2356 1605 V 2356 1771 +4 167 v 2786 1713 a FF(SP)2877 1727 y Fr(\(16\))p 3416 +1771 V 2356 1774 1063 4 v 322 1922 a Fs(EIP)-11 b(,)20 +b(old)g(EIP)p 1294 1845 V 1294 2011 4 167 v 1720 1953 +a FF(CS)1818 1967 y Fr(\(16\))p 2353 2011 V 1294 2014 +1063 4 v 2356 1845 V 2356 2011 4 167 v 2793 1953 a FF(IP)2869 +1967 y Fr(\(16\))p 3416 2011 V 2356 2014 1063 4 v 322 +2585 a Ft(Example)322 2741 y FI(Signalling)g(can)g(be)g(implemented)e +(as)j(follo)n(ws:)442 2936 y(signal)f(\(lthread\))f(:)562 +3036 y(esp)i(:=)f(recei)n(v)o(e)f(signal)h(stack)h(;)562 +3135 y(eip)f(:=)h(recei)n(v)o(e)e(signal)h(;)562 3235 +y(mem)g([esp)g(\226)g(\226])g(:=)h(0)f(;)562 3335 y(lthread)g(e)o(x)f +(re)o(gs)h(\(lthread,)f(esp,)h(eip,)g(e\003ags,)g(\226,)g(\226\))g(;) +562 3434 y(mem)g([esp)g(\226)g(\226])g(:=)h(e\003ags)f(;)562 +3534 y(mem)g([esp)g(\226)g(\226])g(:=)h(eip)f(;)562 3634 +y(mem)g([idle)g(stack)g(\226)h(w)o(ordlength])c(:=)k(esp)f(.)442 +3841 y(recei)n(v)o(e)f(signal)i(:)562 3941 y(push)f(all)h(re)o(gs)e(;) +562 4040 y Fz(while)i FI(mem)f([esp)g(+)h(8)f Fv(\002)g +FI(w)o(ordlength])e(=)i(0)h Fz(do)682 4140 y FI(thread)e(switch)i +(\(nilthread\))562 4240 y Fz(od)g FI(;)562 4339 y(pop)e(all)i(re)o(gs)f +(;)562 4439 y(pop)f(\(esp\))h(;)562 4538 y(jmp)g(\(signal)g(eip\))g(.)p +eop +%%Page: 30 30 +30 29 bop 156 -290 a FI(30)3088 b FB(T)-8 b(ASK)p 3542 +-290 25 4 v 30 w(NEW)156 324 y Fh(task)p 421 324 44 4 +v 51 w(new)p 2151 335 4 100 v 2809 335 V 2151 434 V 2809 +434 V 2151 534 V 2809 534 V 2151 634 V 2202 604 a Fg(\000)21 +b FI(INT)f(0x36)p Fg(!)p 2809 634 V 1350 305 a Fs(mcp)g(/)h(ne)o(w)g(c) +o(hief)98 b FF(EAX)p 2151 335 V 2809 335 V 757 w(EAX)i +Fv(\030)1505 404 y Fs(initial)20 b(ESP)98 b FF(ECX)p +2151 434 V 2809 434 V 761 w(ECX)104 b Fv(\030)1518 504 +y Fs(initial)21 b(EIP)98 b FF(EDX)p 2151 534 V 2809 534 +V 757 w(EDX)i Fv(\030)1675 604 y Fs(pa)o(g)o(er)e FF(EBX)p +2151 634 V 2809 634 V 761 w(EBX)104 b Fv(\030)1802 703 +y(\030)99 b FF(EBP)p 2151 733 V 2809 733 V 772 w(EBP)115 +b Fv(\030)1578 803 y Fs(dest)21 b(task)99 b FF(ESI)p +2151 833 V 2809 833 V 794 w(ESI)137 b Fs(ne)o(w)20 b(task)1802 +902 y Fv(\030)99 b FF(EDI)p 2151 932 V 2809 932 V 783 +w(EDI)126 b Fv(\030)156 1196 y FI(This)25 b(function)e(deletes)h +(and/or)g(creates)g(a)h(task.)38 b(Deletion)24 b(of)g(a)h(task)g(means) +f(that)h(the)f(address)h(space)f(of)g(the)h(task)g(and)156 +1295 y(all)g(threads)f(of)g(the)g(task)h(disappear)-5 +b(.)36 b(The)24 b(cputime)f(of)h(all)h(deleted)f(threads)f(is)j(added)d +(to)h(the)g(cputime)g(of)g(the)g(deleting)156 1395 y(thread.)g(If)c +(the)h(deleted)e(task)i(w)o(as)g(chief)e(of)h(a)h(clan,)f(all)h(tasks)f +(of)g(the)g(clan)g(are)h(deleted)e(as)i(well.)281 1527 +y(T)-7 b(asks)26 b(may)g(be)f(created)g(as)i Fs(active)e +FI(or)h Fs(inactive)p FI(.)41 b(F)o(or)25 b(an)h(acti)n(v)o(e)f(task,)j +(a)e(ne)n(w)g(address)f(space)h(is)g(created)f(together)156 +1626 y(with)18 b(128)e(threads.)23 b(Lthread)16 b(0)i(is)g(started,)g +(the)f(other)f(ones)h(w)o(ait)h(for)f(a)g(\223real\224)g(creation)g(by) +g(lthread)p 3065 1626 25 4 v 28 w(e)o(x)p 3171 1626 V +29 w(re)o(gs.)24 b(An)17 b(inacti)n(v)o(e)156 1726 y(task)24 +b(is)f(empty)-5 b(.)32 b(It)23 b(occupies)f(no)h(resources,)f(has)h(no) +g(address)f(space)h(and)f(no)h(threads.)32 b(Communication)21 +b(with)i(inacti)n(v)o(e)156 1826 y(tasks)i(is)g(not)f(possible.)36 +b(Loosely)23 b(speaking,)h(inacti)n(v)o(e)f(tasks)i(are)f(not)g(really) +f(e)o(xisting)h(b)n(ut)g(represent)f(only)g(the)h(right)g(to)156 +1925 y(create)c(an)g(acti)n(v)o(e)g(task.)281 2057 y(A)f(ne)n(wly)f +(created)g(task)g(gets)h(the)g(creator)e(as)i(its)h(chief,)e(i.e.)h(it) +g(is)g(created)f(inside)g(the)h(creator')-5 b(s)18 b(clan.)24 +b(Symmetrically)-5 b(,)156 2157 y(a)21 b(task)g(can)f(only)f(be)h +(deleted)g(either)f(directly)h(by)f(its)j(chief)d(\(its)i(creator\))e +(or)h(indirectly)f(by)h(a)g(higher)n(-le)n(v)o(el)e(chief.)156 +2572 y Ft(P)o(arameters)156 2797 y Fs(dest)j(task)1128 +2777 y FI(T)-7 b(ask)18 b(id)h(of)f(an)g Fs(e)n(xisting)g +FI(task)h(\(acti)n(v)o(e)e(or)h(inacti)n(v)o(e\))f(whose)h(chief)f(is)j +(the)e(current)f(task.)24 b(If)1128 2876 y(one)19 b(of)g(these)h +(preconditions)d(is)k(not)e(ful\002lled,)g(the)g(system)h(call)g(has)g +(no)f(ef)n(fect.)24 b(Simul-)1128 2976 y(taneously)-5 +b(,)18 b(a)i(ne)n(w)f(task)h Fs(with)g(the)g(same)g(task)g(number)f +FI(is)h(created.)k(It)c(may)g(be)f(acti)n(v)o(e)g(or)1128 +3076 y(inacti)n(v)o(e)g(\(see)h(ne)o(xt)g(parameter\).)156 +3265 y Fs(pa)o(g)o(er)779 3253 y Fn(6)p Fx(=)851 3261 +y Fs(nil)189 b FI(The)17 b(ne)n(w)g(task)g(is)h(created)f(as)h +Fs(active)p FI(.)23 b(The)17 b(speci\002ed)g(pager)f(is)j(associated)e +(with)g(lthread)1128 3360 y(0.)779 3452 y Fx(=)851 3460 +y Fs(nil)189 b FI(\(0\))19 b(The)h(ne)n(w)g(task)h(is)g(created)e(as)i +Fs(inactive)p FI(.)j(No)d(lthread)e(is)i(created.)156 +3669 y Fs(ESP)1128 3649 y FI(Initial)28 b(stack)g(pointer)f(for)g +(lthread)h(0)g(if)g(the)g(ne)n(w)g(task)h(is)g(created)e(as)i(an)f +(acti)n(v)o(e)g(one.)1128 3749 y(Ignored)18 b(otherwise.)156 +3957 y Fs(EIP)1128 3935 y FI(Initial)27 b(instruction)e(pointer)h(for)h +(lthread)f(0)h(if)g(the)g(ne)n(w)g(task)h(is)g(created)e(as)i(an)f +(acti)n(v)o(e)1128 4035 y(one.)d(Ignored)18 b(otherwise.)156 +4224 y Fs(mcp)1128 4220 y FI(Maximum)23 b(controlled)g(priority)g +(\(mcp\))g(de\002nes)i(the)f(highest)g(priority)g(which)g(can)g(be)1128 +4319 y(ruled)18 b(by)g(the)h(ne)n(w)f(task)i(acting)e(as)h(a)h +(scheduler)-5 b(.)23 b(The)c(ne)n(w)f(task')-5 b(s)20 +b(ef)n(fecti)n(v)o(e)d(mcp)h(is)i(the)1128 4419 y(minimum)e(of)i(the)h +(creator')-5 b(s)19 b(mcp)h(and)g(the)g(speci\002ed)g(mcp.)1128 +4519 y(EAX)i(contains)f(this)h(parameter)m(,)e(if)i(the)f(ne)n(wly)g +(generated)f(task)i(is)h(an)e Fs(active)h FI(task,)g(i.e.)1128 +4618 y(has)e(a)h(pager)e(and)h(at)g(least)h(lthread)f(0.)156 +4829 y Fs(ne)o(w)h(c)o(hief)1128 4824 y FI(Speci\002es)d(the)f(chief)g +(of)g(the)h(ne)n(w)f(inacti)n(v)o(e)f(task.)25 b(This)17 +b(mechanism)f(permits)h(to)h(transfer)1128 4924 y(inacti)n(v)o(e)30 +b(\(\223empty\224\))e(tasks)k(to)f(other)e(tasks.)57 +b(T)m(ransferring)29 b(an)h(inacti)n(v)o(e)g(task)h(to)g(the)1128 +5023 y(speci\002ed)19 b(chief)g(means)g(to)h(transfer)f(the)g(related)g +(right)g(to)h(create)f(a)h(task.)25 b(Note)19 b(that)h(the)1128 +5123 y(task)g(number)f(remains)g(unchanged.)1128 5223 +y(EAX)26 b(contains)g(this)h(parameter)m(,)f(if)h(the)g(ne)n(wly)f +(generated)e(task)j(is)h(an)e Fs(inactive)g FI(task,)1128 +5322 y(i.e.)f(has)h(no)f(pager)f(and)h(no)g(threads.)39 +b(EAX)26 b(contains)e(only)h(the)g(lo)n(wer)g(32)g(bits)h(of)f(the)1128 +5422 y(ne)n(w)20 b(chief)5 b(')-5 b(s)19 b(task)i(id.)k(\(The)19 +b(chief)h(must)g(reside)g(in)h(the)f(same)g(site.\))p +eop +%%Page: 31 31 +31 30 bop 322 -290 a FB(CHAPTER)21 b(2.)46 b(L4/X86)2749 +b FI(31)322 -83 y Fs(ne)o(w)21 b(task)f(id)945 -111 y +Fn(6)p Fx(=)996 -103 y Fy(nil)194 b FI(T)-7 b(ask)27 +b(creation)f(succeeded.)43 b(If)27 b(the)g(ne)n(w)f(task)h(is)h(acti)n +(v)o(e,)g(the)f(ne)n(w)f(task)h(id)g(will)h(ha)n(v)o(e)1294 +-3 y(a)h(ne)n(w)g(v)o(ersion)e(number)h(so)h(that)g(it)g(dif)n(fers)f +(from)g(all)i(task)f(ids)g(used)g(earlier)-5 b(.)51 b(Chief)1294 +96 y(and)28 b(task)h(number)d(are)j(the)f(same)h(as)g(in)g +Fs(dest)g(task)p FI(.)50 b(If)28 b(the)h(ne)n(w)f(task)h(is)h(created)d +(in-)1294 196 y(acti)n(v)o(e,)j(the)e(chief)h(is)g(tak)o(en)f(from)g +(the)h Fs(c)o(hief)f FI(parameter;)j(the)e(task)g(number)e(remains)1294 +296 y(unchanged.)22 b(The)e(v)o(ersion)f(is)i(unde\002ned)e(so)h(that)h +(the)f(ne)n(w)g(task)g(id)h(might)e(be)i(identical)1294 +395 y(with)h(a)h(formerly)e(\(b)n(ut)h(not)g(currently)f(and)h(not)g +(in)g(future\))f(v)n(alid)h(task)h(id.)32 b(This)22 b(is)i(safe)1294 +495 y(since)c(communication)d(with)k(inacti)n(v)o(e)e(tasks)i(is)g +(impossible.)945 628 y Fx(=)996 636 y Fy(nil)194 b FI(\(0\))19 +b(The)h(task)h(creation)e(f)o(ailed.)p eop +%%Page: 32 32 +32 31 bop 156 -290 a FI(32)2750 b FB(CHAPTER)21 b(2.)46 +b(L4/X86)156 -57 y FH(2.4)119 b(Pr)n(ocessor)29 b(Mirr)n(oring)156 +146 y Ft(2.4.1)99 b(Segments)156 301 y FI(L4)17 b(uses)g(a)h(\003at)f +(\(unse)o(gmented\))d(memory)h(model.)23 b(There)16 b(are)g(only)h(tw)o +(o)g(se)o(gments)f(a)n(v)n(ailable:)23 b Fs(user)p 3113 +301 25 4 v 30 w(space)p FI(,)17 b(a)g(read/write)156 +401 y(se)o(gment,)22 b(and)g Fs(user)p 767 401 V 30 w(space)p +987 401 V 29 w(e)n(xec)p FI(,)h(an)g(e)o(x)o(ecutable)d(se)o(gment.)31 +b(Both)23 b(co)o(v)o(er)e(\(at)h(least\))h(the)g(complete)e(user)n(-le) +n(v)o(el)g(address)156 500 y(space.)281 600 y(The)i(v)n(alues)g(of)g +(both)g(se)o(gment)g(selectors)g Fs(ar)m(e)h(unde\002ned)p +FI(.)32 b(When)23 b(a)h(thread)f(is)h(created,)f(its)i(se)o(gment)d(re) +o(gisters)h(SS,)156 700 y(DS,)f(ES,)f(FS)h(and)f(GS)g(are)g +(initialized)g(with)g Fs(user)p 1621 700 V 30 w(space)p +FI(,)g(CS)h(with)f Fs(user)p 2318 700 V 30 w(space)p +2538 700 V 29 w(e)n(xec)p FI(.)28 b(Whene)n(v)o(er)19 +b(the)i(k)o(ernel)f(detects)i(a)156 799 y(general)17 +b(protection)g(e)o(xception)f(and)h(the)h(se)o(gment)f(re)o(gisters)h +(are)g(not)g(loaded)f(properly)-5 b(,)15 b(it)k(reloads)f(them)f(with)i +(the)f(abo)o(v)o(e)156 899 y(mentioned)h(selectors.)25 +b(From)19 b(the)i(user')-5 b(s)20 b(point)f(of)h(vie)n(w)-5 +b(,)20 b(the)g(se)o(gment)f(re)o(gisters)h(cannot)f(be)h(modi\002ed.) +281 999 y(Ho)n(we)n(v)o(er)m(,)25 b(the)h(binary)e(representation)g(of) +h Fs(user)p 1731 999 V 30 w(space)g FI(and)g Fs(user)p +2265 999 V 30 w(space)p 2485 999 V 29 w(e)n(xec)h FI(may)f(change)g(at) +h(an)o(y)f(point)g(during)156 1098 y(program)18 b(e)o(x)o(ecution.)23 +b(Ne)n(v)o(er)c(rely)h(on)g(this)h(v)n(alue.)281 1198 +y(Furthermore,)f(the)j(LSL)g(\(load)f(se)o(gment)f(limit\))i(machine)e +(instruction)h(may)g(deli)n(v)o(er)f(wrong)h(se)o(gment)f(limits,)j(e)n +(v)o(en)156 1297 y(\003oating)c(ones.)25 b(The)19 b(result)i(of)f(this) +g(instruction)f(is)i(al)o(w)o(ays)g(unde\002ned.)156 +1535 y Ft(2.4.2)99 b(Exception)26 b(Handling)156 1691 +y FI(#PF)19 b(\(page)e(f)o(ault\),)h(#MC)g(\(machine)f(check)g(e)o +(xception\))f(and)i(some)g(#GP)g(\(general)f(protection\))f(e)o +(xceptions)g(are)j(handled)156 1790 y(by)31 b(the)g(k)o(ernel.)56 +b(The)31 b(other)f(e)o(xceptions)f(are)i(mirrored)e(to)i(the)g(virtual) +f(processor)f(of)i(the)g(thread)f(which)g(raised)h(the)156 +1890 y(e)o(xception.)281 1990 y(The)20 b(mirrored)e(e)o(xception)g +(handling)h(w)o(orks)g(as)i(described)e(in)i(the)f(processor)f +(manuals.)156 2113 y Fs(LIDT)63 b([EAX])1128 2104 y FI(This)30 +b(machine)f(instruction)g(is)i(emulated)e(by)h(the)g(k)o(ernel)g(and)f +(operates)h(per)f(thread.)1128 2204 y(An)o(y)d(thread)g(should)h +(install)g(an)g(IDT)h(by)e(this)i(instruction.)45 b(The)26 +b(length)h(\002eld)g(of)g(the)1128 2303 y(IDT)e(v)o(ector)f(is)i(not)e +(interpreted.)38 b(The)25 b(IDT)g(has)g(al)o(w)o(ays)h(a)f(length)f(of) +h(256)f(bytes,)i(i.e.)1128 2403 y(co)o(v)o(ers)19 b(the)h(Intel-reserv) +o(ed)d(e)o(xceptions)i(0)h(to)h(31.)1128 2544 y(The)i(IDT)h(must)g(ha)n +(v)o(e)g(the)f(format)g(described)g(in)h(the)g(processor)f(manuals.)35 +b(Ho)n(we)n(v)o(er)m(,)1128 2644 y(only)25 b(trap)h(gates)g(can)g(be)g +(used)f(in)i(a)f(user)n(-le)n(v)o(el)f(IDT)-6 b(.)26 +b(The)g(se)o(gment)f(selectors)h(in)g(the)1128 2743 y(IDT)20 +b(are)g(ignored,)e(since)i(all)h(se)o(gments)f(describe)f(the)h(\003at) +h(address)f(space.)1128 2885 y(In)m(v)n(alid)30 b(IDT)i(addresses)f(or) +h(in)m(v)n(alid)e(e)o(xception-handler)e(addresses)k(do)f(not)g(raise)i +(a)1128 2984 y(double)18 b(f)o(ault;)j(instead,)e(the)i(current)d +(thread)i(is)h(shut)f(do)n(wn.)156 3121 y(Note)j(that)g(this)g +(mechanism)f(deals)h(only)f(with)h(e)o(xceptions,)f(not)g(INT)h +Fy(n)g FI(instructions.)32 b(Ex)o(ecuting)20 b(an)j(INT)g +Fy(n)g FI(in)g(32-bit)156 3220 y(mode)i(will)i(al)o(w)o(ays)f(raise)g +(a)g(#GP)g(\(general)f(protection\).)39 b(The)26 b(general-protection)c +(handler)i(may)i(interpret)e(the)i(error)156 3320 y(code)20 +b(\()p Fu(8)p Fy(n)d Fu(+)h(2)p FI(,)i(see)h(processor)e(manual\))g +(and)g(emulate)h(the)g(INT)g Fy(n)h FI(accordingly)-5 +b(.)156 3557 y Ft(2.4.3)99 b(Deb)n(ug)26 b(Registers)156 +3713 y FI(User)n(-le)n(v)o(el)21 b(deb)n(ug)f(re)o(gisters)h(e)o(xist)g +(per)g(thread.)27 b(DR0.)12 b(.)g(.)g(3,)22 b(DR6)f(and)g(DR7)g(can)g +(be)h(accessed)f(by)g(the)g(machine)f(insruc-)156 3813 +y(tions)i Fc(MO)l(V)j(DRx,n)d FI(and)g Fc(MO)l(V)i(r)l(,DRx)p +FI(.)30 b(Ho)n(we)n(v)o(er)m(,)20 b(only)h(task-local)g(breakpoints)f +(can)i(be)g(acti)n(v)n(ated,)f(i.e.)h(bits)g(L0.)12 b(.)g(.)g(3)156 +3912 y(in)21 b(DR7)f(cannot)f(be)i(set.)k(Breakpoints)19 +b(operate)g(per)h(thread.)k(Breakpoints)19 b(are)h(signalled)g(as)h +(#DB)f(e)o(xception)f(\(INT)g(1\).)281 4012 y(Note)h(that)g(user)n(-le) +n(v)o(el)f(breakpoints)g(are)h(suspended)e(when)i(k)o(ernel)f +(breakpoints)f(are)j(set)g(by)e(the)i(k)o(ernel)e(deb)n(ugger)-5 +b(.)p eop +%%Page: 33 33 +33 32 bop 322 -290 a FB(2.5.)45 b(THE)21 b(KERNEL-INFO)e(P)-8 +b(A)m(GE)2388 b FI(33)322 -57 y FH(2.5)119 b(The)31 b(K)m(er)n(nel-Inf) +m(o)f(P)o(age)322 129 y FI(The)h(k)o(ernel-info)d(page)i(contains)h(k)o +(ernel-v)o(ersion)c(data,)33 b(memory)d(descriptors)f +Fs(and)h(the)h(cloc)n(k)p FI(.)57 b(The)30 b(remainder)f(of)322 +229 y(the)e(page)f(is)i(unde\002ned.)43 b(\(In)26 b(f)o(act,)j(it)f +(contains)e(k)o(ernel)g(code.\))44 b(The)26 b(k)o(ernel-info)f(page)h +(is)i(mapped)d Fs(r)m(ead-only)g FI(in)i(the)322 328 +y Fy(\033)369 340 y Fx(0)407 328 y FI(-address)g(space.)45 +b Fy(\033)1010 340 y Fx(0)1076 328 y FI(can)27 b(use)g(the)h(memory)d +(descriptors)h(for)h(its)h(memory)d(management.)44 b +Fy(\033)3257 340 y Fx(0)3323 328 y FI(can)27 b(map)f(the)i(page)322 +428 y(read-only)18 b(to)j(other)e(address)h(spaces.)p +322 623 3189 4 v 322 1039 4 416 v 1701 980 a FF(L4)d(v)o(ersion)h +(parts)p 3507 1039 V 322 1042 3189 4 v 1550 w Fy(L)g +Fv(\002)g Fu(16)p 322 1236 1595 4 v 322 1402 4 167 v +1092 1344 a FE(\030)p 1913 1402 V 322 1405 1595 4 v 1916 +1236 798 4 v 1916 1402 4 167 v 982 w FF(b)o(us)e(frequenc)o(y)p +2710 1402 V 1916 1405 798 4 v 2713 1236 V 2713 1402 4 +167 v 346 w(processor)i(frequenc)o(y)p 3507 1402 V 2713 +1405 798 4 v 366 w FI(0xB0)p 322 1408 1595 4 v 322 1574 +4 167 v 1092 1516 a FE(\030)p 1913 1574 V 322 1577 1595 +4 v 1916 1408 V 1916 1574 4 167 v 1495 w FF(clock)p 3507 +1574 V 1916 1577 1595 4 v 954 w FI(0xA0)p 322 1580 798 +4 v 322 1746 4 167 v 435 1688 a FF(dedicated)i(mem4.high)p +1116 1746 V 322 1749 798 4 v 1119 1580 V 1119 1746 4 +167 v 236 w(dedicated)g(mem4.lo)n(w)p 1913 1746 V 1119 +1749 798 4 v 1916 1580 V 1916 1746 4 167 v 236 w(dedicated)g(mem3.high) +p 2710 1746 V 1916 1749 798 4 v 2713 1580 V 2713 1746 +4 167 v 236 w(dedicated)g(mem3.lo)n(w)p 3507 1746 V 2713 +1749 798 4 v 369 w FI(0x90)p 322 1752 V 322 1918 4 167 +v 435 1860 a FF(dedicated)g(mem2.high)p 1116 1918 V 322 +1921 798 4 v 1119 1752 V 1119 1918 4 167 v 236 w(dedicated)g(mem2.lo)n +(w)p 1913 1918 V 1119 1921 798 4 v 1916 1752 V 1916 1918 +4 167 v 236 w(dedicated)g(mem1.high)p 2710 1918 V 1916 +1921 798 4 v 2713 1752 V 2713 1918 4 167 v 236 w(dedicated)g(mem1.lo)n +(w)p 3507 1918 V 2713 1921 798 4 v 369 w FI(0x80)p 322 +1924 V 322 2090 4 167 v 435 2031 a FF(dedicated)g(mem0.high)p +1116 2090 V 322 2093 798 4 v 1119 1924 V 1119 2090 4 +167 v 236 w(dedicated)g(mem0.lo)n(w)p 1913 2090 V 1119 +2093 798 4 v 1916 1924 V 1916 2090 4 167 v 251 w(reserv)o(ed)f +(mem1.high)p 2710 2090 V 1916 2093 798 4 v 2713 1924 +V 2713 2090 4 167 v 266 w(reserv)o(ed)g(mem1.lo)n(w)p +3507 2090 V 2713 2093 798 4 v 384 w FI(0x70)p 322 2095 +V 322 2261 4 167 v 450 2203 a FF(reserv)o(ed)g(mem0.high)p +1116 2261 V 322 2264 798 4 v 1119 2095 V 1119 2261 4 +167 v 266 w(reserv)o(ed)g(mem0.lo)n(w)p 1913 2261 V 1119 +2264 798 4 v 1916 2095 V 1916 2261 4 167 v 328 w(main)f(mem.high)p +2710 2261 V 1916 2264 798 4 v 2713 2095 V 2713 2261 4 +167 v 391 w(main)f(mem.lo)n(w)p 3507 2261 V 2713 2264 +798 4 v 446 w FI(0x60)p 322 2267 3189 4 v 322 2433 4 +167 v 1889 2375 a FE(\030)p 3507 2433 V 322 2436 3189 +4 v 1812 w FI(0x50)p 322 2439 V 322 2605 4 167 v 1889 +2547 a FE(\030)p 3507 2605 V 322 2608 3189 4 v 1812 w +FI(0x40)p 322 2611 V 322 2777 4 167 v 1889 2719 a FE(\030)p +3507 2777 V 322 2780 3189 4 v 1812 w FI(0x30)p 322 2783 +V 322 2949 4 167 v 1889 2891 a FE(\030)p 3507 2949 V +322 2952 3189 4 v 1812 w FI(0x20)p 322 2955 V 322 3121 +4 167 v 1889 3063 a FE(\030)p 3507 3121 V 322 3124 3189 +4 v 1812 w FI(0x10)p 322 3127 1196 4 v 322 3293 4 167 +v 893 3234 a FE(\030)p 1515 3293 V 322 3296 1196 4 v +1518 3127 200 4 v 1518 3293 4 167 v 653 w FF(2)p 1714 +3293 V 1518 3296 200 4 v 1717 3127 V 1717 3293 4 167 +v 159 w Fp(L)p 1913 3293 V 1717 3296 200 4 v 1916 3127 +798 4 v 1916 3293 4 167 v 300 w FF(v)o(ersion)i(w)o(ord)p +2710 3293 V 1916 3296 798 4 v 2713 3127 V 2713 3293 4 +167 v 512 w(\223L4)p Fp(\026)p FF(K\224)p 3507 3293 V +2713 3296 798 4 v 534 w FI(0x00)913 3460 y(+0xC)708 b(+8)g(+4)g(+0)322 +3694 y Fs(mem.low)1294 3693 y FI(Physical)19 b(address)h(of)g(\002rst)h +(byte)f(of)g(re)o(gion.)j(Must)e(be)f(page)f(aligned.)322 +3872 y Fs(mem.high)1294 3867 y FI(Physical)30 b(address)h(of)f(\002rst) +i(byte)e(be)o(yond)f(the)i(re)o(gion.)55 b(Must)31 b(be)g(page)f +(aligned.)56 b(If)1294 3967 y Fs(mem.high)1640 3959 y +Fx(=)1711 3967 y FI(0,)20 b(the)h(re)o(gion)d(is)j(empty)-5 +b(.)322 4142 y Fs(main)20 b(mem)1294 4141 y FI(Main)g(memory)e(re)o +(gion.)322 4320 y Fs(r)m(eserved)j(mem)1294 4300 y FI(This)g(re)o(gion) +e(must)i(not)g(be)g(used.)26 b(It)21 b(contains)g(k)o(ernel)f(code)g +(\(reserv)o(ed)f(mem0\))h(or)g(data)1294 4399 y(\(reserv)o(ed)e(mem1\)) +h(grabbed)f(by)i(the)g(k)o(ernel)g(before)e Fy(\033)2899 +4411 y Fx(0)2958 4399 y FI(w)o(as)j(initialized.)322 +4577 y Fs(dedicated)e(mem)1294 4557 y FI(This)c(re)o(gion)f(contains)h +(dedicated)f(memory)f(which)i(cannot)f(be)i(used)f(as)h(standard)e +(mem-)1294 4656 y(ory)-5 b(.)24 b(F)o(or)19 b(e)o(xample,)g([640K,)g +(1M])g(is)i(a)g(popular)d(dedicated)h(memory)g(re)o(gion.)322 +4834 y Fs(cloc)n(k)1294 4833 y FI(System)h(clock)g(in)g +Fy(\026)p FI(s.)322 5017 y Fs(pr)l(ocessor)h(fr)m(equency)1294 +5016 y FI(Processor')-5 b(s)20 b(e)o(xternal)f(clock)g(rate)h(in)h +(MHz.)322 5200 y Fs(b)n(us)g(fr)m(equency)1294 5199 y +FI(Processor')-5 b(s)20 b(e)o(xternal)f(clock)g(rate)h(in)h(MHz.)p +eop +%%Page: 34 34 +34 33 bop 156 -290 a FI(34)2750 b FB(CHAPTER)21 b(2.)46 +b(L4/X86)156 -57 y FH(2.6)119 b(P)o(age-F)m(ault)30 b(and)h(Pr)n +(eemption)f(RPC)156 312 y Ft(P)o(age)25 b(F)n(ault)f(RPC)156 +660 y Fz(k)o(er)o(nel)d(sends:)779 681 y FI(w0)f(\(EDX\))p +1227 573 1993 4 v 1227 739 4 167 v 819 w FF(f)o(ault)f(address)f(/)f(4) +2386 695 y Fr(\(30\))p 3216 739 V 1227 742 1993 4 v 3219 +573 67 4 v 3219 739 4 167 v 3227 681 a Fp(w)p 3282 739 +V 3219 742 67 4 v 3286 573 V 3286 739 4 167 v 14 w FE(\030)p +3349 739 V 3286 742 67 4 v 779 853 a FI(w1)j(\(EBX\))p +1227 745 2126 4 v 1227 911 4 167 v 803 w FF(f)o(aulting)g(user)o(-le)n +(v)o(el)f(EIP)2540 867 y Fr(\(32\))p 3349 911 V 1227 +914 2126 4 v 779 1053 a Fy(w)855 1045 y Fx(=)919 1053 +y Fu(0)266 b FI(Read)20 b(page)g(f)o(ault.)779 1152 y +Fy(w)855 1144 y Fx(=)919 1152 y Fu(1)266 b FI(Write)21 +b(page)e(f)o(ault.)156 1331 y Fz(k)o(er)o(nel)i(r)o(ecei)o(v)o(es:)1128 +1310 y FI(The)h(recei)n(v)o(e)f(fpage)g(co)o(v)o(ers)g(the)i(complete)e +(user)h(address)g(space.)32 b(The)22 b(k)o(ernel)f(accepts)1128 +1410 y(mappings)g(or)i(grants)g(into)g(this)g(re)o(gion)f(as)i(well)f +(as)h(a)g(simple)f(2-w)o(ord)e(cop)o(y)h(message.)1128 +1509 y(The)e(recei)n(v)o(ed)e(message)i(is)h(ignored!)p +911 1675 2092 4 v 909 1775 4 100 v 1060 1745 a(timeouts)p +1494 1775 V 199 w(PF)g(at)158 b(PF)21 b(at)g(ipc)f(in)236 +b(PF)21 b(at)g(ipc)f(in)p 3000 1775 V 909 1875 V 1069 +1845 a(used)f(for)p 1494 1875 V 224 w(user)206 b(recei)n(v)o(er')-5 +b(s)319 b(sender')-5 b(s)p 3000 1875 V 909 1974 V 961 +1944 a(pagef)o(ault)18 b(RPC)p 1494 1974 V 108 w(le)n(v)o(el)263 +b(space)432 b(space)p 3000 1974 V 911 1978 2092 4 v 909 +2077 4 100 v 1146 2047 a(snd)p 1494 2077 V 329 w Fv(1)145 +b FI(sender')-5 b(s)19 b(snd)h(pf)99 b(recei)n(v)o(er')-5 +b(s)19 b(rcv)h(pf)p 3000 2077 V 909 2177 V 1150 2147 +a(rcv)p 1494 2177 V 334 w Fv(1)145 b FI(sender')-5 b(s)19 +b(snd)h(pf)99 b(recei)n(v)o(er')-5 b(s)19 b(rcv)h(pf)p +3000 2177 V 909 2277 V 1101 2247 a(snd)g(pf)p 1494 2277 +V 284 w Fv(1)145 b FI(sender')-5 b(s)19 b(snd)h(pf)99 +b(recei)n(v)o(er')-5 b(s)19 b(rcv)h(pf)p 3000 2277 V +909 2376 V 1105 2346 a(rcv)g(pf)p 1494 2376 V 289 w Fv(1)145 +b FI(sender')-5 b(s)19 b(snd)h(pf)99 b(recei)n(v)o(er')-5 +b(s)19 b(rcv)h(pf)p 3000 2376 V 911 2380 2092 4 v 156 +2910 a Ft(Pr)n(eemption)27 b(RPC)156 3258 y Fz(k)o(er)o(nel)21 +b(sends:)779 3279 y FI(w0)f(\(EDX\))p 1227 3171 2126 +4 v 1227 3337 4 167 v 902 w FF(user)o(-le)n(v)o(el)g(ESP)2436 +3293 y Fr(\(32\))p 3349 3337 V 1227 3340 2126 4 v 779 +3452 a FI(w1)g(\(EBX\))p 1227 3344 V 1227 3510 4 167 +v 915 w FF(user)o(-le)n(v)o(el)f(EIP)2428 3466 y Fr(\(32\))p +3349 3510 V 1227 3513 2126 4 v 156 3729 a Fz(k)o(er)o(nel)i(r)o(ecei)o +(v)o(es:)1128 3728 y FI(The)f(k)o(ernel)f(accepts)h(only)f(a)i(simple)f +(2-w)o(ord)f(reply)-5 b(.)24 b(Its)c(content)g(is)h(ignored!)p +1537 3895 839 4 v 1535 3995 4 100 v 1722 3965 a(timeouts)p +2191 3995 V 2374 3995 V 1535 4094 V 1730 4064 a(used)f(for)p +2191 4094 V 2374 4094 V 1535 4194 V 1587 4164 a(preemption)e(RPC)p +2191 4194 V 2374 4194 V 1537 4197 839 4 v 1535 4297 4 +100 v 1807 4267 a(snd)p 2191 4297 V 320 w Fv(1)p 2374 +4297 V 1535 4396 V 1812 4367 a FI(rcv)p 2191 4396 V 324 +w Fv(1)p 2374 4396 V 1535 4496 V 1762 4466 a FI(snd)j(pf)p +2191 4496 V 274 w Fv(1)p 2374 4496 V 1535 4596 V 1767 +4566 a FI(rcv)f(pf)p 2191 4596 V 279 w Fv(1)p 2374 4596 +V 1537 4599 839 4 v eop +%%Page: 35 35 +35 34 bop 322 -290 a FB(2.7.)45 b Fy(\033)540 -278 y +Fx(0)599 -290 y FB(RPC)22 b(PR)m(O)m(T)o(OCOL)2631 b +FI(35)322 -57 y FH(2.7)119 b Fb(\033)658 -39 y Fu(0)734 +-57 y FH(RPC)30 b(pr)n(otocol)322 147 y Fy(\033)369 159 +y Fx(0)435 147 y FI(is)f(the)f(initial)g(address)f(space.)48 +b(Although)26 b(it)i(is)h Fs(not)e FI(part)g(of)h(the)g(k)o(ernel,)g +(its)h(basic)f(protocol)e(is)i(de\002ned)f(with)h(the)322 +247 y(Nucleus.)d(Special)20 b Fy(\033)953 259 y Fx(0)1012 +247 y FI(implementations)e(may)i(e)o(xtend)e(this)j(protocol.)447 +356 y(The)27 b(address)f(space)h Fy(\033)1139 368 y Fx(0)1204 +356 y FI(is)h(idempotent,)f(i.e.)45 b(all)28 b(virtual)e(addresses)h +(in)g(this)g(address)g(space)g(are)f(identical)h(to)g(the)322 +456 y(corresponding)19 b(physical)h(address.)28 b(Note)22 +b(that)g(pages)f(requested)f(from)g Fy(sig)s(ma)2710 +468 y Fx(0)2769 456 y FI(continue)g(to)h(be)h(mapped)e(idempotent)322 +555 y(if)h(the)f(recei)n(v)o(er)f(speci\002es)i(its)g(complete)e +(address)h(space)g(as)h(recei)n(v)o(e)e(fpage.)447 665 +y Fy(\033)494 677 y Fx(0)555 665 y FI(gi)n(v)o(es)k(pages)f(to)h(the)g +(k)o(ernel)g(and)f(to)h(arbitrary)f(tasks,)i(b)n(ut)f(only)f(once.)32 +b(The)23 b(idea)g(is)h(that)f(all)g(pagers)g(request)f(the)322 +764 y(memory)e(the)o(y)h(need)g(in)g(the)h(startup)f(phase)g(of)g(the)h +(system)f(so)h(that)g(afterw)o(ards)e Fy(\033)2761 776 +y Fx(0)2821 764 y FI(has)i(spent)f(all)h(its)g(memory)-5 +b(.)27 b(Further)322 864 y(requests)20 b(will)h(then)f(automatically)f +(denied.)322 1155 y Ft(K)n(er)o(nel)25 b(Communication)322 +1422 y Fy(\033)369 1434 y Fx(0)428 1422 y Fz(r)o(ecei)o(v)o(es)20 +b(fr)o(om)f(a)h Fa(k)n(ernel)g Fz(thr)o(ead:)945 1641 +y FI(w0)g(\(EDX\))p 1393 1533 1993 4 v 1393 1699 4 167 +v 857 w FF(FFFFFFFF/4)2514 1655 y Fr(\(30\))p 3382 1699 +V 1393 1702 1993 4 v 3385 1533 67 4 v 3385 1699 4 167 +v 3402 1641 a FF(0)p 3448 1699 V 3385 1702 67 4 v 3452 +1533 V 3452 1699 4 167 v 33 w(0)p 3515 1699 V 3452 1702 +67 4 v 945 1814 a FI(w1)g(\(EBX\))p 1393 1706 2126 4 +v 1393 1872 4 167 v 1074 w FE(\030)2435 1828 y Fr(\(32\))p +3515 1872 V 1393 1875 2126 4 v 322 2101 a Fs(Intended)f(Action:)1294 +2081 y FI(F)o(or)g(reply)-5 b(,)19 b Fy(\033)1682 2093 +y Fx(0)1739 2081 y FI(should)g Fs(gr)o(ant)g FI(a)h(page)f(\(4K\))g(to) +h(the)g(k)o(ernel)f(thread.)24 b(The)19 b(page)g(might)g(be)1294 +2180 y(located)i(at)i(an)f(arbitrary)e(position)h(b)n(ut)h(must)g +(contain)f(ordinary)f(memory)-5 b(.)28 b(If)22 b(no)g(more)1294 +2280 y(memory)c(is)j(a)n(v)n(ailable,)f Fy(\033)2052 +2292 y Fx(0)2110 2280 y FI(should)f(reply)h(a)g(0-w)o(ord)f(instead)h +(of)g(a)h(page.)322 2469 y Fy(\033)369 2481 y Fx(0)428 +2469 y Fz(r)o(ecei)o(v)o(es)f(fr)o(om)f(a)h Fa(k)n(ernel)g +Fz(thr)o(ead:)945 2688 y FI(w0)g(\(EDX\))p 1393 2580 +2059 4 v 1393 2746 4 167 v 1047 w FF(0)2391 2702 y Fr(\(31\))p +3448 2746 V 1393 2749 2059 4 v 3452 2580 67 4 v 3452 +2746 4 167 v 3468 2688 a FF(1)p 3515 2746 V 3452 2749 +67 4 v 945 2861 a FI(w1)g(\(EBX\))p 1393 2753 1595 4 +v 1393 2919 4 167 v 809 w FE(\030)2169 2875 y Fr(\(24\))p +2984 2919 V 1393 2922 1595 4 v 2987 2753 532 4 v 2987 +2919 4 167 v 3186 2861 a FF(0)3236 2875 y Fr(\(8\))p +3515 2919 V 2987 2922 532 4 v 322 3148 a Fs(Intended)f(r)m(eply:)945 +3185 y FI(w0)h(\(EDX\))p 1393 3077 2126 4 v 1393 3243 +4 167 v 1077 w Fp(k)2427 3199 y Fr(\(32\))p 3515 3243 +V 1393 3246 2126 4 v 945 3358 a FI(w1)g(\(EBX\))p 1393 +3250 V 1393 3416 4 167 v 1074 w FE(\030)2435 3372 y Fr(\(32\))p +3515 3416 V 1393 3419 2126 4 v 1393 3557 a Fy(k)29 b +FI(is)d(the)g(number)d(of)j(pages)f(recommended)d(by)j +Fy(\033)2916 3569 y Fx(0)2980 3557 y FI(for)g(k)o(ernel)g(use)h +(\(pagetables)e(and)1393 3657 y(other)19 b(k)o(ernel-internal)f +(data\).)322 3980 y Ft(General)25 b(Memory)g(Mapping)322 +4265 y Fy(\033)369 4277 y Fx(0)428 4265 y Fz(r)o(ecei)o(v)o(es)20 +b(fr)o(om)f(a)h Fa(non-k)n(ernel)g Fz(thr)o(ead:)945 +4484 y FI(w0)g(\(EDX\))p 1393 4376 1993 4 v 1393 4542 +4 167 v 857 w FF(FFFFFFFF/4)2514 4498 y Fr(\(30\))p 3382 +4542 V 1393 4545 1993 4 v 3385 4376 67 4 v 3385 4542 +4 167 v 3402 4484 a FF(0)p 3448 4542 V 3385 4545 67 4 +v 3452 4376 V 3452 4542 4 167 v 33 w(0)p 3515 4542 V +3452 4545 67 4 v 945 4657 a FI(w1)g(\(EBX\))p 1393 4549 +2126 4 v 1393 4715 4 167 v 1074 w FE(\030)2435 4671 y +Fr(\(32\))p 3515 4715 V 1393 4718 2126 4 v 322 4944 a +Fs(Intended)f(Action:)1294 4924 y FI(F)o(or)e(reply)-5 +b(,)17 b Fy(\033)1678 4936 y Fx(0)1735 4924 y FI(should)f +Fs(map)i FI(a)g(page)g(\(4K\))f(writable)g(to)h(the)g(requester)-5 +b(.)24 b(The)18 b(page)f(might)1294 5023 y(be)28 b(located)g(at)h(an)g +(arbitrary)e(position)h(b)n(ut)g(must)h(contain)f(ordinary)e(memory)-5 +b(.)48 b(If)29 b(no)1294 5123 y(more)19 b(free)h(page)f(is)j(a)n(v)n +(ailable,)d Fy(\033)2273 5135 y Fx(0)2331 5123 y FI(should)h(reply)f(a) +i(0-w)o(ord)d(instead)i(of)g(a)h(page.)1294 5223 y(The)h(mapped)e(page) +h(must)i(be)f(mark)o(ed)e(and)i(must)g(not)g(further)e(be)i(mapped)f +(or)h(granted)1294 5322 y(by)17 b Fy(\033)1442 5334 y +Fx(0)1497 5322 y FI(to)h(another)e(task.)24 b(Ho)n(we)n(v)o(er)m(,)16 +b(multiple)g(mapping)g(to)h(the)g(same)h(requester)e(should)1294 +5422 y(be)k(supported.)p eop +%%Page: 36 36 +36 35 bop 156 -290 a FI(36)2750 b FB(CHAPTER)21 b(2.)46 +b(L4/X86)156 -82 y Fy(\033)203 -70 y Fx(0)262 -82 y Fz(r)o(ecei)o(v)o +(es)20 b(fr)o(om)f(any)h(thr)o(ead:)779 137 y FI(w0)g(\(EDX\))p +1227 29 1993 4 v 1227 195 4 167 v 731 w FF(address)2075 +129 y Fm(\024)2140 137 y FF(40000000/4)2474 151 y Fr(\(30\))p +3216 195 V 1227 198 1993 4 v 3219 29 67 4 v 3219 195 +4 167 v 3236 137 a FF(0)p 3282 195 V 3219 198 67 4 v +3286 29 V 3286 195 4 167 v 33 w(0)p 3349 195 V 3286 198 +67 4 v 779 309 a FI(w1)g(\(EBX\))p 1227 201 2126 4 v +1227 368 4 167 v 1074 w FE(\030)2269 323 y Fr(\(32\))p +3349 368 V 1227 371 2126 4 v 156 587 a Fs(Intended)f(Action:)1128 +567 y FI(F)o(or)e(reply)-5 b(,)17 b Fy(\033)1512 579 +y Fx(0)1567 567 y FI(should)g Fs(map)g FI(the)h(speci\002ed)f(physical) +g(page)f(frame)h(\(4K\))g(writable)g(to)h(the)1128 666 +y(requester)-5 b(.)33 b(If)23 b(the)h(page)e(is)j(already)d(mapped)g +(or)h(is)h(not)f(a)n(v)n(ailable,)g Fy(\033)3193 678 +y Fx(0)3255 666 y FI(should)f(reply)h(a)1128 766 y(0-w)o(ord)18 +b(instead)i(of)g(a)h(page.)1128 866 y(The)g(mapped)g(page)g(must)h(be)g +(mark)o(ed)f(and)h(must)g(not)g(further)e(be)i(mapped)f(or)h(granted) +1128 965 y(by)17 b Fy(\033)1276 977 y Fx(0)1331 965 y +FI(to)h(another)e(task.)24 b(Ho)n(we)n(v)o(er)m(,)16 +b(multiple)g(mapping)g(to)h(the)g(same)h(requester)e(should)1128 +1065 y(be)k(supported.)156 1243 y Fy(\033)203 1255 y +Fx(0)262 1243 y Fz(r)o(ecei)o(v)o(es)g(fr)o(om)f(any)h(thr)o(ead:)779 +1462 y FI(w0)g(\(EDX\))p 1227 1354 1993 4 v 1227 1521 +4 167 v 607 w FF(40000000/4)2069 1454 y Fk(<)2134 1462 +y Fp(a)2188 1454 y Fm(\024)2253 1462 y FF(C0000000/4)2598 +1476 y Fr(\(30\))p 3216 1521 V 1227 1524 1993 4 v 3219 +1354 67 4 v 3219 1521 4 167 v 3236 1462 a FF(0)p 3282 +1521 V 3219 1524 67 4 v 3286 1354 V 3286 1521 4 167 v +33 w(0)p 3349 1521 V 3286 1524 67 4 v 779 1635 a FI(w1)g(\(EBX\))p +1227 1527 2126 4 v 1227 1693 4 167 v 1074 w FE(\030)2269 +1649 y Fr(\(32\))p 3349 1693 V 1227 1696 2126 4 v 156 +1913 a Fs(Intended)f(Action:)1128 1892 y FI(F)o(or)c(reply)-5 +b(,)16 b Fy(\033)1509 1904 y Fx(0)1563 1892 y FI(should)f +Fs(map)g FI(the)h(physical)f(4M)h(superpage)e(with)i(address)g +Fy(a)s Fv(\000)s Fu(40000000)1128 1992 y FI(writable)22 +b(to)h(the)g(requester)-5 b(.)32 b(If)22 b(the)h(page)f(is)i(already)d +(mapped)h(or)g(is)i(not)e(a)n(v)n(ailable,)h Fy(\033)3694 +2004 y Fx(0)1128 2092 y FI(should)c(reply)g(a)i(0-w)o(ord)e(instead)h +(of)f(a)i(page.)1128 2191 y(The)29 b(mapped)f(superpage)g(must)i(be)g +(mark)o(ed)e(and)h(must)h(not)f(further)g(be)g(mapped)f(or)1128 +2291 y(granted)h(by)i Fy(\033)1570 2303 y Fx(0)1639 2291 +y FI(to)g(another)e(task.)58 b(Ho)n(we)n(v)o(er)m(,)31 +b(multiple)f(mapping)f(to)i(the)g(same)g(re-)1128 2391 +y(quester)19 b(should)g(be)i(supported.)156 2569 y Fy(\033)203 +2581 y Fx(0)262 2569 y Fz(r)o(ecei)o(v)o(es)f(fr)o(om)f(any)h(thr)o +(ead:)779 2788 y FI(w0)g(\(EDX\))p 1227 2680 2059 4 v +1227 2846 4 167 v 1047 w FF(0)2225 2802 y Fr(\(31\))p +3282 2846 V 1227 2849 2059 4 v 3286 2680 67 4 v 3286 +2846 4 167 v 3302 2788 a FF(1)p 3349 2846 V 3286 2849 +67 4 v 779 2961 a FI(w1)g(\(EBX\))p 1227 2853 1595 4 +v 1227 3019 4 167 v 809 w FE(\030)2003 2975 y Fr(\(24\))p +2817 3019 V 1227 3022 1595 4 v 2821 2853 532 4 v 2821 +3019 4 167 v 3020 2961 a FF(1)3070 2975 y Fr(\(8\))p +3349 3019 V 2821 3022 532 4 v 156 3238 a Fs(Intended)f(Action:)1128 +3218 y FI(F)o(or)h(reply)-5 b(,)18 b Fy(\033)1516 3230 +y Fx(0)1575 3218 y FI(should)h Fs(map)h(r)m(ead)g(only)f +FI(the)h(k)o(ernel)g(info)f(page)h(to)g(the)g(requester)-5 +b(.)1128 3318 y(This)20 b(page)g(can)g(be)g(mapped)e(multiply)-5 +b(.)p eop +%%Page: 37 37 +37 36 bop 322 -290 a FB(2.8.)45 b(ST)-8 b(AR)j(TING)21 +b(L4)2834 b FI(37)322 -57 y FH(2.8)119 b(Starting)31 +b(L4)322 208 y FI(F)o(or)20 b(booting)f(L4,)g(see)i(appendix)d(A.)447 +349 y(After)24 b(booting,)g(L4)h(enters)f(protected)f(mode)h(if)h +(started)g(in)g(real)f(mode,)h(enables)f(paging)f(and)i(initializes)g +(itself.)39 b(It)322 449 y(generates)19 b(the)h(basic)g(address)g +(space-serv)o(ers)e Fy(\033)1752 461 y Fx(0)1810 449 +y FI(and)i(a)g(task)g Fs(r)l(oot)h(server)g FI(which)e(is)i(intended)d +(to)i(boot)f(the)h(higher)n(-le)n(v)o(el)322 548 y(system.)447 +689 y Fy(\033)494 701 y Fx(0)555 689 y FI(and)i(the)g +Fs(r)l(oot)h(server)g FI(are)f(user)n(-le)n(v)o(el)g(tasks)h(and)f(not) +g(part)g(of)g(the)g(pure)g(Nucleus.)31 b(The)22 b(prede\002ned)f(ones)h +(can)g(be)322 789 y(replaced)g(by)h(modifying)e(the)i(follo)n(wing)e +(table)i(in)h(the)f(L4)g(image)f(before)g(starting)h(L4.)33 +b(The)23 b(k)o(ernel)f(deb)n(ugger)f Fs(kdeb)n(ug)322 +889 y FI(is)h(also)e(not)g(part)g(of)g(the)g(Nucleus)g(and)f(can)h +(accordingly)e(be)i(replaced)f(by)h(modifying)e(the)i(table.)p +322 1126 798 4 v 322 1292 4 167 v 435 1234 a FF(dedicated)g(mem4.high)p +1116 1292 V 322 1295 798 4 v 1119 1126 V 1119 1292 4 +167 v 236 w(dedicated)g(mem4.lo)n(w)p 1913 1292 V 1119 +1295 798 4 v 1916 1126 V 1916 1292 4 167 v 236 w(dedicated)g(mem3.high) +p 2710 1292 V 1916 1295 798 4 v 2713 1126 V 2713 1292 +4 167 v 236 w(dedicated)g(mem3.lo)n(w)p 3507 1292 V 2713 +1295 798 4 v 286 w FI(0x1090)p 322 1298 V 322 1464 4 +167 v 435 1406 a FF(dedicated)g(mem2.high)p 1116 1464 +V 322 1467 798 4 v 1119 1298 V 1119 1464 4 167 v 236 +w(dedicated)g(mem2.lo)n(w)p 1913 1464 V 1119 1467 798 +4 v 1916 1298 V 1916 1464 4 167 v 236 w(dedicated)g(mem1.high)p +2710 1464 V 1916 1467 798 4 v 2713 1298 V 2713 1464 4 +167 v 236 w(dedicated)g(mem1.lo)n(w)p 3507 1464 V 2713 +1467 798 4 v 286 w FI(0x1080)p 322 1469 3189 4 v 322 +1636 4 167 v 1889 1577 a FE(\030)p 3507 1636 V 322 1639 +3189 4 v 1729 w FI(0x1070)p 322 1641 V 322 1807 4 167 +v 1889 1749 a FE(\030)p 3507 1807 V 322 1810 3189 4 v +1729 w FI(0x1060)p 322 1813 798 4 v 322 1979 4 167 v +457 1921 a FF(kdeb)o(ug)e(permissions)p 1116 1979 V 322 +1982 798 4 v 1119 1813 V 1119 1979 4 167 v 251 w(kdeb)o(ug)g +(con\002guration)p 1913 1979 V 1119 1982 798 4 v 1916 +1813 V 1916 1979 4 167 v 491 w FE(\030)p 2710 1979 V +1916 1982 798 4 v 2713 1813 V 2713 1979 4 167 v 547 w +FF(L4)e(con\002guration)p 3507 1979 V 2713 1982 798 4 +v 342 w FI(0x1050)p 322 1985 V 322 2151 4 167 v 484 2093 +a Fl(r)m(oot)i(server)f FF(end+1)p 1116 2151 V 322 2154 +798 4 v 1119 1985 V 1119 2151 4 167 v 335 w Fl(r)m(oot)h(server)f +FF(be)o(gin)p 1913 2151 V 1119 2154 798 4 v 1916 1985 +V 1916 2151 4 167 v 303 w Fl(r)m(oot)h(server)f FF(start)h(EIP)p +2710 2151 V 1916 2154 798 4 v 2713 1985 V 2713 2151 4 +167 v 252 w Fl(r)m(oot)f(server)h FF(start)g(ESP)p 3507 +2151 V 2713 2154 798 4 v 284 w FI(0x1040)p 322 2157 V +322 2323 4 167 v 592 2265 a Fp(\033)632 2274 y Fr(1)683 +2265 y FF(end+1)p 1116 2323 V 322 2326 798 4 v 1119 2157 +V 1119 2323 4 167 v 551 w Fp(\033)1439 2274 y Fr(1)1490 +2265 y FF(be)o(gin)p 1913 2323 V 1119 2326 798 4 v 1916 +2157 V 1916 2323 4 167 v 519 w Fp(\033)2194 2274 y Fr(1)2245 +2265 y FF(start)g(EIP)p 2710 2323 V 1916 2326 798 4 v +2713 2157 V 2713 2323 4 167 v 468 w Fp(\033)2984 2274 +y Fr(1)3035 2265 y FF(start)g(ESP)p 3507 2323 V 2713 +2326 798 4 v 392 w FI(0x1030)p 322 2329 V 322 2495 4 +167 v 592 2437 a Fp(\033)632 2446 y Fr(0)683 2437 y FF(end+1)p +1116 2495 V 322 2498 798 4 v 1119 2329 V 1119 2495 4 +167 v 551 w Fp(\033)1439 2446 y Fr(0)1490 2437 y FF(be)o(gin)p +1913 2495 V 1119 2498 798 4 v 1916 2329 V 1916 2495 4 +167 v 519 w Fp(\033)2194 2446 y Fr(0)2245 2437 y FF(start)g(EIP)p +2710 2495 V 1916 2498 798 4 v 2713 2329 V 2713 2495 4 +167 v 468 w Fp(\033)2984 2446 y Fr(0)3035 2437 y FF(start)g(ESP)p +3507 2495 V 2713 2498 798 4 v 392 w FI(0x1020)p 322 2501 +V 322 2667 4 167 v 534 2609 a Fl(kdeb)o(ug)g FF(end+1)p +1116 2667 V 322 2670 798 4 v 1119 2501 V 1119 2667 4 +167 v 435 w Fl(kdeb)o(ug)g FF(be)o(gin)p 1913 2667 V +1119 2670 798 4 v 1916 2501 V 1916 2667 4 167 v 390 w +Fl(kdeb)o(ug)g FF(e)o(xception)p 2710 2667 V 1916 2670 +798 4 v 2713 2501 V 2713 2667 4 167 v 420 w Fl(kdeb)o(ug)g +FF(init)p 3507 2667 V 2713 2670 798 4 v 415 w FI(0x1010)913 +2835 y(+0xC)708 b(+8)g(+4)g(+0)322 3075 y(0x1010)20 b(.)12 +b(.)g(.)g(are)23 b(of)n(fsets)g(relati)n(v)o(e)e(to)i(the)f(load)g +(address.)31 b(The)22 b(EIP)g(and)g(ESP)h(v)n(alues)f(ho)n(we)n(v)o(er) +m(,)e(are)j(absolute)e(32-bit)g(ad-)322 3175 y(dresses.)k(The)17 +b(appropriate)f(code)h(must)h(be)g(loaded)f(at)h(these)g(addresses)f +(before)g(L4)h(is)g(started.)24 b(Note)18 b(that)g(the)g(prede\002ned) +322 3275 y(root)i(serv)o(er)f(currently)g(e)o(x)o(ecutes)g(only)g(a)i +(brief)e(k)o(ernel)h(test.)322 3450 y Fs(mem.low)1294 +3449 y FI(Physical)f(address)h(of)g(\002rst)h(byte)f(of)g(re)o(gion.)j +(Must)e(be)f(page)f(aligned.)322 3669 y Fs(mem.high)1294 +3665 y FI(Physical)30 b(address)h(of)f(\002rst)i(byte)e(be)o(yond)f +(the)i(re)o(gion.)55 b(Must)31 b(be)g(page)f(aligned.)56 +b(If)1294 3764 y Fs(mem.high)1640 3756 y Fx(=)1711 3764 +y FI(0,)20 b(the)h(re)o(gion)d(is)j(empty)-5 b(.)322 +3984 y Fs(dedicated)19 b(mem)1294 3963 y FI(This)c(re)o(gion)f +(contains)h(dedicated)f(memory)f(which)i(cannot)f(be)i(used)f(as)h +(standard)e(mem-)1294 4063 y(ory)-5 b(.)24 b(F)o(or)19 +b(e)o(xample,)g([640K,)g(1M])g(is)i(a)g(popular)d(dedicated)h(memory)g +(re)o(gion.)322 4282 y Fs(be)m(gin)1294 4281 y FI(Physical)g(address)h +(of)g(the)g(\002rst)h(byte)f(of)g(a)h(serv)o(er')-5 b(s)19 +b(code+data)g(area.)322 4507 y Fs(end)1294 4506 y FI(Physical)g +(address)h(of)g(the)g(last)h(byte)f(of)g(a)h(serv)o(er')-5 +b(s)19 b(code+data)g(area.)322 4730 y Fs(start)i(EIP)1294 +4729 y FI(Physical)e(address)h(of)g(a)h(serv)o(er')-5 +b(s)19 b(initial)i(instruction)e(pointer)g(\(start\).)322 +4955 y Fs(start)i(ESP)1294 4954 y FI(Physical)e(address)h(of)g(a)h +(serv)o(er')-5 b(s)19 b(initial)i(stack)f(pointer)f(\(stack)h +(bottom\).)322 5179 y Fs(kdeb)n(ug)f(init)1294 5178 y +FI(Physical)g(address)h(of)g Fs(kdeb)n(ug)p FI(')-5 b(s)19 +b(initialization)h(routine.)322 5403 y Fs(kdeb)n(ug)f(e)n(xception)1294 +5402 y FI(Physical)g(address)h(of)g Fs(kdeb)n(ug)p FI(')-5 +b(s)19 b(deb)n(ug-e)o(xception)e(handler)-5 b(.)p eop +%%Page: 38 38 +38 37 bop 156 -290 a FI(38)2750 b FB(CHAPTER)21 b(2.)46 +b(L4/X86)156 -83 y Fs(L4)21 b(con\002gur)o(ation)p 1128 +-154 1063 4 v 1128 12 4 167 v 1567 -46 a FE(\030)1638 +-32 y Fr(\(16\))p 2187 12 V 1128 15 1063 4 v 2190 -154 +532 4 v 2190 12 4 167 v 2312 -46 a FF(pnodes)2517 -32 +y Fr(\(8\))p 2718 12 V 2190 15 532 4 v 2722 -154 V 2722 +12 4 167 v 2868 -46 a FF(ptabs)3025 -32 y Fr(\(8\))p +3250 12 V 2722 15 532 4 v 779 120 a FI(ptabs)173 b(number)29 +b(of)h(ptabs)h(\(4K)g(each\))f(per)g(4M)h(of)f(physical)g(memory)f +(which)i(the)f(Nucleus)1128 220 y(should)25 b(allocate)g(for)h(page)f +(tables.)42 b(0)26 b(indicates)g(to)g(use)g(the)g(def)o(ault)f(v)n +(alue.)41 b(A)27 b(v)n(alue)1128 320 y(of)22 b(128,)f(for)h(e)o +(xample,)f(speci\002es)h(that)g(1/8)g(of)g(memory)e(should)i(be)g +(reserv)o(ed)e(for)i(page)1128 419 y(tables.)779 519 +y(pnodes)112 b(number)18 b(of)i(pnode)e(entries)i(\(16)g(bytes)g +(each\))f(the)h(Nucleus)g(should)f(allocate)h(per)f(phys-)1128 +618 y(ical)h(frame.)k(A)d(v)n(alue)f(of)g(0)g(indicates)g(to)g(use)h +(the)f(def)o(ault)f(v)n(alue.)156 796 y Fs(kdeb)n(ug)g(con\002gur)o +(ation)p 1128 726 798 4 v 1128 892 4 167 v 1408 834 a +FF(port)1532 848 y Fr(\(12\))p 1921 892 V 1128 895 798 +4 v 1925 726 266 4 v 1925 892 4 167 v 1958 834 a FF(rate)2074 +848 y Fr(\(4\))p 2187 892 V 1925 895 266 4 v 2190 726 +465 4 v 2190 892 4 167 v 2346 834 a FE(\030)2417 848 +y Fr(\(7\))p 2652 892 V 2190 895 465 4 v 2655 726 67 +4 v 2655 892 4 167 v 2672 834 a Fp(s)p 2718 892 V 2655 +895 67 4 v 2722 726 532 4 v 2722 892 4 167 v 157 w FF(pages)3030 +848 y Fr(\(8\))p 3250 892 V 2722 895 532 4 v 779 1000 +a FI(pages)159 b(The)28 b(number)f(of)h(4K)h(pages)g(that)f(kdeb)n(ug)f +(should)h(allocate)h(for)f(its)h(trace)g(b)n(uf)n(fer)-5 +b(.)50 b(A)1128 1099 y(v)n(alue)19 b(of)h(0)g(indicates)g(no)g(trace)g +(b)n(uf)n(fer)-5 b(.)779 1199 y Fy(s)832 1191 y Fx(=)897 +1199 y Fu(1)189 b FI(The)20 b(Nucleus)f(enters)h(kdeb)n(ug)f(before)g +(starting)h(the)g(root)f(serv)o(er)-5 b(.)779 1298 y(port)214 +b(Initially)-5 b(,)21 b(kdeb)n(ug)f(should)h(use)h(the)g(serial)h(line) +f(base)g(IO)g(address)g Fs(port)g FI(for)f(output)g(and)1128 +1398 y(input.)i(A)c(port)e(address)h(of)f(0)i(indicates)e(to)i(use)f +(the)g(inte)o(grated)e(console)i(\(k)o(e)o(yboard)d(and)1128 +1498 y(display\))k(instead)h(of)g(a)g(serial)h(line.)779 +1597 y(rate)224 b(determines)37 b(the)h(def)o(ault)f(baud)h(rate)g(for) +f(kdeb)n(ug)g(when)g(using)h(a)h(serial)f(line.)79 b(If)1128 +1697 y Fy(por)r(t)1293 1689 y Fn(6)p Fx(=)1358 1697 y +Fu(0)p FI(,)20 b(this)h(is)g(also)g(the)f(initial)g(baud)f(rate.)25 +b(Possible)c(v)n(alues:)922 1789 y Fx(=)987 1797 y Fu(1)99 +b FI(115.2)18 b(Kbd)922 1888 y Fx(=)987 1896 y Fu(2)133 +b FI(57.6)19 b(Kbd)922 1988 y Fx(=)987 1996 y Fu(3)133 +b FI(38.4)19 b(Kbd)922 2087 y Fx(=)987 2095 y Fu(6)133 +b FI(19.2)19 b(Kbd)880 2187 y Fx(=)945 2195 y Fu(12)161 +b FI(9.6)20 b(Kbd)156 2373 y Fs(kdeb)n(ug)f(permissions)p +1128 2302 1196 4 v 1128 2468 4 167 v 1633 2410 a FE(\030)1705 +2424 y Fr(\(18\))p 2320 2468 V 1128 2471 1196 4 v 2323 +2302 67 4 v 2323 2468 4 167 v 2339 2410 a Fp(p)p 2386 +2468 V 2323 2471 67 4 v 2390 2302 V 2390 2468 4 167 v +36 w(i)p 2453 2468 V 2390 2471 67 4 v 2456 2302 V 2456 +2468 4 167 v 29 w(w)p 2519 2468 V 2456 2471 67 4 v 2523 +2302 V 2523 2468 4 167 v 23 w(d)p 2586 2468 V 2523 2471 +67 4 v 2589 2302 V 2589 2468 4 167 v 31 w(r)p 2652 2468 +V 2589 2471 67 4 v 2655 2302 V 2655 2468 4 167 v 21 w(m)p +2718 2468 V 2655 2471 67 4 v 2722 2302 532 4 v 2722 2468 +4 167 v 199 w(k)2974 2424 y Fr(\(8\))p 3250 2468 V 2722 +2471 532 4 v 779 2576 a Fy(k)839 2568 y Fx(=)904 2576 +y Fu(0)182 b FI(An)o(y)19 b(task)i(can)f(use)g(kdeb)n(ug)f(from)g(user) +n(-le)n(v)o(el.)779 2676 y Fy(k)839 2668 y Fq(>)904 2676 +y Fu(0)182 b FI(Only)23 b(tasks)g(1)h(to)f Fy(k)k FI(can)c(use)g(kdeb)n +(ug)f(from)g(user)n(-le)n(v)o(el.)33 b(Threads)22 b(of)h(other)f(tasks) +i(will)1128 2775 y(be)c(shut)g(do)n(wn)f(when)h(in)m(v)n(oking)e(kdeb)n +(ug.)779 2875 y Fy(m)866 2867 y Fx(=)931 2875 y Fu(1)155 +b FI(Kdeb)n(ug)19 b(may)g(display)h(mapping.)779 2975 +y Fy(r)833 2967 y Fx(=)897 2975 y Fu(1)189 b FI(Kdeb)n(ug)19 +b(may)g(display)h(user)g(re)o(gisters.)779 3074 y Fy(d)836 +3066 y Fx(=)901 3074 y Fu(1)185 b FI(Kdeb)n(ug)19 b(may)g(display)h +(user)g(memory)-5 b(.)779 3174 y Fy(w)855 3166 y Fx(=)919 +3174 y Fu(1)167 b FI(Kdeb)n(ug)19 b(may)g(modify)g(memory)-5 +b(,)18 b(re)o(gister)m(,)h(mappings)f(and)i(tcbs.)779 +3274 y Fy(i)822 3266 y Fx(=)886 3274 y Fu(1)200 b FI(Kdeb)n(ug)19 +b(may)g(read)h(from)f(and)h(write)g(to)h(IO)f(ports.)779 +3373 y Fy(p)835 3365 y Fx(=)899 3373 y Fu(1)187 b FI(Kdeb)n(ug)19 +b(may)g(protocol)g(page)g(f)o(aults)i(and)e(IPC.)p eop +%%Page: 39 39 +39 38 bop 322 566 a Fw(A)l(ppendix)43 b(A)322 981 y FA(Booting)322 +1463 y FH(PC-compatible)31 b(Machines)322 1648 y FI(L4)18 +b(can)g(be)g(loaded)f(at)i(an)o(y)e(16-byte-aligned)d(location)j(be)o +(yond)f(0x1000)g(in)i(physical)f(memory)-5 b(.)22 b(It)c(can)g(be)g +(started)g(in)g(real)322 1748 y(mode)e(or)h(in)g(32-bit)f(protected)f +(mode)h(at)h(address)g(0x100)e(or)i(0x1000)d(relati)n(v)o(e)i(to)h(its) +h(load)e(address.)24 b(The)16 b(protected-mode)322 1847 +y(conditions)j(are)h(compliant)f(to)h(the)h(Multiboot)e(Standard)f(V)-9 +b(ersion)20 b(0.6.)p 828 1960 2590 4 v 826 2055 4 95 +v 1869 2026 a FF(Start)e(Preconditions)p 3416 2055 V +828 2058 2590 4 v 826 2153 4 95 v 1729 2153 V 2017 2124 +a(Real)h(Mode)p 2595 2153 V 398 w(32-bit)g(Protected)g(Mode)p +3416 2153 V 828 2156 2590 4 v 826 2251 4 95 v 1100 2222 +a(load)f(base)g(\()p Fp(L)p FF(\))p 1729 2251 V 322 w +Fp(L)1840 2214 y Fm(\025)1900 2222 y FF(0x1000,)f(16-byte)i(aligned)p +2595 2251 V 303 w Fp(L)2908 2214 y Fm(\025)2967 2222 +y FF(0x1000)p 3416 2251 V 826 2345 V 1077 2317 a(load)f(of)n(fset)g(\() +p Fp(X)5 b FF(\))p 1729 2345 V 323 w Fp(X)1879 2309 y +Fr(=)1937 2317 y FF(0x100)18 b(or)f Fp(X)2266 2309 y +Fr(=)2325 2317 y FF(0x1000)p 2595 2345 V 124 w Fp(X)2722 +2309 y Fr(=)2780 2317 y FF(0x100)h(or)f Fp(X)3110 2309 +y Fr(=)3168 2317 y FF(0x1000)p 3416 2345 V 826 2440 V +1150 2412 a(Interrupts)p 1729 2440 V 647 w(disabled)p +2595 2440 V 625 w(disabled)p 3416 2440 V 826 2535 V 1151 +2506 a(Gate)h(A20)p 1729 2535 V 729 w FE(\030)p 2595 +2535 V 752 w FF(open)p 3416 2535 V 826 2629 V 1155 2601 +a(EFLA)m(GS)p 1729 2629 V 709 w(I)2135 2593 y Fr(=)2182 +2601 y FF(0)p 2595 2629 V 631 w(I)2868 2593 y Fr(=)2915 +2601 y FF(0,)e(VM)3088 2593 y Fr(=)3135 2601 y FF(0)p +3416 2629 V 826 2724 V 1218 2695 a(CR0)p 1729 2724 V +746 w(PE)2163 2687 y Fr(=)2209 2695 y FF(0)p 2595 2724 +V 588 w(PE)2908 2687 y Fr(=)2954 2695 y FF(1,)g(PG)3105 +2687 y Fr(=)3152 2695 y FF(0)p 3416 2724 V 826 2819 V +1207 2790 a(\(E\)IP)p 1729 2819 V 781 w Fp(X)p 2595 2819 +V 718 w(L)g Fo(+)g Fp(X)p 3416 2819 V 826 2913 V 1238 +2885 a FF(CS)p 1729 2913 V 768 w Fp(L=)p Fo(16)p 2595 +2913 V 507 w FF(0,)h(4GB,)f(32-bit)j(e)o(x)o(ec)p 3416 +2913 V 826 3008 V 1144 2979 a(SS,DS,ES)p 1729 3008 V +721 w FE(\030)p 2595 3008 V 569 w FF(0,)d(4GB,)h(read/write)p +3416 3008 V 826 3102 V 1211 3074 a(EAX)p 1729 3102 V +788 w FE(\030)p 2595 3102 V 625 w FF(0x2B)n(ADB002)p +3416 3102 V 826 3197 V 1213 3169 a(EBX)p 1729 3197 V +790 w FE(\030)p 2595 3197 V 2962 3145 a Fm(\003)2998 +3169 y Fp(P)p 3416 3197 V 828 3200 2590 4 v 826 3295 +4 95 v 1164 3267 a FE(h)p Fp(P)25 b Fo(+)16 b(0)p FE(i)p +1729 3295 V 2595 3295 V 1506 w(\030)h FF(OR)g(1)p 3416 +3295 V 826 3390 V 1164 3361 a FE(h)p Fp(P)25 b Fo(+)16 +b(4)p FE(i)p 1729 3390 V 729 w FF(n/a)p 2595 3390 V 492 +w(belo)n(w)j(640)e(K)f(mem)h(in)g(K)p 3416 3390 V 826 +3484 V 1164 3456 a FE(h)p Fp(P)25 b Fo(+)16 b(8)p FE(i)p +1729 3484 V 2595 3484 V 1320 w FF(be)o(yond)j(1M)d(mem)h(in)g(K)p +3416 3484 V 828 3488 2590 4 v 826 3582 4 95 v 877 3554 +a(all)h(remaining)h(re)o(gisters)g(&)d(\003ags)p 1729 +3582 V 2595 3582 V 3416 3582 V 826 3677 V 967 3649 a(\(general,)j +(\003oating)g(point,)p 1729 3677 V 546 w FE(\030)p 2595 +3677 V 789 w(\030)p 3416 3677 V 826 3772 V 924 3743 a +FF(ESP)-7 b(,)15 b(xDT)-5 b(,)16 b(TR,)g(CRx,)h(DRx\))p +1729 3772 V 2595 3772 V 3416 3772 V 828 3775 2590 4 v +447 3923 a FI(L4)i(relocates)f(itself)i(to)f(0x1000,)d(enters)j +(protected)e(mode)h(if)i(started)e(in)h(real)g(mode,)f(enables)h +(paging)e(and)i(initializes)322 4023 y(itself.)2081 5620 +y(39)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/l4-x86/smp/lx/doc/Lnkdebug.ps b/l4-x86/smp/lx/doc/Lnkdebug.ps new file mode 100644 index 0000000..4d238f5 --- /dev/null +++ b/l4-x86/smp/lx/doc/Lnkdebug.ps @@ -0,0 +1,2362 @@ +%!PS-Adobe-2.0 + +%%Creator: dvips 5.58 Copyright 1986, 1994 Radical Eye Software + +%%Title: lnkdebug.dvi + +%%CreationDate: Tue Dec 16 16:12:50 1997 + +%%Pages: 14 + +%%PageOrder: Ascend + +%%BoundingBox: 0 0 612 792 + +%%EndComments + +%DVIPSCommandLine: C:\EMTEX\BIN\DVIPS32.EXE lnkdebug + +%DVIPSParameters: dpi=300, compressed, comments removed + +%DVIPSSource: TeX output 1997.12.16:1612 + +%%BeginProcSet: texc.pro + +/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N + +/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 + +mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} + +ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale + +isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div + +hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul + +TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} + +forall round exch round exch]setmatrix}N /@landscape{/isls true N}B + +/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B + +/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ + +/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N + +string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N + +end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ + +/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] + +N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup + +length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ + +128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub + +get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data + +dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N + +/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup + +/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx + +0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff + +setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff + +.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N + +/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id + +gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp + +add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add + +/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{ + +dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1 + +adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2 + +idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string + +putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval + +adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg} + +{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{ + +adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2 + +chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{] + +}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup + +length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ + +cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin + +0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul + +add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore showpage + +userdict /eop-hook known{eop-hook}if}N /@start{userdict /start-hook + +known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X + +/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for + +65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 + +0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V + +{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 + +getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} + +ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false + +RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 + +false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform + +round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg + +rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail + +{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} + +B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ + +4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ + +p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p + +a}B /bos{/SS save N}B /eos{SS restore}B end + +%%EndProcSet + +TeXDict begin 40258431 52099146 1000 300 300 + +(/DOC/LAVA/LNKD/lnkdebug.dvi) @start /Fa 1 63 df<12C012F01238120E6C7EEA + +01E0EA0078131C1307EB03C0A2EB0700131C1378EA01E0EA0780000EC7FC123812F012C0 + +12147D901A>62 D E /Fb 34 121 df<12E0A312601240A312C003087C820C>44 + +DI<12E0A303037C820C>I<5A1207123FB4FC12C71207B3A3EAFF + +F8A20D1C7C9B15>49 DI<133C137C135C13DCA2EA019C1203A2EA071CA2120EA2121CA21238127812 + +7012F0B512C0A238001C00A7121B7F9A15>52 D<131C133EA2132E1367A2EBE78013C713 + +C300017F1383138100037F1301486C7EA21206000E1378380FFFF8A2381C003CA2121800 + +387FA248131F80126000E0EB0780191D7F9C1C>65 D67 DIIII<12F0B3AB041D7C9C0C>73 D<12F0B3A9B5FCA2101D7D9C16>76 + +D80 D83 DI<00 + +F01370B3A5007813E0A2383C01C0381E0380EA0F073807FE00EA01F8141E7C9C1D>I97 D<12E0ABEAE3E0EAEFF8EAFFFCEAF83EEAE01E130E1307A613 + +0EEAF01EEAF83CEAFFF8EAEFF0EAE3E0101D7D9C15>II<1307ABEA07 + +C7EA1FF7EA3FFFEA3C1FEA7807127012E0A61270EA780FEA3C1FEA3FFFEA1FF7EA07C710 + +1D7F9C15>II<3807C3C0EA0FFF5A38383800487EA56C5A + +EA3FF05BEA77C00070C7FCA2EA3FFC13FF481380EA700738E001C0A3EAF003387C0F8038 + +3FFF006C5AEA07F8121B7F9115>103 D<12F0A41200A71270B2041D7E9C0A>105 + +D<12E0B3AB031D7D9C0A>108 D110 D112 DI< + +EAE38012E712EFEAFC005A5AA25AAB09127D910E>II<121CA6EAFFE0A2EA1C00AC1320EA1FF0120FEA07C00C187F970F>II<3870038038780700EA3C0EEA1C1C120E6C5AEA03F0 + +6C5A5B7F487EEA0738EA0618EA0E1C487E487E3870038000F013C01212809113>120 + +D E /Fc 26 124 df42 D<497EB0B612FEA23900 + +018000B01F227D9C26>I45 D<14801301A2EB0300A31306A35B + +A35BA35BA35BA35BA3485AA448C7FCA31206A35AA35AA35AA35AA35AA311317DA418>47 + +D<12F0B3B104237CA20D>73 D80 D82 + +D84 D<00F01478A2007814F0A36CEB01E0A36C + +EB03C0A36CEB0780A213800007EB0F00A23803C00E141EA23801E01C143CA23800F03814 + +78A2EB787014F0A2EB38E0133DEB1DC0131FA26D5AA21D237FA220>86 + +D<0078EB01E0007CEB03C06C1307001E1480001FEB0F006C6C5A0007131E6C6C5AEBE07C + +3801F07800005B13F9EB7DE0EB3FC0131F5C6DC7FC497E80133FEB7DE0EB79F013F00001 + +1378497E3803C03E0007131E497ED80F001380481307001EEB03C04814E0007CEB01F000 + +7813004814F81D237FA220>88 D97 + +D<12F0AD13F8EAF3FEB5FC38FE0F80EAF80738F003C0A2EB01E0A7130314C0A238F80780 + +EAFE1F38F7FF00EAF3FCEAF1F813237DA219>I100 + +D<3803F078380FFFF85A383E1F00EA3C0F38780780A5383C0F00EA3E1FEA1FFE485AEA33 + +F00070C7FCA21278EA3FFEEBFFC06C13E04813F0EA780138F000F81478A4007813F0383E + +03E0381FFFC06C13803801FC0015217F9518>103 D<12F0A41200A912F0B3A404237DA2 + +0B>105 D<12F0ADEB1F80EB3F00133E5B5BEAF1F0EAF3E0EAF7C012FFA27FA2EAFDF0EA + +F8F8EAF078137C7F131E131F7F1480EB07C012237CA218>107 D<39F0F807C039F3FE1F + +F039F7FF3FF839FE0F707800FCEBE07C39F807C03CA200F01380AF1E167C9527>109 + +D111 + +DI114 DI<121EA6EAFFFCA3EA1E00AE1308EA1F1CEA0FFC13F8EA07C00E1C7F9B12>II<39F007803CEB0FC0A2D8780D1378131D + +14E0131CD83C1813F0133814F0001C14E0001E137113701479000EEB39C01360000F133B + +00071480141BEBC01FA2000314001E167F9521>119 D<007813F0387C01E0383E03C0EA + +1E07000F138038078F0013DEEA03FE6C5A6C5A137013F8487EEA03DC139EEA078F380F07 + +80121EEB03C0383C01E0387800F000F813F81516809516>I123 + +D E /Fd 1 62 df61 D + +E /Fe 2 55 df<14C01303EB0700131C1378EA01E0EA0780000EC7FC123812F0A2123812 + +0E6C7EEA01E0EA0078131C1307EB03C013001400A6387FFF80B512C0121C7D931A>20 + +D<1303A21306A2130C1318A21330A2136013C0A2EA0180A2EA0300A212065AA25AA25A5A + +A25A1240101A7C9300>54 D E /Ff 9 117 df12 + +D101 D<137F3801E3803803C7C0EA0787120FEB8380 + +EB8000A5EAFFF8A2EA0F80AEEA7FF0A2121D809C0F>I104 D<121E123FA4121EC7FCA6127FA2 + +121FAEEAFFC0A20A1E7F9D0E>I108 + +D<38FF0FC0EB31E0381F40F0EB80F8A21300AB38FFE7FFA218127F911B>110 + +D115 D<1203A45AA25AA2EA3FFC12FFEA1F00A9 + +130CA4EA0F08EA0798EA03F00E1A7F9913>I E /Fg 10 123 df<3801803000031370A3 + +380700E0A4380E01C0A4381C0388A3EA1E07383E1990383BE0E00038C7FCA25AA45AA25A + +151B7F9119>22 D<126012F0A2126004047C830C>58 D<126012F0A212701210A41220A2 + +12401280040C7C830C>I<130113031306A3130CA31318A31330A31360A213C0A3EA0180 + +A3EA0300A31206A25AA35AA35AA35AA35AA210297E9E15>61 D<48B5FC39003C01C09038 + +3800E015F01570A25B15F0A2EC01E09038E003C0EC0780EC1F00EBFFFC3801C00FEC0780 + +EC03C0A2EA0380A439070007801500140E5C000E1378B512C01C1C7E9B1F>66 + +D<3A01FFC0FF803A001E003C00011C13306D13205D010F5B6D48C7FC1482EB038414CCEB + +01D814F05C130080EB0170EB0278EB04381308EB103CEB201CEB401EEB800E3801000F00 + +027F1206001E497E39FF803FF0211C7F9B22>88 D100 D<380787803808C8403810F0C03820F1E0EBE3C03840E1803800E000 + +A2485AA43863808012F3EB810012E5EA84C6EA787813127E9118>120 + +D<001C13C0EA27011247A238870380A2120EA2381C0700A4EA180EA3EA1C1EEA0C3CEA07 + +DCEA001C1318EA6038EAF0305B485AEA4180003EC7FC121A7E9114>II E /Fh 31 122 df<903801F03C9038071C47010C13C7EC19C6 + +90381C0180140313181338A2EC0700A20003B512F03900700700A3140EA213E0A35CA2EA + +01C0A35CA2EA0380A21430EB0070A248136038C630E038E638C038CC3180D8781EC7FC20 + +25819C19>11 D<1218123CA31204A21208A21210122012401280060C779C0D>39 + +D<13031306130813181330136013C0A2EA0180EA0300A21206A25AA2121C1218A2123812 + +30A21270A21260A412E0A51260A51220123012107EA2102A7B9E11>I45 D<1230127812F0126005047C830D>I<48B5FC39003C03C090383800E0A21570 + +A24913781538A215785BA4484813F0A315E03803800115C0140315803907000700140E5C + +5C000E13E0B512801D1C7E9B1F>68 D<3A01FFC07F803A003C001E000138131815205D5D + +D97002C7FC5C5C5CEBE04014C013E1EBE2E0EA01C4EBD07013E013C048487EA21418141C + +EA070080A348130F39FFE07FC0211C7E9B20>75 D<3801FFC038003C001338A45BA45BA4 + +485AA438038002A31404EA0700140C14181438000E13F0B5FC171C7E9B1A>I78 + +D97 D<123F1207A2120EA45AA4EA39E0EA3A18EA3C0C12381270130EA3EAE0 + +1CA31318133813301360EA60C0EA3180EA1E000F1D7C9C13>I<13F8EA0304120EEA1C0E + +EA181CEA30001270A25AA51304EA60081310EA3060EA0F800F127C9113>II<13F8EA0704120CEA1802EA38041230EA7008EA7FF0 + +EAE000A5EA60041308EA30101360EA0F800F127C9113>IIIII107 DI<391C1E078039266318C0394683A0E0384703 + +C0008E1380A2120EA2391C0701C0A3EC0380D8380E1388A2EC0708151039701C03203930 + +0C01C01D127C9122>II<13F8EA030CEA0E06487E121812 + +3000701380A238E00700A3130EA25BEA60185BEA30E0EA0F8011127C9115>I<38038780 + +3804C860EBD03013E0EA09C014381201A238038070A31460380700E014C0EB0180EB8300 + +EA0E86137890C7FCA25AA45AB4FC151A809115>I114 DI<12035AA3120EA4EAFFE0EA1C00A35AA45AA4EAE080A2EAE100A2126612380B1A7C99 + +0E>I<381C0180EA2E03124EA2388E0700A2121CA2EA380EA438301C80A3EA383C38184D + +00EA0F8611127C9116>II<381E0183382703871247148338870701A2 + +120EA2381C0E02A31404EA180C131C1408EA1C1E380C26303807C3C018127C911C>I<38 + +1C0180EA2E03124EA2388E0700A2121CA2EA380EA4EA301CA3EA383CEA1878EA0FB8EA00 + +3813301370EAE0605BEA81800043C7FC123C111A7C9114>121 D + +E /Fi 5 104 df0 D<1203A4EAC30CEAE31CEA7338EA1FE0EA07 + +80A2EA1FE0EA7338EAE31CEAC30CEA0300A40E127D9215>3 D15 + +D<133C13E0EA01C013801203AD13005A121C12F0121C12077E1380AD120113C0EA00E013 + +3C0E297D9E15>102 D<12F0121C12077E1380AD120113C0EA00E0133C13E0EA01C01380 + +1203AD13005A121C12F00E297D9E15>I E /Fj 49 122 df<1238127C12FEA3127C1238 + +07077C8610>46 D<13181378EA01F812FFA21201B3A7387FFFE0A213207C9F1C>49 + +DI<13FE3807FFC0380F07E0381E03F0123FEB81F8A3EA1F + +0314F0120014E0EB07C0EB1F803801FE007F380007C0EB01F014F8EB00FCA2003C13FE12 + +7EB4FCA314FCEA7E01007813F8381E07F0380FFFC03801FE0017207E9F1C>I<14E01301 + +1303A21307130F131FA21337137713E7EA01C71387EA03071207120E120C121812381270 + +12E0B6FCA2380007E0A790B5FCA218207E9F1C>I<00301320383E01E0383FFFC0148014 + +005B13F8EA33C00030C7FCA4EA31FCEA37FF383E0FC0383807E0EA3003000013F0A214F8 + +A21238127C12FEA200FC13F0A2387007E0003013C0383C1F80380FFF00EA03F815207D9F + +1C>II<12601278387FFFFEA214FC14F8A2 + +14F038E0006014C038C00180EB0300A2EA00065B131C131813381378A25BA31201A31203 + +A76C5A17227DA11C>I<13FE3803FFC0380703E0380E00F05A1478123C123E123F1380EB + +E0F0381FF9E0EBFFC06C13806C13C06C13E04813F0381E7FF8383C1FFCEA7807EB01FEEA + +F000143E141EA36C131C007813387E001F13F0380FFFC00001130017207E9F1C>I<1238 + +127C12FEA3127C12381200A81238127C12FEA3127C123807167C9510>58 + +D<1470A214F8A3497EA2497EA3EB067FA2010C7F143FA2496C7EA201307F140F01707FEB + +6007A201C07F90B5FC4880EB8001A2D803007F14004880000680A23AFFE007FFF8A22522 + +7EA12A>65 D + +IIIIIIII75 DIIIII82 D<3801FE023807FF86381F01FE383C007E007C131E0078130EA2 + +00F81306A27E1400B4FC13E06CB4FC14C06C13F06C13F86C13FC000313FEEA003F1303EB + +007F143FA200C0131FA36C131EA26C133C12FCB413F838C7FFE00080138018227DA11F> + +I<007FB61280A2397E03F80F00781407007014030060140100E015C0A200C01400A40000 + +1500B3A248B512F0A222227EA127>I86 + +D97 DIII<13FE3807FF80380F87C0381E01 + +E0003E13F0EA7C0014F812FCA2B5FCA200FCC7FCA3127CA2127E003E13186C1330380FC0 + +703803FFC0C6130015167E951A>I<3801FE0F3907FFBF80380F87C7381F03E7391E01E0 + +00003E7FA5001E5BEA1F03380F87C0EBFF80D809FEC7FC0018C8FCA2121C381FFFE06C13 + +F86C13FE001F7F383C003F48EB0F80481307A40078EB0F006C131E001F137C6CB45A0001 + +13C019217F951C>103 DI<121C123E127FA3123E121CC7FCA7B4FCA2121FB2EAFFE0 + +A20B247EA310>I107 + +DI<3AFF07F007F090391FFC1FFC3A1F303E30 + +3E01401340496C487EA201001300AE3BFFE0FFE0FFE0A22B167E9530>I<38FF07E0EB1F + +F8381F307CEB403CEB803EA21300AE39FFE1FFC0A21A167E951F>I<13FE3807FFC0380F + +83E0381E00F0003E13F848137CA300FC137EA7007C137CA26C13F8381F01F0380F83E038 + +07FFC03800FE0017167E951C>I<38FF0FE0EB3FF8381FE07CEB803E497E1580A2EC0FC0 + +A8EC1F80A29038803F00EBC03EEBE0FCEB3FF8EB0FC090C8FCA8EAFFE0A21A207E951F> + +I114 + +DI<487EA412 + +03A21207A2120F123FB5FCA2EA0F80ABEB8180A5EB8300EA07C3EA03FEEA00F811207F9F + +16>I<38FF01FEA2381F003EAF147E14FE380F81BE3907FF3FC0EA01FC1A167E951F>I<39 + +FFE07FC0A2390F801C006C6C5A6C6C5AEBF0606C6C5A3800F980137F6DC7FC7F80497E13 + +37EB63E0EBC1F03801C0F848487E3807007E000E133E39FF80FFE0A21B167F951E>120 + +D<39FFE01FE0A2391F800700000F1306EBC00E0007130C13E000035BA26C6C5AA26C6C5A + +A2EB7CC0A2137F6D5AA26DC7FCA2130EA2130CA25B1278EAFC3813305BEA69C0EA7F8000 + +1FC8FC1B207F951E>I E /Fk 28 118 df<49B4FC011F13C090387F81E0EBFC013901F8 + +07F01203EA07F0A4EC01C091C8FCA3EC3FF8B6FCA33807F003B3A33A7FFF3FFF80A3212A + +7FA925>12 D45 D<130E131E137EEA07FE12FFA212F81200B3AB + +B512FEA317277BA622>49 DII< + +140FA25C5C5C5C5BA2EB03BFEB073F130E131C133C1338137013E0EA01C0EA0380120713 + +00120E5A5A5A12F0B612F8A3C7EA7F00A890381FFFF8A31D277EA622>I70 D<91387FE003903907FFFC07011FEB + +FF0F90397FF00F9F9039FF0001FFD801FC7F484880484880484880485A82485A82127FA2 + +90CAFC5AA892B512F87E7F03001300123FA26C7EA26C7E6C7E6C7E6C7E6CB45B90387FF0 + +07011FB5129F0107EBFE0F9039007FF0032D297CA835>I76 + +DII82 + +D<9038FF80600003EBF0E0000F13F8381F80FD383F001F003E1307481303A200FC1301A2 + +14007EA26C140013C0EA7FFCEBFFE06C13F86C13FE80000714806C14C0C6FC010F13E0EB + +007FEC1FF0140F140700E01303A46C14E0A26C13076C14C0B4EB0F80EBE03F39E3FFFE00 + +00E15B38C01FF01C297CA825>I<007FB71280A39039807F807FD87C00140F00781507A2 + +0070150300F016C0A2481501A5C791C7FCB3A490B612C0A32A287EA72F>I<3803FF8000 + +0F13F0381F01FC383F80FE147F801580EA1F00C7FCA4EB3FFF3801FC3FEA0FE0EA1F80EA + +3F00127E5AA4145F007E13DF393F839FFC381FFE0F3803FC031E1B7E9A21>97 + +D99 D101 D<1207EA0F80EA1FC0EA3FE0A3EA1FC0EA0F80EA0700C7FCA7 + +EAFFE0A3120FB3A3EAFFFEA30F2B7EAA12>105 D107 DI<26FFC07FEB1FC0903AC1FFC07FF0903AC307E0C1F8D80FC49038F101FC90 + +39C803F20001D801FE7F01D05BA201E05BB03CFFFE3FFF8FFFE0A3331B7D9A38>I<38FF + +C07E9038C1FF809038C30FC0D80FC413E0EBC80701D813F013D0A213E0B039FFFE3FFFA3 + +201B7D9A25>II<38FFE1FE9038EFFF809038FE0FE0390FF803F09038F001 + +F801E013FC140015FEA2157FA8157E15FEA215FC140101F013F89038F807F09038FC0FE0 + +9038EFFF809038E1FC0001E0C7FCA9EAFFFEA320277E9A25>I<38FFC1F0EBC7FCEBC63E + +380FCC7F13D813D0A2EBF03EEBE000B0B5FCA3181B7F9A1B>114 + +D<3803FE30380FFFF0EA3E03EA7800127000F01370A27E00FE1300EAFFE06CB4FC14C06C + +13E06C13F0000713F8C6FCEB07FC130000E0137C143C7E14387E6C137038FF01E038E7FF + +C000C11300161B7E9A1B>I<13E0A41201A31203A21207120F381FFFE0B5FCA2380FE000 + +AD1470A73807F0E0000313C03801FF8038007F0014267FA51A>I<39FFE07FF0A3000F13 + +07B2140FA2000713173903F067FF3801FFC738007F87201B7D9A25>I + +E /Fl 21 86 df45 D<13181330EA03F0EA0C701200A313 + +E0A6EA01C0A6EA0380A6EA07001380EAFFF80D1C7C9B15>49 D<137E38018380380201C0 + +380400E0A2120FA25AA2120EEA000114C0EB0380A2EB0700130E5B5B13605B485A380300 + +801206380801001210EA3FFF485A12FF131C7E9B15>I<137CEA0187380203801204000F + +13C0A3000E13801200EB070013065B1338EA03F0EA001C7FA2130FA3127012F8A2EAF00E + +EAE01EEA801CEA4038EA3070EA0F80121D7D9B15>I<14C0EB01801303A21307130B1313 + +EB2700136713C71387EA01071202EA040E12081218121012201240B512C038001C00A55B + +133C3803FF80121C7E9B15>I<14201430147014F0A2130180EB0278A21304A213088013 + +10A21320A2EB403E141EEBFFFEEB801EEA0100141F00027FA25A120C001E148039FF807F + +F01C1D7F9C1F>65 D<903807F01090381C0C3090387002609038C001E03803800048C7FC + +000E1460A2481440123C123800781400A35AA51580EC01001270A26C13025C7E000C1318 + +6C1320380380C0D8007FC7FC1C1E7C9C1E>67 D<0007B512E03800F801EBF0001540A448 + +5A14201500A2146014E048B45A13C01440A3158038078000A2EC0100A25C1406380F000E + +143EB512FC1B1C7E9B1C>69 D<0007B512C03800F803EBF001EC0080A4485A14201500A2 + +146014E048B45A13C01440A44848C7FCA648C8FC7FEAFFF81A1C7E9B1B>I<903807F010 + +90381C0C3090387002609038C001E03803800048C7FC000E1460A2481440123C12380078 + +1400A35AA3ECFFF0EC0F801407EC0F001270A27EA26C5B000C131E6C136638038182D800 + +7EC7FC1C1E7C9C21>I73 D<3907FF80FF3900F8007849136015401580EC0100140448485A + +5C5C5C14C0EBE3E0EA03C5EBC9F013D0EBE0F8EBC078147C3807803C143E141E141F8015 + +80380F00079038800FC039FFF03FF0201C7F9B20>75 D<3807FFC03800F8005BA5485AA6 + +485AA51404EA0780A31408A21418380F003814F0B5FC161C7E9B1A>IIII<3807FFFC3800 + +F80F9038F0038015C01401A33801E003A31580EC0700140E3803C03CEBFFE001C0C7FCA4 + +485AA648C8FC7FEAFFF01A1C7E9B1C>I<380FFFF83800F80E9038F00780EC03C0140115 + +E0A23901E003C0A21580EC0700140E143C3803FFE0EBC078141C141E140E140F3807801E + +A51508D80F001310138039FFF00E20C7EA03C01D1D7E9B1F>82 DI< + +001FB512F0383C07C00030EB80300020142012601240A2EB0F00128000001400A4131EA6 + +5BA65B137C381FFFE01C1C7C9B1E>I<39FFF01FF0391F000780001EEB03001402A4485B + +A6485BA6485BA212705CA26C5B5C6C48C7FCEA0E0EEA01F01C1D7A9B1F>I + +E /Fm 78 124 df11 D<137E3801C180EA0301380703C0120EEB + +018090C7FCA5B512C0EA0E01B0387F87F8151D809C17>II34 D<126012F012F812681208A31210A212 + +2012401280050C7C9C0C>39 D<1380EA0100120212065AA25AA25AA35AA412E0AC1260A4 + +7EA37EA27EA27E12027EEA0080092A7C9E10>I<7E12407E12307EA27EA27EA37EA41380 + +AC1300A41206A35AA25AA25A12205A5A092A7E9E10>I<1306ADB612E0A2D80006C7FCAD + +1B1C7E9720>43 D<126012F0A212701210A41220A212401280040C7C830C>II<126012F0A2126004047C830C>I<130113031306A3130CA31318A31330A3 + +1360A213C0A3EA0180A3EA0300A31206A25AA35AA35AA35AA35AA210297E9E15>II<5A1207123F12C71207B3A5EAFFF80D1C7C9B15>III<130CA2131C133C + +A2135C13DC139CEA011C120312021204120C1208121012301220124012C0B512C038001C + +00A73801FFC0121C7F9B15>II<13F0EA030CEA0404EA0C0EEA181E1230130CEA7000A21260EAE3E0EAE430EAE818 + +EAF00C130EEAE0061307A51260A2EA7006EA300E130CEA1818EA0C30EA03E0101D7E9B15 + +>I<1240387FFF801400A2EA4002485AA25B485AA25B1360134013C0A212015BA21203A4 + +1207A66CC7FC111D7E9B15>III<126012F0A212601200AA126012F0A2126004127C91 + +0C>I<126012F0A212601200AA126012F0A212701210A41220A212401280041A7C910C>I< + +B612E0A2C9FCA8B612E0A21B0C7E8F20>61 D64 D<1306A3130FA3EB1780A2EB37C01323A2EB43E01341A2EB80F0A338010078A2 + +EBFFF83802003CA3487FA2000C131F80001E5BB4EBFFF01C1D7F9C1F>II<90381F8080EBE0613801801938070007000E13035A14015A007813 + +00A2127000F01400A8007014801278A212386CEB0100A26C13026C5B380180083800E030 + +EB1FC0191E7E9C1E>IIII<90381F8080EBE0613801801938070007000E13035A14015A + +00781300A2127000F01400A6ECFFF0EC0F80007013071278A212387EA27E6C130B380180 + +113800E06090381F80001C1E7E9C21>I<39FFF0FFF0390F000F00AC90B5FCEB000FAD39 + +FFF0FFF01C1C7F9B1F>II<3807FF8038007C00 + +133CB3127012F8A21338EA7078EA4070EA30E0EA0F80111D7F9B15>I<39FFF01FE0390F + +000780EC060014045C5C5C5C5C49C7FC13021306130FEB17801327EB43C0EB81E013016D + +7E1478A280143E141E80158015C039FFF03FF01C1C7F9B20>IIIIII82 D<3807E080EA1C19EA30051303EA600112 + +E01300A36C13007E127CEA7FC0EA3FF8EA1FFEEA07FFC61380130FEB07C0130313011280 + +A300C01380A238E00300EAD002EACC0CEA83F8121E7E9C17>I<007FB512C038700F0100 + +60130000401440A200C014201280A300001400B1497E3803FFFC1B1C7F9B1E>I<39FFF0 + +1FF0390F000380EC0100B3A26C1302138000035BEA01C03800E018EB7060EB0F801C1D7F + +9B1F>I<39FFE00FF0391F0003C0EC01806C1400A238078002A213C000035BA2EBE00C00 + +011308A26C6C5AA213F8EB7820A26D5AA36D5AA2131F6DC7FCA21306A31C1D7F9B1F>I< + +3AFFE1FFC0FF3A1F003E003C001E013C13186C6D1310A32607801F1320A33A03C0278040 + +A33A01E043C080A33A00F081E100A39038F900F3017913F2A2017E137E013E137CA2013C + +133C011C1338A20118131801081310281D7F9B2B>I<12FEA212C0B3B312FEA207297C9E + +0C>91 DI<12FEA21206B3B312FEA20729809E0C>I97 + +D<12FC121CAA137CEA1D87381E0180381C00C014E014601470A6146014E014C0381E0180 + +38190700EA10FC141D7F9C17>IIII<13F8EA018CEA071E1206EA0E0C1300A6EAFFE0EA0E00B0EA7F + +E00F1D809C0D>II<12FC121CAA137C1387EA1D03001E1380121CAD38 + +FF9FF0141D7F9C17>I<1218123CA21218C7FCA712FC121CB0EAFF80091D7F9C0C>I<13C0 + +EA01E0A2EA00C01300A7EA07E01200B3A21260EAF0C012F1EA6180EA3E000B25839C0D> + +I<12FC121CAAEB0FE0EB0780EB06005B13105B5B13E0121DEA1E70EA1C781338133C131C + +7F130F148038FF9FE0131D7F9C16>I<12FC121CB3A9EAFF80091D7F9C0C>I<39FC7E07E0 + +391C838838391D019018001EEBE01C001C13C0AD3AFF8FF8FF8021127F9124>IIII<3803E080EA0E19EA1805EA3807EA7003A212E0 + +A61270A2EA38071218EA0E1BEA03E3EA0003A7EB1FF0141A7F9116>II + +I<1204A4120CA2121C123CEAFFE0EA1C00A91310A5120CEA0E20EA03C00C1A7F9910>I< + +38FC1F80EA1C03AD1307120CEA0E1B3803E3F014127F9117>I<38FF07E0383C0380381C + +0100A2EA0E02A2EA0F06EA0704A2EA0388A213C8EA01D0A2EA00E0A3134013127F9116> + +I<39FF3FC7E0393C0703C0001CEB01801500130B000E1382A21311000713C4A213203803 + +A0E8A2EBC06800011370A2EB8030000013201B127F911E>I<38FF0FE0381E0700EA1C06 + +EA0E046C5AEA039013B0EA01E012007F12011338EA021C1204EA0C0E487E003C138038FE + +1FF014127F9116>I<38FF07E0383C0380381C0100A2EA0E02A2EA0F06EA0704A2EA0388 + +A213C8EA01D0A2EA00E0A31340A25BA212F000F1C7FC12F312661238131A7F9116>III E /Fn + +22 118 df<127012F812FCA212741204A41208A21210A212201240060F7C840E>44 + +D<13801203120F12F31203B3A9EA07C0EAFFFE0F217CA018>49 D<137EEA01C138030080 + +380601C0EA0C03121C381801800038C7FCA212781270A2EAF0F8EAF30CEAF4067F00F813 + +80EB01C012F014E0A51270A3003813C0A238180380001C1300EA0C06EA070CEA01F01322 + +7EA018>54 D<12401260387FFFE014C0A23840008038C0010012801302A2485A5BA25B5B + +A21360134013C0A21201A25B1203A41207A76CC7FC13237DA118>I57 + +D<903807E0109038381830EBE0063901C0017039038000F048C7FC000E1470121E001C14 + +30123CA2007C14101278A200F81400A812781510127C123CA2001C1420121E000E14407E + +6C6C13803901C001003800E002EB381CEB07E01C247DA223>67 DI<3803FFE038001F007FB3A6127012 + +F8A2130EEAF01EEA401C6C5AEA1870EA07C013237EA119>74 D<39FFFC07FF390FC000F8 + +6C4813701520B3A5000314407FA2000114806C7E9038600100EB3006EB1C08EB03F02023 + +7EA125>85 D<120E12FE121E120EAB131FEB61C0EB8060380F0030000E1338143C141C14 + +1EA7141C143C1438000F1370380C8060EB41C038083F0017237FA21B>98 + +DI<14E0130F13011300ABEA01F8EA0704EA0C02 + +EA1C01EA38001278127012F0A7127012781238EA1801EA0C0238070CF03801F0FE17237E + +A21B>II<120E12FE121E120E + +ABEB1F80EB60C0EB80E0380F0070A2120EAF38FFE7FF18237FA21B>104 + +D<121C123EA3121CC7FCA8120E127E121E120EB1EAFFC00A227FA10E>I<390E1FC07F3A + +FE60E183803A1E807201C03A0F003C00E0A2000E1338AF3AFFE3FF8FFE27157F942A> + +109 D<380E1F8038FE60C0381E80E0380F0070A2120EAF38FFE7FF18157F941B>II114 DI<1202A41206A3120E121E123EEAFFFCEA0E00AB1304A6EA07081203EA01 + +F00E1F7F9E13>I<000E137038FE07F0EA1E00000E1370AD14F0A2380601703803827838 + +00FC7F18157F941B>I E /Fo 12 118 df75 + +DIII97 + +DI<16FC153FA315011500167CB3A414FF01 + +0713E090381F80F090387E001C01F81306484813034848EB01FC485A000F140049147C12 + +1F48C8FCA35A127EA212FEAA127EA2127FA27EA26C7E16FC120F6C6C13016C6CEB037C6C + +6C13066C6CEB0C7E017CEB387F90263F80F013F890380FFFC0903801FE002D487DC735> + +100 D<49B4FC010F13E090381F03F090387C00FC49133ED801E07F000315804848130F48 + +4814C0001F140716E048C7FCA21503007E15F0A312FEB7FCA248C9FCA7127EA2127F7EA2 + +6C6C1430A2000F15607F6C6C14C0000314016C6C1480D800FCEB0700013F130E90381FC0 + +78903807FFE001001380242C7EAB2A>I103 + +D108 + +D<3903F003FC00FFEB1FFF9138380FC091386003E0000790388001F0D803F1C77EEA01F2 + +13F601F4147C13F8A35BB3AA486C14FEB539E03FFFF8A32D2C7DAB35>110 + +D117 + +D E end + +%%EndProlog + +%%BeginSetup + +%%Feature: *Resolution 300dpi + +TeXDict begin + +%%PaperSize: Letter + + + +%%EndSetup + +%%Page: 1 1 + +1 0 bop 648 508 a Fo(LN)31 b(Kdebug)g(Man)m(ual)988 655 + +y Fn(Jo)q(c)o(hen)739 714 y Fm(IBM)14 b(T.)g(J.)f(W)m(atson)g(Researc)o + +(h)i(Cen)o(ter)841 772 y(jo)q(c)o(hen@w)o(atson.ibm.com)860 + +952 y Fn(Decem)o(b)q(er)f(16,)i(1997)849 1002 y(Under)g(Construction)p + +eop + +%%Page: 1 2 + +1 1 bop 161 155 a Fl(1)41 b(GENERAL)14 b(REMARKS)1281 + +b Fm(1)161 300 y Fk(1)67 b(General)23 b(Remarks)161 400 + +y Fj(Ab)r(out)c(LNKD)161 476 y Fm(LN)12 b(Kdebug)h(\(LNKD\))f(is)f + +(primarily)e(a)j(to)q(ol)f(to)h(test)h(LN)f(and)f(to)h(\014x)g(bugs)g + +(in)f(LN.)g(Ho)o(w)o(ev)o(er,)h(it)g(can)g(sometimes)161 + +526 y(also)h(b)q(e)i(useful)f(for)g(testing)g(higher)g(la)o(y)o(ers.)k + +(Consequen)o(tly)m(,)223 609 y Fi(\017)j Fm(LNKD)13 b(alw)o(a)o(ys)e + +(freezes)k(the)e(en)o(tire)g(mac)o(hine)e(state)i(when)g(in)o(v)o(ok)o + +(ed.)k(All)12 b(in)o(terrupts)h(are)g(disabled,)g(ev)o(en)265 + +659 y(the)h(clo)q(c)o(k)g(is)g(halted.)k(No)c(k)o(ernel)g(or)g(user)h + +(pro)q(cess)h(pro)q(ceeds)g(while)d(LNKD)h(is)g(activ)o(e.)223 + +742 y Fi(\017)21 b Fm(LNKD)c(is)g(a)f(stand-alone)h(debugger.)28 + +b(It)17 b(do)q(es)h(neither)f(use)h(parts)g(of)e(LN)h(nor)g(other)g + +(device)h(driv)o(ers.)265 792 y(LNKD)e(includes)h(simple)e(device)i + +(driv)o(ers)h(for)e(k)o(eyb)q(oard,)g(displa)o(y)g(\(CGA\),)g(and)g + +(the)h(serial)f(in)o(terfaces)265 842 y(COM1)e(and)g(COM2.)k(These)d + +(device)g(driv)o(ers)f(are)g Fh(not)h Fm(in)o(terrupt)f(driv)o(en.)223 + +925 y(Although)i(dev)o(elop)q(ed)h(together)g(with)f(the)h(La)o(v)n(a)e + +(Nucleus)i(\(LN\))g(and)f(traditionally)e(pac)o(k)n(aged)i(together)161 + +974 y(with)g(LN,)f(the)h(LN)g(Kdebug)h(\(LNKD\))f(is)f + +Fh(not)i Fm(part)f(of)f(the)h(LN)g Fg(\026)p Fm(-k)o(ernel.)24 + +b(LN)16 b(can)g(run)g(without)f(LNKD)h(or)161 1024 y(with)h(another)g + +(k)o(ernel)g(debugger.)27 b(There)17 b(is)g(no)f(other)h(connection)h + +(b)q(et)o(w)o(een)g(LN)e(and)h(LNKD)f(that)h(LNKD)161 + +1074 y(in)o(timately)12 b(kno)o(ws)h(LN's)h(data)g(structures.)161 + +1190 y Fj(Ab)r(out)19 b(Exception)e(Handling)161 1267 + +y Fm(LNKD)e(is)g(in)o(v)o(ok)o(ed)g(b)o(y)g(exceptions,)h(in)f + +(particular)g(b)o(y)g(the)g(debug)h(exception)g(\(INT)f(1\))g(and)g + +(the)h(breakp)q(oin)o(t)161 1317 y(exception)i(\(INT)g(3\).)27 + +b(Some)16 b(exceptions)i(are)g(handled)f(normally)e(b)o(y)i(LN,)f(for)h + +(example)f(a)h(page)g(fault.)27 b(All)161 1367 y(other)18 + +b(exceptions)g(are)g(distributed)g(b)o(y)f(LN)g(either)h(to)f(LNKD)g + +(or)h(to)f(the)g(curren)o(t)i(user-lev)o(el)f(thread.)29 + +b(The)161 1416 y(according)14 b(algorithm)d(is:)223 1513 + +y(exception)k(dispatc)o(h:)286 1563 y Ff(if)d Fm(excption)j(o)q + +(ccurred)g(in)f(k)o(ernel)348 1613 y Ff(then)30 b Fm(in)o(v)o(ok)o(e)13 + +b(LNKD)g(with)h(k)o(ernel)g(error)286 1663 y Ff(elif)e + +Fm(curren)o(t)j(thread)g(de\014ned)f(an)g(IDT)g(AND)f(corresp)q(onding) + +i(IDT)f(en)o(try)1503 1659 y Fe(6)p Fd(=)1529 1663 y + +Fm(0)348 1712 y Ff(then)30 b Fm(in)o(v)o(ok)o(e)13 b(user-lev)o(el)h + +(exception)h(handler)f(b)o(y)f(up)q(call)348 1762 y Ff(else)48 + +b Fm(in)o(v)o(ok)o(e)13 b(LNKD)g(with)h(user)h(error)286 + +1812 y Ff(\014)e Fm(.)161 1860 y(Summarizing:)h(LNKD)f(is)g(used)h(for) + +f(k)o(ernel)g(errors.)19 b(It)13 b(is)g(used)h(for)f(user)h(errors)g + +(only)e(as)h(long)g(as)g(no)f(debugger)161 1910 y(is)h(installed)g(at)f + +(user)j(lev)o(el.)i Fh(\(LNKD's)d(user-level)f(fe)n(atur)n(es)h(might)g + +(disapp)n(e)n(ar)g(in)g(pr)n(o)n(duction)h(versions)f(of)g(LN.)p + +eop + +%%Page: 2 3 + +2 2 bop 161 155 a Fl(2)41 b(LN-SPECIFIC)15 b(FUNCTIONS)1185 + +b Fm(2)161 300 y Fk(2)67 b(LN-Sp)r(eci\014c)24 b(F)-6 + +b(unctions)161 400 y Fj(2.1)56 b(Thread)18 b(Con)n(trol)i(Blo)r(c)n(k:) + +j Fc(t)161 476 y Fm(Displa)o(ys)18 b(the)h Fh(c)n(ommente)n(d)h(thr)n + +(e)n(ad)f(c)n(ontr)n(ol)g(blo)n(ck)p Fm(,)g(the)h(thread's)f + +Fh(kernel)g(stack)p Fm(,)g(and)g(the)g(thread's)g Fh(gener)n(al)161 + +526 y(purp)n(ose)c(r)n(e)n(gisters)p Fm(.)p 161 632 1802 + +2 v 186 716 a Fc(t)447 b Fm(displa)o(ys)13 b(the)i(thread)f(con)o(trol) + +g(blo)q(c)o(k)g(of)f(the)h(curren)o(t)i(thread.)186 816 + +y Fc(t)p Fg(xxxx)351 b Fm(displa)o(ys)17 b(the)g(thread)h(con)o(trol)f + +(blo)q(c)o(k)g(of)g(thread)h Fg(xxxx)p Fm(.)27 b Fg(xxxx)16 + +b Fm(is)h(the)h(global)651 866 y(thread)d(n)o(um)o(b)q(er)e + +(\(hexadecimal\);)f(leading)h(zeros)i(can)f(b)q(e)h(omitted.)186 + +965 y Fc(t)p Fg(xxx:y)q(y)322 b Fm(displa)o(ys)13 b(the)h(thread)g(con) + +o(trol)f(blo)q(c)o(k)g(of)g(thread)h Fg(y)q(y)i Fm(of)d(task)g + +Fg(xxx)p Fm(.)k Fg(xxx)c Fm(and)g Fg(y)q(y)651 1015 y + +Fm(are)j(b)q(oth)g(hexadecimal;)f(leading)g(zeros)i(ma)o(y)d(b)q(e)i + +(omitted.)22 b(F)m(or)16 b(example,)e(in)651 1065 y(LN)e(v)o(ersion)g + +(2,)g(thread)g(1)g(of)f(task)h(4)g(can)g(b)q(e)g(denoted)h(b)o(y)f + +(4.01)e(or)i(b)o(y)g(the)h(global)651 1115 y(thread)i(n)o(um)o(b)q(er)e + +(201.)p 161 1181 V 186 1266 a(thread)i(con)o(trol)e(blo)q(c)o(k)98 + +b(The)14 b(\014elds)h(of)e(the)h(thread)h(con)o(trol)f(blo)q(c)o(k)f + +(are)i(lab)q(eled.)186 1365 y(k)o(ernel)f(stac)o(k)251 + +b(The)15 b(k)o(ernel)f(stac)o(k)h(of)e(the)i(displa)o(y)o(ed)e(thread)i + +(is)f(dump)q(ed)f(from)g(stac)o(k)h(b)q(ottom)651 1415 + +y(\(lo)o(w)o(er)g(righ)o(t)g(corner\))i(up)e(to)g(the)h(curren)o(t)h + +(stac)o(k)f(top.)k(When)c(en)o(tering)f(k)o(ernel)651 + +1465 y(mo)q(de,)g(the)h(pro)q(cessor)i(\014rst)f(pushes)g(SS,)f(ESP)m + +(,)g(EFLA)o(GS,)f(CS)h(and)g(EIP)g(on)o(to)651 1515 y(the)g(k)o(ernel)f + +(stac)o(k.)k(So)c(the)g(lo)o(w)o(est)g(line)g(lo)q(oks)f(alw)o(a)o(ys)g + +(lik)o(e)955 1573 y Fb(.)6 b(.)h(.)p 1010 1532 162 2 + +v 1010 1585 2 54 v 20 w(userEIP)p 1170 1585 V 1010 1587 + +162 2 v 1185 1532 148 2 v 1185 1585 2 54 v 42 w(userCS)p + +1331 1585 V 1185 1587 148 2 v 1347 1532 247 2 v 1347 + +1585 2 54 v 43 w(userEFLA)o(GS)p 1592 1585 V 1347 1587 + +247 2 v 1607 1532 173 2 v 1607 1585 2 54 v 42 w(userESP)p + +1778 1585 V 1607 1587 173 2 v 1794 1532 145 2 v 1794 + +1585 2 54 v 43 w(userSS)p 1936 1585 V 1794 1587 145 2 + +v 186 1672 a Fm(registers)316 b(are)12 b(displa)o(y)o(ed)f(if)g(the)h + +Fh(curr)n(ently)g(active)f Fm(thread)i(is)e(displa)o(y)o(ed.)17 + +b(F)m(or)11 b(this)h(thread,)651 1722 y(LNKD)i(kno)o(ws)g(that)g(the)h + +(registers)g(are)g(pushed)g(b)q(ey)o(ond)f(the)h(displa)o(y)o(ed)e + +(stac)o(k)651 1772 y(top.)22 b(Dep)q(ending)16 b(on)f(their)g(state,)h + +(other)g(threads)g(migh)o(t)d(not)j(ha)o(v)o(e)f(sa)o(v)o(ed)g(all)651 + +1822 y(their)f(registers)i(on)d(the)i(stac)o(k.)651 1872 + +y(With)k(the)g(cursor)i(k)o(eys,)f(the)g(virtual)e(top)i(of)e(the)i + +(displa)o(y)o(ed)e(k)o(ernel)i(thread)651 1921 y(can)14 + +b(b)q(e)g(c)o(hanged.)k(When)c(pressing)g(the)g(en)o(ter)g(k)o(ey)m(,)f + +(LNKD)g(assumes)h(that)f(the)651 1971 y(curren)o(t)19 + +b(stac)o(k)g(top)f(holds)f(a)h(return)h(address)g(and)f(all)f + +(registers)i(are)g(pushed)651 2021 y(b)q(ey)o(ond)e(and)f(accordingly)g + +(displa)o(ys)g(the)h(register)h(v)n(alues.)25 b(This)16 + +b(feature)i(can)651 2071 y(b)q(e)c(used)h(for)e(k)o(ernel)i(stac)o(ks)f + +(of)f(the)i(curren)o(tly)f(activ)o(e)g(thread)h(as)e(w)o(ell)g(as)h + +(other)651 2121 y(threads.)p 161 2187 1802 2 v eop + +%%Page: 3 4 + +3 3 bop 161 155 a Fl(2)41 b(LN-SPECIFIC)15 b(FUNCTIONS)1185 + +b Fm(3)161 300 y Fj(2.2)56 b(Mo)r(dules:)24 b Fc(a)161 + +377 y Fm(Displa)o(ys)13 b(LN)h(mo)q(dules)f(and)h(helps)g(to)g(deco)q + +(de)h(LN)f(addresses)i(to)e(mo)q(dule-relativ)o(e)e(addresses.)p + +161 441 1802 2 v 186 525 a Fc(a)442 b Fm(displa)o(ys)18 + +b(a)g(list)g(of)f(all)g(LN)i(mo)q(dules,)f(LN)g(Kdebug)h(mo)q(dules,)f + +(Sigma0,)e(and)651 575 y(Ktest.)23 b(The)15 b(list)g(con)o(tains)g + +(name,)f(date)h(and)g(base)h(address\(es\))h(of)d(its)h(k)o(co)q(de-) + +651 625 y(and)10 b(co)q(de-segmen)o(ts)h(\(for)e(k)o(ernel)i(mo)q + +(dules\),)e(or)h(dco)q(de)h(segmen)o(ts)f(\(for)g(LNKD\),)651 + +675 y(or.)34 b(sco)q(de)21 b(segmen)o(ts)e(for)g(Sigma0.)32 + +b(Ico)q(de)20 b(segmen)o(t)f(and)g(co)q(de16)g(segmen)o(t)651 + +725 y(addresses)d(are)d(not)h(includeded.)k(The)c(rep)q(orted)h(base)f + +(addresses)h(can)f(b)q(e)g(used)651 775 y(for)g(setting)g(breakp)q(oin) + +o(ts)g(relativ)o(ely)f(to)h(the)g(b)q(eginning)g(of)f(mo)q(dules)g + +(\(see)i Fb(bb)p Fm(\).)186 874 y Fc(a)p Fg(xxxx)346 + +b Fm(\014nds)23 b(the)g(k)o(ernel)g(mo)q(dule)e(that)h(corresp)q(onds)i + +(to)f(ph)o(ysical)e(address)j Fg(xxxx)651 924 y Fm(pro)o(vided)17 + +b(that)h Fg(xxxx)e Fm(lies)h(in)g(one)h(of)f(the)h(k)o(co)q(de-,)g(co)q + +(de-,)g(dco)q(de-)g(or)g(sco)q(de-)651 974 y(segmen)o(ts)g(men)o + +(tioned)f(ab)q(o)o(v)o(e.)29 b(It)18 b(giv)o(es)g(base)h(address)g + +Fg(B)h Fm(of)d(the)i(according)651 1024 y(mo)q(dule)13 + +b(segemen)o(t)i(and)g(o\013set)g(address)h Fg(X)j Fm(so)c(that)f + +Fg(B)f Fm(+)d Fg(X)17 b Fm(=)c Fg(xxxx)p Fm(.)19 b Fg(X)g + +Fm(can)651 1073 y(b)q(e)g(used)h(for)e(the)i(iden)o(tifying)d(the)i(co) + +q(de)g(b)o(y)g(means)f(of)g(a)g(listing)g(or)g(setting)651 + +1123 y(breakp)q(oin)o(ts)c(relativ)o(e)g(to)g(the)g(mo)q(dule.)651 + +1173 y Fg(xxxx)f Fm(is)h(a)f(hexadecimal)g(n)o(um)o(b)q(er.)k(Leading)c + +(zeros)i(can)f(b)q(e)h(omitted.)p 161 1239 V 161 1461 + +a Fj(2.3)56 b(Kernel)17 b(Data:)25 b Fc(k)161 1537 y + +Fm(Displa)o(ys)13 b(some)g(global)f(LN)i(k)o(ernel)h(data.)p + +161 1601 V 186 1686 a Fc(k)441 b Fm(displa)o(ys)13 b(some)g(k)o(ernel)i + +(data)e(that)h(is)g(not)g(thread)g(sp)q(eci\014c.)p 161 + +1752 V 161 1974 a Fj(2.4)56 b(Mapping:)25 b(m)161 2050 + +y Fm(P)o(ermits)14 b(to)f(parse)i(the)f(LN)g(mapping)e(database.)p + +161 2114 V 186 2199 a Fc(m)p Fg(xxxx)330 b Fm(starts)11 + +b(parsing)e(the)h(mapping)d(subtree)12 b(corresp)q(onding)e(to)g(ph)o + +(ysical)f(page)g(frame)651 2248 y Fg(xxxx)p Fm(000.)15 + +b(The)d(cursor)g(k)o(eys)f(can)g(b)q(e)h(used)f(to)g(pro)q(ceed)i(to)d + +(paren)o(t-,)i(c)o(hild-,)e(and)651 2298 y(sister-en)o(tries.)p + +161 2365 V eop + +%%Page: 4 5 + +4 4 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(4)161 300 y Fk(3)67 b(General)23 b(T)-6 b(est)22 + +b(F)-6 b(unctions)161 400 y Fj(3.1)56 b(Breakp)r(oin)n(t:)23 + +b Fc(b)161 476 y Fm(Sets/resets)17 b(one)d(global)e(breakp)q(oin)o(t)i + +(for)g(k)o(ernel-mo)q(de)f(and)g(user)i(mo)q(de.)p 161 + +542 1802 2 v 186 627 a Fc(b)440 b Fm(displa)o(ys)13 b(the)i(curren)o(t) + +g(breakp)q(oin)o(t.)186 727 y Fc(bi)f Fm(.)7 b(.)f(.)366 + +b(sets)15 b(an)f(instruction)g(breakp)q(oin)o(t.)186 + +785 y Fc(b)o(w)p Fi(f)p Fm(1,2,4)p Fi(g)e Fm(.)6 b(.)h(.)218 + +b(sets)15 b(a)f(data-write)g(breakp)q(oin)o(t)f(for)h(a)g(1-,)e(2-)i + +(or)g(4-b)o(yte)g(v)n(ariable.)186 843 y Fc(ba)p Fi(f)p + +Fm(1,2,4)p Fi(g)e Fm(.)7 b(.)f(.)227 b(sets)15 b(a)f(data-access)h + +(breakp)q(oin)o(t)f(for)f(a)h(1-,)f(2-)g(or)h(4-b)o(yte)g(v)n(ariable.) + +186 901 y Fc(bp)p Fi(f)p Fm(1,2,4)p Fi(g)e Fm(.)6 b(.)h(.)225 + +b(sets)15 b(a)f(breakp)q(oin)o(t)g(for)f(in/out)g(to)h(a)g(1-,)f(2-)g + +(or)h(4-b)o(yte)g(io)f(p)q(ort.)283 959 y(.)6 b(.)h(.)20 + +b Fg(xxxxxxxx)107 b Fm(The)24 b(breakp)q(oin)o(t)g(address)h(can)f(b)q + +(e)h(absolute)f(or)g(relativ)o(e.)47 b(If)24 b(no)g(break-)651 + +1009 y(p)q(oin)o(t)13 b(base)h(address)g(w)o(as)g(sp)q(eci\014ed)g(b)q + +(efore)g(\(see)h(b)q(elo)o(w\))e(or)h(if)e(the)i(breakp)q(oin)o(t)651 + +1059 y(base)j(address)g Fg(B)i Fm(is)d(0,)f Fg(xxxxxxxx)f + +Fm(is)i(the)h(breakp)q(oin)o(t)f(address.)26 b(Otherwise,)651 + +1109 y Fg(B)12 b Fm(+)f Fg(xxxxxxxx)h Fm(is)j(the)g(breakp)q(oin)o(t)g + +(address.)22 b Fg(xxxxxxxx)12 b Fm(is)j(a)f(hexadecimal)651 + +1158 y(n)o(um)o(b)q(er)f(where)i(leading)e(zeros)i(can)f(b)q(e)h + +(omitted.)186 1258 y Fc(bb)p Fg(xxxxxxxx)223 b Fm(sets)16 + +b(the)f(breakp)q(oin)o(t)g(base)g(address)h Fg(B)h Fm(to)d + +Fg(xxxxxxxx)p Fm(.)k Fg(xxxxxxxx)13 b Fm(is)h(a)h(hex-)651 + +1308 y(adecimal)d(n)o(um)o(b)q(er)h(where)i(leading)e(zeros)i(can)f(b)q + +(e)h(omitted.)186 1407 y Fc(b-)424 b Fm(resets)16 b(the)e + +(system-global)e(breakp)q(oin)o(t.)p 161 1474 V 186 1558 + +a Fc(b)o(r)h Fm(.)7 b(.)f(.)362 b(restricts)15 b(the)f(breakp)q(oin)o + +(t.)j(The)d(breakp)q(oin)o(t)f(exception)h(in)o(v)o(ok)o(es)f(LNKD)g + +(only)651 1608 y(when)j(all)d(set)j(restrictions)g(are)g(met.)k + +(Otherwise,)d(the)e(breakp)q(oin)o(t)g(exception)651 + +1658 y(is)f(ignored.)186 1758 y Fc(b)o(rt)p Fg(xxxx)310 + +b Fm(restricts)16 b(breakp)q(oin)o(ts)e(to)g(thread)g + +Fg(xxxx)p Fm(.)186 1857 y Fc(b)o(rT)p Fg(xxxx)295 b Fm(restricts)16 + +b(breakp)q(oin)o(ts)e(to)g(threads)1235 1853 y Fe(6)p + +Fd(=)1260 1857 y Fg(xxxx)p Fm(.)186 1957 y Fc(b)o(r)p + +Fi(f)p Fb(eax,eb)o(x,ecx,edx,ebp,esi,edi,eip)p Fi(g)186 + +2007 y Fm([)p Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)q(;)7 + +b(z)r(z)r(z)r(z)s(z)r(z)r(z)r(z)r Fm(])82 b(The)13 b(sp)q(eci\014ed)h + +(register)g(\(or)e(the)h(instruction)g(p)q(oin)o(ter)g(eip\))g(m)o(ust) + +e(ha)o(v)o(e)h(a)g(v)n(alue)651 2057 y(in)h(the)h(sp)q(eci\014ed)g(in)o + +(terv)n(al)f(\(if)f Fg(y)q(y)q(y)q(y)r(y)q(y)r(y)r(y)1311 + +2053 y Fe(\024)1340 2057 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r + +Fm(\))i(or)f(outside)h(the)g(in)o(terv)n(al)651 2106 + +y([)p Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r(;)7 b(y)q(y)q(y)q(y)q(y)r(y)r + +(y)r(y)r Fm(])16 b(if)d Fg(y)q(y)q(y)q(y)r(y)q(y)r(y)r(y)1260 + +2102 y Fa(>)1289 2106 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r + +Fm(.)186 2206 y Fc(b)o(r)p Fi(f)p Fb(1,2,4)p Fi(g)p Fg(xxx)o(xxxx)o(x) + +186 2256 y Fm([)p Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)q(;)7 + +b(z)r(z)r(z)r(z)s(z)r(z)r(z)r(z)r Fm(])651 2206 y(The)26 + +b(sp)q(eci\014ed)i(1-,)f(2-)f(or)g(4-b)o(yte)f(v)n(ariable)g(m)o(ust)g + +(ha)o(v)o(e)g(a)h(v)n(alue)f(in)g(the)651 2256 y(sp)q(eci\014ed)32 + +b(in)o(terv)n(al)d(\(if)g Fg(y)q(y)q(y)q(y)r(y)r(y)q(y)r(y)1243 + +2252 y Fe(\024)1272 2256 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r + +Fm(\))i(or)g(outside)f(the)h(in)o(terv)n(al)651 2306 + +y([)p Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r(;)7 b(y)q(y)q(y)q(y)q(y)r(y)r + +(y)r(y)r Fm(])16 b(if)d Fg(y)q(y)q(y)q(y)r(y)q(y)r(y)r(y)1260 + +2302 y Fa(>)1289 2306 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r + +Fm(.)186 2405 y Fc(b)o(r-)408 b Fm(All)13 b(breakp)q(oin)o(t)h + +(restrictions)h(are)f(reset.)p 161 2472 V 186 2556 a(Note:)367 + +b(Breakp)q(oin)o(t)22 b(base)g(and)f(breakp)q(oin)o(t)g(restrictions)i + +(are)f Fh(not)f Fm(reset)i(when)f(the)651 2606 y(breakp)q(oin)o(t)13 + +b(address)h(or)f(t)o(yp)q(e)g(are)h(c)o(hanged)f(or)g(when)g(the)h + +(breakp)q(oin)o(t)e(is)h(reset)651 2656 y(\()p Fb(b-)p + +Fm(\).)27 b(Breakp)q(oin)o(t)18 b(base)f(can)g(b)q(e)g(explicitly)f + +(reset)j(to)d(0;)i(breakp)q(oin)o(t)f(restric-)651 2706 + +y(tions)12 b(can)h(b)q(e)g(explicitly)e(reset)j(\()p + +Fb(b)o(r-)p Fm(\).)k(Ho)o(w)o(ev)o(er,)13 b(c)o(hanges)g(of)f(the)h + +(base)g(address)651 2756 y(or)h(restrictions)h(do)f(not)g(require)g + +(prior)g(reset.)651 2805 y Fb(b)o(rt,)h(b)o(rT)p Fm(,)g(and)f + +Fb(b)o(r)p Fi(f)p Fb(e,1,2,4)p Fi(g)f Fm(restrictions)j(are)f + +(logically)e(anded.)20 b(Ho)o(w)o(ev)o(er,)15 b(set-)651 + +2855 y(ting)k(a)g(register)i(restriction)g(o)o(v)o(erwrites)f(a)g + +(prior)f(v)n(ariable)g(restriction,)i(and)651 2905 y(setting)14 + +b(a)g(v)n(ariable)f(restriction)i(o)o(v)o(erwrites)f(a)g(prior)f + +(register)j(restriction.)p 161 2972 V eop + +%%Page: 5 6 + +5 5 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(5)161 300 y Fj(3.2)56 b(Dump)17 b(Memory:)23 b Fc(d)161 + +377 y Fm(Displa)o(ys)13 b(ph)o(ysical)h(and)f(virtual)g(memory)m(.)p + +161 441 1802 2 v 186 525 a Fc(d)p Fg(xxxxxxxx)248 b Fm(displa)o(ys)22 + +b(memory)d(b)q(eginning)j(from)e(address)j Fg(xxxxxxxx)p + +Fm(.)41 b(The)22 b(dump)f(is)651 575 y(32-bit-w)o(ord)15 + +b(orien)o(ted)j(so)e(that)h(addresses)i(are)e(alw)o(a)o(ys)e(truncated) + +j(to)f(4-b)o(yte)651 625 y(aligned)g(addresses.)31 b(The)19 + +b(cursor)f(k)o(eys,)h Fb(PgUp)p Fm(,)e(and)h Fb(PgDn)f + +Fm(can)h(b)q(e)g(used)h(to)651 675 y(mo)o(v)o(e)12 b(the)j(dump)d + +(cursor)j(and)f(displa)o(y)f(further)i(memory)m(.)651 + +725 y(Since)i(some)f(terminal)f(em)o(ulators)g(do)h(not)h(supp)q(ort)g + +Fb(PgUp)f Fm(and)g Fb(PgDn)p Fm(,)h Fb(Ctl)e(p)651 775 + +y Fm(and)f Fb(Ctl)f(q)h Fm(can)g(b)q(e)h(used)g(instead.)651 + +824 y(This)h(command)d(alw)o(a)o(ys)i(displa)o(ys)h(virtual)f(memory)f + +(of)h(the)i(curren)o(t)h(address)651 874 y(space.)30 + +b(P)o(ages)18 b(that)g(are)g(not)g(mapp)q(ed)e(to)i(ph)o(ysical)f + +(memory)e(are)j(sho)o(wn)g(as)651 924 y(.)6 b(.)h(.)f(.)h(.)f(.)h(.)f + +(.)h(.)p 161 990 V 651 1075 a(Memory)17 b(can)h(b)q(e)h(displa)o(y)o + +(ed)f(in)f(v)n(arious)h(mo)q(des.)30 b(The)18 b(blank)g(k)o(ey)g(switc) + +o(hes)651 1125 y(b)q(et)o(w)o(een)d(these)h(mo)q(des:)297 + +1225 y(d-mo)q(de)218 b(32-bit)22 b(w)o(ords)g(are)h(sho)o(wn)g(as)g(dw) + +o(ords,)h(upp)q(ermost)f(nibble)f(leftmost,)h(e.g.)651 + +1274 y(00000002)13 b(for)h(the)i(v)n(alue)e(2.)21 b(V)m(alues)15 + +b(0)f(and)h(FFFFFFFF)g(are)h(displa)o(y)o(ed)e(sp)q(e-)651 + +1324 y(cially:)114 b(0)13 b(and)111 b(-1.)297 1424 y(b-mo)q(de)218 + +b(32-bit)28 b(w)o(ords)h(are)g(sho)o(wn)g(b)o(ytewise,)j(upp)q(ermost)d + +(b)o(yte)g(righmost,)i(e.g.)651 1474 y(02000000)17 b(for)h(the)i(v)n + +(alue)e(2.)32 b(V)m(alues)19 b(0)g(and)f(FFFFFFFF)i(are)f(not)g + +(treated)651 1523 y(di\013eren)o(tly)m(.)297 1623 y(c-mo)q(de)223 + +b(Bytes)15 b(are)f(sho)o(wn)g(as)g(ASCI)q(I)g(c)o(haracters.)297 + +1723 y(p-mo)q(de)218 b(32-bit)13 b(w)o(ords)h(are)g(sho)o(wn)g(as)g + +(page-table)g(en)o(tries)h(\(see)g(b)q(elo)o(w\).)p 161 + +1789 V eop + +%%Page: 6 7 + +6 6 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(6)161 300 y Fj(3.3)56 b(Dump)17 b(P)n(age)j(T)-5 + +b(ables:)24 b Fc(p)161 377 y Fm(Displa)o(ys)13 b(page)h(tables)g(and)g + +(virtual)f(memory)m(.)p 161 441 1802 2 v 186 525 a Fc(p)440 + +b Fm(displa)o(ys)14 b(the)i(higher-lev)o(el)e(page)h(table)g(\(page)g + +(directory\))g(of)g(the)g(curren)o(t)h(ad-)651 575 y(dress)e(space.)19 + +b(The)14 b(cursor)g(k)o(eys,)f Fb(PgUp)p Fm(,)f Fb(PgDn)p + +Fm(,)g Fb(Ctl)h(p)p Fm(,)g(and)f Fb(Ctl)h(q)g Fm(can)g(b)q(e)h(used)651 + +625 y(lik)o(e)e(in)g(the)i(dump)d(case.)19 b(Pressing)14 + +b(the)f(en)o(ter)h(k)o(ey)f(when)g(the)g(cursor)h(p)q(oin)o(ts)f(to)651 + +675 y(a)j(v)n(alid)e(lo)o(w)o(er-lev)o(el)h(page)h(table)g(switc)o(hes) + +h(to)e(this)h(table.)24 b(In)16 b(the)g(same)f(w)o(a)o(y)m(,)651 + +725 y(the)j(en)o(ter)g(k)o(ey)f(there)i(switc)o(hes)f(to)f(the)h(data)f + +(page.)28 b(The)18 b(home)e(k)o(ey)h(alw)o(a)o(ys)651 + +775 y(\\returns")e(to)f(the)g(lo)o(w)o(er-)g(or)f(higher-lev)o(el)h + +(page)g(table)g(resp)q(ectiv)o(ely)m(.)186 874 y Fc(p)p + +Fg(xxx)368 b Fm(displa)o(ys)13 b(the)i(higher-lev)o(el)e(page)h(table)g + +(of)f(task)h Fg(xxx)p Fm(.)186 974 y Fc(p)p Fg(xxxxx)p + +Fm(000)257 b(displa)o(ys)13 b(the)i(higher-lev)o(el)e(page)h(table)g(b) + +q(eginning)f(at)h(address)h Fg(xxxxxxxx)p Fm(.)p 161 + +1040 V 651 1125 a(P)o(age-table)f(en)o(try)g(formats:)297 + +1183 y({)333 b(Nil)13 b(en)o(try)m(.)241 1241 y Fg(xxxx)c + +Fi(\000)g(\000)p Fm(r)216 b(User-lev)o(el,)14 b(read-only)m(,)f(p)q + +(oin)o(ting)f(to)i(ph)o(ysical)g(address)h Fg(xxxx)p + +Fm(000.)241 1299 y Fg(xxxx)9 b Fi(\000)g(\000)p Fm(w)202 + +b(User-lev)o(el,)14 b(read/write,)g(p)q(oin)o(ting)f(to)h(ph)o(ysical)f + +(address)i Fg(xxxx)p Fm(000.)241 1357 y Fg(xxxx)9 b Fi(\000)g(\000)p + +Fm(R)201 b(Kernel,)14 b(read-only)m(,)f(p)q(oin)o(ting)g(to)g(ph)o + +(ysical)h(address)h Fg(xxxx)p Fm(000.)241 1415 y Fg(xxxx)9 + +b Fi(\000)g(\000)p Fm(r)216 b(Kernel,)14 b(read/write,)g(p)q(oin)o + +(ting)f(to)h(ph)o(ysical)f(address)i Fg(xxxx)p Fm(000.)238 + +1474 y Fg(xx=)p Fm(4)6 b Fi(\000)h(\000f)p Fm(r,w,R,W)p + +Fi(g)48 b Fm(4M-page)14 b(en)o(try)m(,)f(p)q(oin)o(ting)g(to)h(ph)o + +(ysical)f(address)i Fg(xx)p Fm(00000.)233 1532 y Fg(xx)5 + +b Fi(\003)g Fm(4)g Fi(\000)g(\000f)p Fm(r,w,R,W)o Fi(g)47 + +b Fm(4M-page)21 b(en)o(try)m(,)h(p)q(oin)o(ting)e(to)g(ph)o(ysical)h + +(address)h Fg(xx)p Fm(00000,)e(4K)h(pages)g(are)651 1581 + +y(mapp)q(ed)13 b(out)h(of)f(this)h(4M)g(en)o(try)m(.)p + +161 1648 V eop + +%%Page: 7 8 + +7 7 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(7)161 300 y Fj(3.4)56 b(P)n(age)19 b(F)-5 b(ault)19 + +b(Monitoring:)24 b Fc(P)161 377 y Fm(Monitors)14 b(page)g(faults.)j(P)o + +(age)d(faults)g(are)g(monitored)e Fh(b)n(efor)n(e)i Fm(they)g(are)g + +(handled)g(or)g(ev)o(en)h(seen)g(b)o(y)e(LN.)p 161 441 + +1802 2 v 186 525 a Fc(P+)396 b Fm(switc)o(hes)13 b(page-fault)d + +(monitoring)f(on.)18 b(Whenev)o(er)12 b(a)g(page)f(fault)g(o)q(ccurs,)i + +(page-)651 575 y(fault)f(address,)j(instruction)e(p)q(oin)o(ter)h(and)f + +(thread)h(n)o(um)o(b)q(er)f(are)g(displa)o(y)o(ed)g(and)651 + +625 y(the)21 b(system)g(stops)g(un)o(til)f(a)g(k)o(ey)h(is)g(hit)f(on)h + +(the)g(debug)g(console.)39 b(Pressing)651 675 y(the)17 + +b Fb(i)p Fm(-k)o(ey)e(in)o(v)o(ok)o(es)h(the)g(full)f(LNKD)h(men)o(u;)f + +(an)o(y)h(other)g(k)o(ey)g(resumes)h(normal)651 725 y(op)q(eration,)c + +(i.e.)g(starts)i(normal)d(page-fault)h(handling.)186 + +824 y Fc(P{)410 b Fm(switc)o(hes)15 b(page-fault)e(monitoring)e(o\013,) + +j(single)f(as)h(w)o(ell)f(as)h(traced)h(monitoring.)186 + +926 y Fc(P*)410 b Fm(switc)o(hes)13 b Fh(tr)n(ac)n(e)n(d)f + +Fm(page-fault)f(monitoring)f(on.)17 b(Instead)c(of)f(presen)o(ting)h + +(an)o(y)f(sin-)651 976 y(gle)e(page)g(fault,)g(all)f(page)i(faults)f + +(are)g(monitored)f(in)h(a)g(trace)i(bu\013er.)18 b(This)10 + +b(bu\013er)651 1026 y(stores)18 b(up)e(to)g(1792)g(en)o(tries.)26 + +b(When)16 b(LNKD)h(is)f(in)o(v)o(ok)o(ed)f(the)i(next)g(time,)e(the)651 + +1076 y(last)g(up)g(to)f(22)h(new)g(en)o(tries)h(\(that)f(w)o(ere)h(en)o + +(tered)g(after)f(the)h(previous)f(in)o(v)o(o)q(ca-)651 + +1126 y(tion)f(of)h(LNKD\))g(of)f(this)h(bu\013er)h(are)f(displa)o(y)o + +(ed.)21 b(More)15 b(en)o(tries,)h(including)e(all)651 + +1176 y(old)f(en)o(tries,)i(can)f(b)q(e)g(displa)o(y)o(ed)g(b)o(y)f(the) + +i Fh(dump)g(tr)n(ac)n(e)f Fm(command.)p 161 1242 V 186 + +1327 a Fc(Pr)g Fm(.)6 b(.)g(.)355 b(restricts)21 b(the)e(monitored)f + +(page)g(fault.)32 b(P)o(age)19 b(faults)f(that)h(do)g(not)g(meet)f(all) + +651 1376 y(sp)q(eci\014ed)d(restrictions)h(are)e(ignored)g(b)o(y)f(the) + +i(monitoring)c(system.)186 1426 y Fc(Prt)p Fg(xxxx)303 + +b Fm(restricts)16 b(page)e(faults)f(to)h(thread)g Fg(xxxx)p + +Fm(.)186 1526 y Fc(PrT)p Fg(xxxx)288 b Fm(restricts)16 + +b(page)e(faults)f(to)h(threads)1221 1522 y Fe(6)p Fd(=)1246 + +1526 y Fg(xxxx)p Fm(.)186 1625 y Fc(Prx)186 1675 y Fm([)p + +Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)q(;)7 b(z)r(z)r(z)r(z)s(z)r(z)r(z)r(z) + +r Fm(])651 1625 y(Only)26 b(page)f(faults)h(with)f(fault)g(addresses)j + +(in)e(the)g(sp)q(eci\014ed)i(in)o(terv)n(al)d(\(if)651 + +1675 y Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)823 1671 y Fe(\024)852 + +1675 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r Fm(\))20 b(or)f(outside)h + +(the)g(in)o(terv)n(al)e([)p Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r(;)7 + +b(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)r Fm(])22 b(\(if)651 + +1725 y Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)823 1721 y Fa(>)852 + +1725 y Fg(z)r(z)r(z)r(z)r(z)r(z)r(z)r(z)r Fm(\))15 b(are)f(monitored.) + +186 1825 y Fc(Pr{)393 b Fm(All)13 b(page-fault)g(restrictions)i(are)f + +(reset.)p 161 1891 V eop + +%%Page: 8 9 + +8 8 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(8)161 300 y Fj(3.5)56 b(IPC)19 b(Monitoring:)24 + +b Fc(I)161 377 y Fm(Monitors)14 b(IPC)g(op)q(erations.)k(IPCs)d(are)f + +(monitored)f Fh(b)n(efor)n(e)g Fm(they)h(are)h(handled)e(or)h(ev)o(en)h + +(seen)g(b)o(y)f(LN.)p 161 441 1802 2 v 186 525 a Fc(I+)414 + +b Fm(switc)o(hes)18 b(IPC)f(monitoring)e(on.)27 b(Whenev)o(er)18 + +b(an)f(IPC)g(op)q(eration)g(is)g(in)o(v)o(ok)o(ed,)651 + +575 y(sender)g(thread)f(n)o(um)o(b)q(er,)e(op)q(eration)h(t)o(yp)q(e)g + +(\(call,)g(send,)h(w)o(ait,)e(w)o(ait)g(for,)h(reply)651 + +625 y(and)e(w)o(ait\),)g(destination)g(thread)i(n)o(um)o(b)q(er)e(\(if) + +g(sp)q(eci\014ed\),)h(message)g(t)o(yp)q(e)g(\(nor-)651 + +675 y(mal)h(or)j(map\),)e(and)h(message)g(w)o(ords)h(0)f(and)g(1)g(are) + +h(displa)o(y)o(ed.)28 b(The)18 b(system)651 725 y(stops)h(un)o(til)f(a) + +h(k)o(ey)f(is)h(hit)f(on)h(the)g(debug)g(console.)33 + +b(Pressing)20 b(the)f Fb(i)p Fm(-k)o(ey)f(in-)651 775 + +y(v)o(ok)o(es)f(the)g(full)f(LNKD)g(men)o(u;)h(an)o(y)f(other)i(k)o(ey) + +f(resumes)g(normal)d(op)q(eration,)651 824 y(i.e.)f(starts)i(normal)d + +(IPC)i(handling.)186 924 y Fc(I{)428 b Fm(switc)o(hes)15 + +b(IPC)f(monitoring)d(o\013,)j(single)f(as)h(w)o(ell)f(as)h(traced)h + +(monitoring.)186 1026 y Fc(I*)428 b Fm(switc)o(hes)20 + +b Fh(tr)n(ac)n(e)n(d)f Fm(IPC)g(monitoring)e(on.)33 b(Instead)20 + +b(of)f(presen)o(ting)h(an)o(y)e(single)651 1076 y(IPC,)c(all)f(IPCs)i + +(are)g(monitored)e(in)h(a)h(trace)g(bu\013er.)21 b(This)14 + +b(bu\013er)i(stores)f(up)g(to)651 1126 y(1792)f(en)o(tries.)23 + +b(When)15 b(LNKD)g(is)g(in)o(v)o(ok)o(ed)g(the)g(next)h(time,)e(the)h + +(last)g(up)g(to)g(22)651 1176 y(new)f(en)o(tries)h(\(that)f(w)o(ere)h + +(en)o(tered)h(after)e(the)g(previous)h(in)o(v)o(o)q(cation)d(of)i + +(LNKD\))651 1225 y(of)g(this)g(bu\013er)i(are)f(displa)o(y)o(ed.)k + +(More)c(en)o(tries,)g(including)e(all)h(old)f(en)o(tries,)j(can)651 + +1275 y(b)q(e)f(displa)o(y)o(ed)e(b)o(y)g(the)i Fh(dump)g(tr)n(ac)n(e)f + +Fm(command.)p 161 1342 V 186 1426 a Fc(Ir)g Fm(.)6 b(.)h(.)372 + +b(restricts)19 b(the)e(monitored)e(IPCs.)28 b(IPCs)17 + +b(that)g(do)f(not)h(meet)f(all)g(sp)q(eci\014ed)i(re-)651 + +1476 y(strictions)d(are)f(ignored)g(b)o(y)f(the)i(monitoring)c(system.) + +186 1526 y Fc(Irt)p Fg(xxxx)321 b Fm(restricts)16 b(IPCs)e(to)g(thread) + +h Fg(xxxx)p Fm(.)186 1625 y Fc(IrT)p Fg(xxxx)306 b Fm(restricts)16 + +b(IPCs)e(to)g(threads)1113 1621 y Fe(6)p Fd(=)1138 1625 + +y Fg(xxxx)p Fm(.)186 1725 y Fc(Irs)416 b Fm(Only)15 b(IPCs)h(con)o + +(taining)e(a)h(send)h(part)g(are)f(monitored,)f(i.e.,)g(call,)h(send,)h + +(reply)651 1775 y(and)e(w)o(ait.)186 1875 y Fc(Ir{)411 + +b Fm(All)13 b(IPC)h(restrictions)h(are)g(reset.)p 161 + +1941 V eop + +%%Page: 9 10 + +9 9 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1120 + +b Fm(9)161 300 y Fj(3.6)56 b(Exception)17 b(Monitoring:)24 + +b Fc(X)161 377 y Fm(Monitors)14 b(Exceptions.)19 b(IPCs)14 + +b(are)h(monitored)d Fh(b)n(efor)n(e)h Fm(they)i(are)f(handled)g(or)g + +(ev)o(en)g(seen)i(b)o(y)d(LN.)p 161 441 1802 2 v 186 + +525 a Fc(X+)p Fg(xx)347 b Fm(switc)o(hes)19 b(excption)e(monitoring)e + +(on)j(for)f(exception)h Fg(xx)p Fm(.)28 b(F)m(or)17 b(description)h(of) + +651 575 y(the)e(exception)f(t)o(yp)q(es,)h(see)g(the)g(P)o(en)o(tium)d + +(pro)q(cessor)k(Reference)g(man)o(ual,)12 b(e.d.)651 + +625 y Fg(xx)699 621 y Fd(=)724 625 y Fm(0)p Fg(d)i Fm(denotes)i(a)e + +(General)h(Exception.)21 b(Whenev)o(er)16 b(an)e(exception)h(is)g + +(raised,)651 675 y(this)20 b(is)f(displa)o(y)o(ed.)35 + +b(The)20 b(system)f(stops)h(un)o(til)f(a)g(k)o(ey)h(is)g(hit)f(on)g + +(the)i(debug)651 725 y(console.)d(Pressing)d(the)f Fb(i)p + +Fm(-k)o(ey)g(in)o(v)o(ok)o(es)f(the)h(full)e(LNKD)i(men)o(u;)e(an)o(y)i + +(other)g(k)o(ey)651 775 y(resumes)g(normal)e(op)q(eration,)i(i.e.)e + +(starts)j(normal)d(IPC)i(handling.)186 874 y Fc(X{)409 + +b Fm(switc)o(hes)15 b(exception)g(monitoring)c(o\013.)186 + +976 y Fc(X*)409 b Fm(switc)o(hes)15 b Fh(tr)n(ac)n(e)n(d)d + +Fm(exception)j(monitoring)10 b(on.)18 b(Instead)c(of)f(presen)o(ting)h + +(an)o(y)f(sin-)651 1026 y(gle)f(exceptions,)h(all)f(are)g(monitored)f + +(in)h(a)g(trace)i(bu\013er.)k(This)13 b(bu\013er)g(stores)h(up)651 + +1076 y(to)d(1792)g(en)o(tries.)18 b(When)12 b(LNKD)f(is)g(in)o(v)o(ok)o + +(ed)g(the)h(next)g(time,)e(the)i(last)g(up)f(to)g(22)651 + +1126 y(new)j(en)o(tries)h(\(that)f(w)o(ere)h(en)o(tered)h(after)e(the)g + +(previous)h(in)o(v)o(o)q(cation)d(of)i(LNKD\))651 1176 + +y(of)g(this)g(bu\013er)i(are)f(displa)o(y)o(ed.)k(More)c(en)o(tries,)g + +(including)e(all)h(old)f(en)o(tries,)j(can)651 1225 y(b)q(e)f(displa)o + +(y)o(ed)e(b)o(y)g(the)i Fh(dump)g(tr)n(ac)n(e)f Fm(command.)p + +161 1292 V 186 1376 a Fc(Xr)g Fm(.)6 b(.)h(.)353 b(restricts)20 + +b(the)g(monitored)d(Exceptions.)32 b(Exceptions)20 b(that)e(do)h(not)f + +(meet)g(all)651 1426 y(sp)q(eci\014ed)d(restrictions)h(are)e(ignored)g + +(b)o(y)f(the)i(monitoring)c(system.)186 1476 y Fc(Xrt)p + +Fg(xxxx)302 b Fm(restricts)16 b(exceptions)f(to)f(thread)g + +Fg(xxxx)p Fm(.)186 1576 y Fc(XrT)p Fg(xxxx)287 b Fm(restricts)16 + +b(exceptions)f(to)f(threads)1212 1572 y Fe(6)p Fd(=)1237 + +1576 y Fg(xxxx)p Fm(.)186 1675 y Fc(Xrx)g Fm([)p Fg(y)q(y)q(y)q(y)q(;)7 + +b(z)r(z)r(z)r(z)r Fm(])169 b(Only)16 b(exceptions)h(with)e(an)h(error)h + +(co)q(de)f(in)g(the)g(sp)q(eci\014ed)i(in)o(terv)n(al)d(are)h(moni-)651 + +1725 y(tored.)i(This)13 b(restriction)h(applies)f(only)f(to)h(those)h + +(exceptions)g(that)f(are)g(accom-)651 1775 y(panied)h(b)o(y)f(hardw)o + +(are-generated)j(error)f(co)q(des,)f(i.e.,)f(0A,)g(0B,)h(0C,)f(0D,)g + +(0E.)186 1875 y Fc(Xr-)400 b Fm(All)13 b(exception)i(restrictions)g + +(are)f(reset.)p 161 1941 V eop + +%%Page: 10 11 + +10 10 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1100 + +b Fm(10)161 300 y Fj(3.7)56 b(T)-5 b(racing:)24 b Fc(T)161 + +377 y Fm(Sho)o(ws)10 b(the)h(trace)g(bu\013er)g(and)f(sp)q(eci\014es)i + +(trace)f(mo)q(de.)16 b(IPCs,)11 b(page)f(faults,)g(exceptions)h(and)f + +(k)o(ernel)h(ev)o(en)o(ts.)18 b(The)161 427 y(according)e(messages)g + +(are)h(stored)g(in)f(a)f(trace)i(bu\013er,)h(together)f(with)e(timing)f + +(information)f(and,)j(optionally)m(,)161 477 y(p)q(erformance-coun)o + +(ter)f(information.)f(On)g(486,)f(timing)e(information)f(is)k(not)f(a)o + +(v)n(ailable.)j(On)e(P)o(en)o(tium)e(and)h(all)161 527 + +y(further)f(pro)q(cessors,)i(eac)o(h)d(trac-bu\013er)i(en)o(try)f(is)f + +(accomplished)f(with)h(a)f(64-bit)h Fh(timestamp)f Fm(whic)o(h)h(is)g + +(read)h(from)161 576 y(the)i(pro)q(cessor's)h(in)o(ternal)e + +(time-stamp-coun)o(ter)e(register.)19 b(When)13 b(p)q(erformance)g + +(coun)o(ting)g(is)g(activ)n(ated,)g(eac)o(h)161 626 y(trace-bu\013er)f + +(en)o(try)f(is)g(also)e(augmen)o(ted)h(with)g(the)h(curren)o(t)g(v)n + +(alues)g(of)e(the)i(pro)q(cessor's)h(t)o(w)o(o)e(p)q(erformance-coun)o + +(t)161 676 y(registers.)p 161 740 1802 2 v 186 824 a + +Fc(T)432 b Fm(en)o(ters)18 b(trace-bu\013er)h(dump.)26 + +b(The)17 b(new)o(est)h(information)c(is)i(displa)o(y)o(ed)h(at)f(the) + +651 874 y(b)q(ottom.)27 b(The)18 b(cursor)h(k)o(eys,)f + +Fb(PgUp)p Fm(,)f(and)h Fb(PgDn)f Fm(can)h(b)q(e)g(used)g(to)f(mo)o(v)o + +(e)f(the)651 924 y(trace-bu\013er)g(cursor)f(and)f(displa)o(y)e + +(further)j(trace-bu\013er)h(en)o(tries.)651 974 y(Since)h(some)f + +(terminal)f(em)o(ulators)g(do)h(not)h(supp)q(ort)g Fb(PgUp)f + +Fm(and)g Fb(PgDn)p Fm(,)h Fb(Ctl)e(p)651 1024 y Fm(and)f + +Fb(Ctl)f(q)h Fm(can)g(b)q(e)h(used)g(instead.)p 161 1090 + +V 651 1175 a(On)g(all)d(pro)q(cessors)17 b(except)e(486,)e + +(trace-bu\013er)j(en)o(tries)g(get)e(timestamps)e(when)651 + +1225 y(they)j(are)g(en)o(tered)h(in)o(to)d(the)i(bu\013er.)21 + +b(Accordingly)m(,)13 b(they)i(can)g(b)q(e)g(displa)o(y)o(ed)e(in)651 + +1274 y(v)n(arious)k(timing)e(mo)q(des.)28 b(The)18 b(blank)e(k)o(ey)i + +(switc)o(hes)g(b)q(et)o(w)o(een)h(these)g(mo)q(des.)651 + +1324 y(Since)f(the)h(486)e(pro)q(cessor)i(o\013ers)g(no)f + +(timestamp-coun)o(ter)e(register,)k(on)d(486,)651 1374 + +y(only)c(index-mo)q(de)g(is)h(a)o(v)n(ailable.)297 1474 + +y(index-mo)q(de)143 b(En)o(tries)11 b(are)g(sho)o(wn)f(with)g(their)g + +(n)o(um)o(b)q(er)g(in)f(the)i(bu\013er.)18 b(Links)10 + +b(to)g(other)h(en)o(tries)651 1523 y(are)j(also)g(sho)o(wn)g(as)f(en)o + +(try)i(n)o(um)o(b)q(ers.)297 1623 y(delta-mo)q(de)151 + +b(En)o(tries)17 b(are)g(sho)o(wn)g(with)f(their)g(time)f(di\013erence)k + +(\(in)d Fg(\026)p Fm(s,)h(ms,)e(or)h(s\))h(to)f(their)651 + +1673 y(displa)o(y)o(ed)g(predeceesor)j(en)o(try)m(.)26 + +b(Links)16 b(to)h(other)g(en)o(tries)g(are)g(sho)o(wn)g(as)f(time)651 + +1723 y(di\013erences.)297 1822 y(page-mo)q(de)158 b(En)o(tries)16 + +b(are)f(sho)o(wn)h(with)e(their)i(time)e(di\013erence)i(relativ)o(e)f + +(to)g(the)h(upp)q(ermost)651 1872 y(en)o(try)f(of)e(the)h(displa)o(y)o + +(ed)g(page.)k(Links)13 b(are)i(sho)o(wn)e(lik)o(e)h(in)f(the)h(delta)g + +(mo)q(de.)p 161 1938 V 651 2023 a(T)m(race-bu\013er)h(en)o(tries)g(can) + +f(b)q(e)h(displa)o(y)o(ed)e(with)h Fh(links)f Fm(to)h(similar)d(en)o + +(tries.)19 b(Tw)o(o)651 2073 y(en)o(tries)13 b(are)g(considered)g(to)f + +(b)q(e)h Fh(similar)e Fm(i\013)g(b)q(oth)i(are)f(of)g(the)g(same)g(t)o + +(yp)q(e)g(\(k)o(ernel)651 2123 y(ev)o(en)o(t,)22 b(page)f(fault,)f(ip)q + +(c-call,)h(ip)q(c-send,)i(etc.\))38 b Fh(and)21 b Fm(en)o(tered)i(b)o + +(y)d(the)h(same)651 2173 y(thread)15 b Fh(and)f Fm(the)h(\014rst)f(w)o + +(ord)g(is)g(iden)o(tical)f(in)g(b)q(oth)i(messages.)651 + +2243 y(The)f(cursor-righ)o(t/left)g(k)o(eys)h(switc)o(h)f(b)q(et)o(w)o + +(een)h(these)h(alternate)e(mo)q(des:)297 2343 y(no-links)211 + +b(No)14 b(links)f(are)h(sho)o(wn)297 2442 y(forw)o(ard-links)116 + +b(Links)11 b(to)f(the)h(next)h(similar)c(en)o(try)j(are)g(sho)o(wn,)g + +(dep)q(ending)h(on)e(the)h(mo)q(de)f(either)651 2492 + +y(as)k(index)g(links)f(or)h(as)g(delta)g(times.)297 2592 + +y(bac)o(kw)o(ard-links)83 b(Links)14 b(to)h(the)g(previous)g(similar)d + +(en)o(try)k(are)f(sho)o(wn,)f(dep)q(ending)h(on)g(the)g(mo)q(de)651 + +2642 y(either)g(as)f(index)g(links)f(or)h(as)g(delta)f(times.)297 + +2741 y(p)q(erf-coun)o(ters)119 b(P)o(erformance-coun)o(ter)16 + +b(deltas)f(are)h(sho)o(wn)f(instead)h(of)e(links.)22 + +b(This)15 b(feature)h(is)651 2791 y(not)c(a)o(v)n(ailable)f(on)h(486)f + +(pro)q(cessors.)20 b(See)13 b(b)q(elo)o(w)g(ho)o(w)f(to)g(activ)n(ate)g + +(p)q(erformance)651 2841 y(monitoring.)p 161 2858 V eop + +%%Page: 11 12 + +11 11 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1100 + +b Fm(11)p 161 310 1802 2 v 186 395 a Fc(P)434 b Fm(p)q(ermits)23 + +b(to)f(activ)n(ate,)j(deactiv)n(ate)e(and)g(c)o(hange)h(p)q(erformance) + +e(monitoring)651 445 y Fh(while)15 b(you)h(ar)n(e)f(in)h(the)f(tr)n(ac) + +n(e-bu\013er)g(dump)p Fm(.)21 b(\(This)15 b(command)c(do)q(es)16 + +b(not)e(w)o(ork)651 495 y(outside)f(the)g(trace-bu\013er)i(dump.)h(P)o + +(erformance)c(monitoring)e(is)j(not)f(a)o(v)n(ailable)651 + +545 y(on)i(486)f(pro)q(cessors.)186 644 y Fc(P+)396 b + +Fm(turns)16 b(p)q(erformance)e(monitoring)e(on.)20 b(Kernel)c(and)e + +(user-mo)q(de)h(activities)f(are)651 694 y(measured.)186 + +794 y Fc(Pu)409 b Fm(turns)28 b(p)q(erformance)f(monitoring)e(on.)57 + +b(Only)27 b(user-mo)q(de)g(activities)g(are)651 843 y(measured.)186 + +943 y Fc(Pk)410 b Fm(turns)24 b(p)q(erformance)g(monitoring)c(on.)47 + +b(Only)23 b(k)o(ernel-mo)q(de)f(activities)h(are)651 + +993 y(measured.)p 161 1059 V 651 1144 a(The)14 b(follo)o(wing)e(p)q + +(erformance-monitoring)f(options)i(are)i(a)o(v)n(ailable:)297 + +1244 y(i)342 b(Instructions,)15 b(coun)o(ts)f(total)f(\(U+V)i(pip)q + +(e\))f(and)g(V-pip)q(e)g(instructions.)297 1343 y(c)336 + +b(Cac)o(he)14 b(misses,)f(coun)o(ts)i(data-cac)o(he)f(and)g + +(instruction-cac)o(he)h(misses.)297 1443 y(t)338 b(TLB)14 + +b(misses,)f(coun)o(ts)i(data-TLB)f(and)f(instruction-TLB)i(nisses.)297 + +1542 y(m)318 b(Memory)13 b(stalls,)g(coun)o(ts)i(read)f(and)g(write)g + +(stall)f(cycles.)297 1642 y(a)333 b(In)o(terlo)q(c)o(ks,)17 + +b(coun)o(ts)g(A)o(GI)f(cycles)h(\(address)h(generation)f(in)o(terlo)q + +(c)o(k\))f(and)g(bank)651 1692 y(con\015icts)f(o)q(ccurrences.)297 + +1792 y(b)331 b(Bus)29 b(utilization,)h(coun)o(ts)f(bus)f(cycles)h(and)f + +(total)g(n)o(um)o(b)q(er)f(of)h(executed)651 1841 y(instructions.)p + +161 1908 V eop + +%%Page: 12 13 + +12 12 bop 161 155 a Fl(3)41 b(GENERAL)14 b(TEST)g(FUNCTIONS)1100 + +b Fm(12)161 300 y Fj(3.8)56 b(IO:)18 b Fc(i/o)161 377 + +y Fm(I/O)c(to)g(p)q(orts.)p 161 443 1802 2 v 186 528 + +a Fc(i)p Fi(f)p Fb(1,2,4)p Fi(g)p Fg(xxxx)229 b Fm(Reads)14 + +b(\()p Fh(in)p Fm(\))g(from)e(the)j(sp)q(eci\014ed)g(1-,)e(2-,)g(or)h + +(4-b)o(yte)g(p)q(ort.)186 627 y Fc(ia)p Fg(xxxx)335 b + +Fm(Reads)14 b(\()p Fh(in)p Fm(\))g(from)e(the)j(sp)q(eci\014ed)g + +(register)g(of)f(the)g(pro)q(cessor's)i(lo)q(cal)d(APIC.)186 + +727 y Fc(ii)p Fg(xxxx)347 b Fm(Reads)14 b(\()p Fh(in)p + +Fm(\))g(from)e(the)j(sp)q(eci\014ed)g(register)g(of)f(the)g(IO)g(APIC.) + +186 827 y Fc(ip)p Fg(xxxxxxxx)237 b Fm(Reads)17 b(\()p + +Fh(in)p Fm(\))f(from)f(the)i(sp)q(eci\014ed)h(PCI)f(con\014guration)f + +(register.)26 b(It)17 b(is)f(not)g(re-)651 876 y(quired)f(to)h(set)g + +(bit)f(32)f(of)h Fg(xxxxxxxx)p Fm(.)k(PCI)d(con\014guaration)e + +(registers)j(are)f(al-)651 926 y(w)o(a)o(ys)e(4-b)o(yte)h(registers.)22 + +b(Their)15 b(address)h Fg(xxxxxxxx)c Fm(m)o(ust)i(alw)o(a)o(ys)g(b)q(e) + +h(4-b)o(yte)651 976 y(aligned.)p 161 1042 V 186 1127 + +a Fc(o)p Fi(f)p Fb(1,2,4)p Fi(g)p Fg(xxxx)186 1177 y + +Fi(f)p Fg(y)q(y)q(;)7 b(y)q(y)q(y)r(y)q(;)g(y)r(y)r(y)q(y)r(y)r(y)r(y)r + +(y)r Fi(g)651 1127 y Fm(W)m(rites)14 b(\()p Fh(out)p + +Fm(\))g Fg(y)q(y)c(:)d(:)g(:)12 b Fm(to)i(the)g(sp)q(eci\014ed)i(1-,)d + +(2-,)g(or)h(4-b)o(yte)f(p)q(ort.)186 1277 y Fc(oa)p Fg(xxxx)h(y)q(y)q + +(y)q(y)q(y)r(y)r(y)q(y)139 b Fm(W)m(rites)15 b(\()p Fh(out)p + +Fm(\))h Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)k Fm(to)15 b(the)g(sp)q + +(eci\014ed)i(register)f(of)f(the)h(pro)q(cessor's)h(lo)q(cal)651 + +1326 y(APIC.)186 1426 y Fc(oi)p Fg(xxxx)334 b Fm(W)m(rites)14 + +b(\()p Fh(out)p Fm(\))g Fg(y)q(y)q(y)q(y)r(y)q(y)r(y)r(y)19 + +b Fm(to)14 b(the)g(sp)q(eci\014ed)h(register)h(of)d(the)h(IO)g(APIC.) + +186 1526 y Fc(op)p Fg(xxxxxxxx)224 b Fm(W)m(rites)14 + +b(\()p Fh(out)p Fm(\))g Fg(y)q(y)q(y)q(y)q(y)r(y)r(y)r(y)k + +Fm(to)c(the)g(sp)q(eci\014ed)h(PCI)f(con\014guration)f(register.)19 + +b(It)14 b(is)651 1576 y(not)j(required)h(to)f(set)h(bit)f(32)f(of)g + +Fg(xxxxxxxx)p Fm(.)26 b(PCI)17 b(con\014guaration)f(registers)651 + +1625 y(are)h(alw)o(a)o(ys)f(4-b)o(yte)h(registers.)29 + +b(Their)17 b(address)i Fg(xxxxxxxx)14 b Fm(m)o(ust)i(alw)o(a)o(ys)g(b)q + +(e)651 1675 y(4-b)o(yte)e(aligned.)p 161 1742 V eop + +%%Page: 13 14 + +13 13 bop 161 155 a Fl(4)41 b(MISCELLANEOUS)1335 b Fm(13)161 + +300 y Fk(4)67 b(Miscellaneous)161 400 y Fj(4.1)56 b(Go:)24 + +b Fc(g)161 485 y Fj(4.2)56 b(Video)18 b(Mo)r(de)g(and)h(Remote)e + +(Console:)24 b Fc(V)161 570 y Fj(4.3)56 b(Remote)16 b(ESC:)j + +Fc(R)p eop + +%%Trailer + +end + +userdict /end-hook known{end-hook}if + +%%EOF + diff --git a/l4-x86/smp/lx/doc/SMP Concepts 0600.ppt b/l4-x86/smp/lx/doc/SMP Concepts 0600.ppt new file mode 100644 index 0000000..b74242d Binary files /dev/null and b/l4-x86/smp/lx/doc/SMP Concepts 0600.ppt differ diff --git a/l4-x86/smp/lx/doc/smp-design.ppt b/l4-x86/smp/lx/doc/smp-design.ppt new file mode 100644 index 0000000..4f12c06 Binary files /dev/null and b/l4-x86/smp/lx/doc/smp-design.ppt differ diff --git a/l4-x86/smp/lx/doc/smp_design.ps b/l4-x86/smp/lx/doc/smp_design.ps new file mode 100644 index 0000000..5e4c6ad --- /dev/null +++ b/l4-x86/smp/lx/doc/smp_design.ps @@ -0,0 +1,1019 @@ +%!PS-Adobe-2.0 +%%Creator: dvips 5.83 (MiKTeX 1.20b) Copyright 1998 Radical Eye Software +%%Title: C:\Home\l4-x-smp\smp-design.dvi +%%CreationDate: Fri Dec 17 00:28:17 1999 +%%Pages: 5 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Times-Italic Helvetica-Bold Times-Roman Helvetica +%%+ Times-BoldItalic +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: C:\utility\miktex\texmf\miktex\bin\dvips.exe +%+ -osmp_design.ps C:\Home\l4-x-smp\smp-design.dvi +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 1999.12.10:2241 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "1 July 1998", +% filename = "8r.enc", +% email = "tex-fonts@@tug.org", +% docstring = "Encoding for TrueType or Type 1 fonts +% to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both +% ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +TeXDict begin 40258431 52099146 1000 600 600 +(C:\Home\l4-x-smp/C:\Home\l4-x-smp\smp-design.dvi) @start +%DVIPSBitmapFont: Fa cmmi8 8 1 +/Fa 1 111 df<3907C007E0391FE03FF83918F8783E393879E01E39307B801F38707F00 +126013FEEAE0FC12C05B00815C0001143E5BA20003147E157C5B15FC0007ECF8081618EB +C00115F0000F1538913803E0300180147016E0001F010113C015E390C7EAFF00000E143E +251F7E9D2B>110 D E +%EndDVIPSBitmapFont +/Fb 134[29 29 44 29 33 18 26 26 1[33 33 33 48 18 29 1[18 +33 33 18 29 33 29 1[33 6[37 9[41 1[44 12[41 6[22 1[33 +1[33 7[17 22 5[22 35[33 3[{TeXBase1Encoding ReEncodeFont}33 +66.4176 /Times-Italic rf /Fc 134[42 1[58 1[46 25 42 29 +46 46 46 46 66 21 42 1[21 46 46 25 42 46 42 46 42 12[46 +1[54 1[50 4[54 1[21 5[54 54 13[42 1[42 42 2[21 25 42[46 +2[{TeXBase1Encoding ReEncodeFont}35 74.7198 /Helvetica-Bold +rf /Fd 135[37 54 1[37 21 29 25 5[21 2[21 37 37 1[33 37 +33 1[33 48[37 6[25 25 40[{.167 SlantFont TeXBase1Encoding ReEncodeFont} +17 74.7198 /Times-Roman rf /Fe 140[29 3[37 42 4[21 1[37 +1[33 37 33 1[37 28[54 9[25 6[37 37 37 49[{TeXBase1Encoding ReEncodeFont} +14 74.7198 /Times-BoldItalic rf +%DVIPSBitmapFont: Ff cmsy9 9 1 +/Ff 1 16 df15 +D E +%EndDVIPSBitmapFont +/Fg 135[37 2[42 21 37 25 5[17 3[42 42 1[42 42 37 1[42 +97[{TeXBase1Encoding ReEncodeFont}12 74.7198 /Helvetica +rf +%DVIPSBitmapFont: Fh cmmi9 9 4 +/Fh 4 117 df<1307D90FC01338011F147C16FC5CA2013F1301A202005BA2491303A201 +7E5CA201FE1307A2495CA20001140FA2495C17800003021F13C016C149EC8180A20007EC +3F836D017F130016034B5A3A0FFC03CF869039FE070F8E9039DFFE07FC9039C3F801F0D8 +1FC0C9FCA25BA2123FA290CAFCA25AA2127EA212FEA25A12382A327FA02E>22 +D105 D107 D116 +D E +%EndDVIPSBitmapFont +/Fi 105[33 1[29 29 24[29 33 33 48 33 33 18 26 22 33 33 +33 33 52 18 33 1[18 33 33 22 29 33 29 33 29 6[41 1[48 +1[48 48 41 37 2[37 48 48 59 3[22 48 1[37 41 1[44 44 48 +7[33 33 1[33 33 33 1[33 33 33 18 17 22 17 4[22 35[37 +37 2[{TeXBase1Encoding ReEncodeFont}60 66.4176 /Times-Roman +rf /Fj 205[25 25 49[{TeXBase1Encoding ReEncodeFont}2 +49.8132 /Times-Roman rf /Fk 134[46 46 65 46 51 28 46 +32 1[51 51 51 74 23 46 1[23 51 51 28 46 51 46 51 46 10[55 +1[51 55 2[55 1[60 69 51 60 1[23 1[65 2[60 60 60 60 11[46 +46 46 46 46 2[23 28 23 44[{TeXBase1Encoding ReEncodeFont}45 +83.022 /Helvetica-Bold rf /Fl 134[33 33 50 33 37 21 29 +29 37 37 37 37 54 21 33 1[21 37 37 21 33 37 33 37 37 +10[46 1[42 37 2[46 1[50 62 42 2[25 54 54 46 1[54 50 1[46 +6[25 4[37 2[37 37 1[21 19 25 19 2[25 25 36[37 3[{ +TeXBase1Encoding ReEncodeFont}49 74.7198 /Times-Italic +rf /Fm 105[37 1[33 33 24[33 37 37 54 37 37 21 29 25 37 +37 37 37 58 21 37 21 21 37 37 25 33 37 33 37 33 9[71 +54 54 46 42 50 54 42 54 54 66 46 54 1[25 54 1[42 46 54 +50 50 54 5[21 21 1[37 37 37 37 37 37 37 37 37 21 19 25 +19 2[25 25 25 35[42 42 2[{TeXBase1Encoding ReEncodeFont}70 +74.7198 /Times-Roman rf /Fn 135[55 78 55 1[33 55 39 1[61 +61 61 89 28 2[28 1[61 1[55 61 55 1[55 13[66 2[66 2[83 +61 2[28 72 2[66 72 72 72 72 8[55 1[55 1[55 55 55 55 49[{ +TeXBase1Encoding ReEncodeFont}34 99.6264 /Helvetica-Bold +rf /Fo 87[28 49[42 42 23 32 28 1[42 42 42 1[23 42 1[23 +42 2[37 42 37 1[37 10[60 60 7[74 51 60 32 74[{ +TeXBase1Encoding ReEncodeFont}23 83.022 /Times-Roman +rf /Fp 135[66 2[73 1[66 47 2[73 73 1[33 3[73 2[66 73 +66 1[66 12[73 80 2[80 1[86 100 73 19[66 1[66 1[66 4[33 +47[{TeXBase1Encoding ReEncodeFont}22 119.552 /Helvetica-Bold +rf /Fq 104[74 34[23 1[32 2[42 1[60 6[23 37 1[37 42 42 +28[60 10[42 7[42 42 3[21 44[{TeXBase1Encoding ReEncodeFont}15 +83.022 /Times-Italic rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +letter + +%%EndSetup +%%Page: 1 1 +1 0 bop 1387 -300 a Fq(\227)20 b(Dr)o(aft)h(of)f(December)g(10,)f(1999) +g(\227)945 22 y Fp(Threads)34 b(on)f(an)h(L4/x86)h(SMP)e(Nuc)n(leus) +1272 204 y Fo(Marcus)20 b(V)7 b(\250)-35 b(olp)415 b(Jochen)19 +b(Liedtk)o(e)1593 404 y(Uni)n(v)o(ersit)5 b(\250)-33 +b(at)20 b(Karlsruhe)-150 721 y Fn(1)100 b(Motiv)n(ation)-150 +888 y Fm(Symmetric)20 b(Multi)g(Processors)h(\(SMPs\))f(are)g(no)n(w)h +(widely)f(used,)i(e)n(v)o(en)f(as)-150 971 y(lo)n(w-end)h(w)o +(orkstations.)31 b(Medium-sized)23 b(serv)o(ers)e(are)g(typically)h +(double-)-150 1054 y(processor)39 b(or)e(quad-processor)j(systems.)80 +b(Consequently)-5 b(,)44 b(an)38 b(SMP-)-150 1137 y(capable)16 +b(Nucleus)g(is)f(a)h Fl(conditio)g(sine)f(qua)i(non)f +Fm(for)f(research)h(on)g(L4-based)-150 1220 y(w)o(orkstation)k +(systems.)-67 1307 y(There)g(are)g(four)g(ob)o(vious)h(principles)f +(that)g(ha)o(v)o(e)g(to)g(lead)g(the)g(design)h(of)-150 +1391 y(an)i(L4)f(SMP-Nucleus.)33 b(The)22 b(\002rst)f(tw)o(o)i +(principles,)g Fl(compatibility)f(of)g(e)o(x-)-150 1474 +y(tension)j Fm(and)h Fl(minimality)e(of)g(e)o(xtension)p +Fm(,)j(go)o(v)o(ern)e(the)g(relations)g(between)-150 +1557 y(the)h(e)o(xisting)g(uniprocessor)h(Nucleus)g(and)f(the)g(SMP)f +(Nucleus.)44 b Fl(P)-6 b(erfor)o(-)-150 1640 y(mance)26 +b Fm(and)f Fl(\003e)o(xibility/g)o(ener)o(ality)g Fm(are)g(a)f +(perpetuation)i(of)f(e)o(xisting)g(and)-150 1723 y(pro)o(v)n(ably)20 +b(successful)g(fundamental)g(L4)f(design)h(principles.)-150 +1952 y Fk(1.1)83 b(Goals)-150 2093 y Fm(So)19 b(the)g(goals)g(were)g +(clear)g(from)g(the)g(be)o(ginning:)-82 2254 y(1.)42 +b Fl(Compatibility:)28 b Fm(An)o(y)607 2222 y Fj(1)658 +2254 y Fm(e)o(xisting)22 b(L4)f(application)i(or)e(L4-based)i(OS)16 +2337 y(personality)30 b(should)g(run)f(on)g(top)g(of)g(the)g(SMP)f +(Nucleus)i(without)16 2420 y(modi\002cation.)j(In)22 +b(particular)m(,)h(all)e(e)o(xisting)h(Nucleus)h(calls)f(ha)o(v)o(e)g +(to)16 2503 y(k)o(eep)e(their)f(functionality)g(\(and)h(their)e(binary) +i(interf)o(ace\).)-82 2669 y(2.)42 b Fl(T)l(r)o(anspar)m(ency)17 +b(in)e(the)f(Lar)m(g)o(e:)23 b Fm(It)14 b(should)i(be)f(easily)g +(possible)g(to)g(con-)16 2752 y(struct)k(applications/systems)i(such)f +(that)f(the)g(w)o(ay)h(ho)n(w)g(the)f(respec-)16 2835 +y(ti)n(v)o(e)25 b(threads)g(are)g(distrib)o(uted)g(o)o(v)o(er)g(the)f +(processors)i(has)g(no)f(ef)n(fect)16 2918 y(on)19 b(the)g +(application')l(s/system')l(s)h(functionality)-5 b(.)-82 +3083 y(3.)42 b Fl(T)l(r)o(anspar)m(ency)22 b(in)d(the)h(Small:)25 +b Fm(In)19 b(principle,)h(no)h(thread)f(should)h(see)16 +3166 y(a)h(functional)g(dif)n(ference)h(whether)f(its)f(partner)h +(threads)g(run)g(on)h(the)16 3249 y(same)c(processor)h(or)f(on)h(a)e +(dif)n(ferent)i(one.)-82 3415 y(4.)42 b Fl(Fle)o(xibility/Gener)o +(ality:)62 b Fm(An)o(y)39 b(reasonable)h(multiprocessor)g(OS)16 +3498 y(polic)o(y)24 b(should)h(be)e(implementable)i(based)f(on)g(the)g +(SMP)e(Nucleus.)16 3581 y(The)k(SMP)g(Nucleus)h(mechanisms)g(for)f +(scheduling,)k(partitioning,)16 3664 y(and)18 b(distrib)o(ution)g(of)f +(processors,)i(time,)e(and)h(memory)g(must)g(enable)16 +3747 y(an)h(as-wide-as-possible)h(design)g(space)g(for)f(policies,)g +(in)g(particular)16 3830 y(for)g(SMP-speci\002c)f(policies.)-82 +3995 y(5.)42 b Fl(Non-T)l(r)o(anspar)m(ency:)29 b Fm(SMP-a)o(w)o(are)21 +b(systems,)g(e.g.)g(OS)f(schedulers,)16 4078 y(need)h(full)e(access)i +(to)e(SMP-speci\002c)h(system)g(data.)26 b(As)19 b(well,)h(SMP-)16 +4161 y(speci\002c)c(hardw)o(are)h(must)g(be)f(usable)h(by)f(such)h +(systems)g(as)f(liberal)g(as)16 4245 y(possible.)23 b(The)15 +b(ultimate)g(goal)h(is)f(to)h(support)g(ef)n(\002cient)f(implementa-)16 +4328 y(tion)k(of)g(as)g(man)o(y)h(as)f(possible)h(dif)n(ferent)f +(policies)h(and)f(higher)o(-le)n(v)o(el)16 4411 y(mechanisms)h(based)g +(on)f(the)g(SMP-Nucleus)g(primiti)n(v)o(es.)-82 4576 +y(6.)42 b Fl(Compatibility)30 b(in)f(P)-6 b(erformance:)46 +b Fm(A)30 b(uniprocessor)o(-tar)o(geted)h(ap-)16 4659 +y(plication/system)e(running)h(on)g(only)f(one)h(processor)g(of)e(an)h +(SMP)16 4742 y(should)d Fl(cum)f(gr)o(ano)h(salis)e Fm(perform)i(as)f +(if)f(the)h(application/system)16 4825 y(runs)18 b(on)g(a)f(physical)h +(uniprocessor)h(system)e(pro)o(vided)i(memory-b)o(us)16 +4908 y(contention)h(is)f(ne)o(gligible.)-82 5074 y(7.)42 +b Fl(SMP)56 b(P)-6 b(erformance:)98 b Fm(SMP-speci\002c)55 +b(Nucleus)i(mechanisms)16 5157 y(should)20 b(perform)f(as)g(good)h(as)f +(possible.)p -150 5242 901 4 v -60 5298 a Fj(1)-30 5321 +y Fi(Pro)o(vided)38 b(the)g(application/OS)j(personality)e(does)f +(neither)h(rely)e(on)g(dis-)-150 5400 y(able/enable)21 +b(interrupt)e(for)e(synchronization)k(nor)c(on)g(priority-based)k +(tricks.)2049 721 y Fk(1.2)83 b(T)-7 b(ar)o(g)q(ets)2049 +870 y Fm(First)40 b(tar)o(get)h(for)g(a)h(SMP-Nucleus)f(implementation) +h(are)g(x86-based)2049 953 y(SMPs,)20 b(in)h(particular)g(Pentium)f(II) +h(and)g(III)f(based)i(double-processor)h(and)2049 1036 +y(quad-processor)d(systems.)j(Such)18 b(systems)g(consist)g(of)g(2)f +(or)h(4)g(processors,)2049 1119 y(each)24 b(supplemented)i(by)e(a)g +(processor)o(-local)h(L1)e(and)i(L2)e(cache,)j(a)d(com-)2049 +1202 y(mon)f(DRAM)g(memory)-5 b(,)22 b(an)g(I/O)f(space)h(shared)h +(between)f(all)f(processors,)2049 1285 y(and)f(an)f(APIC-based)g(inter) +o(-processor)g(interrupt)g(netw)o(ork.)2049 1564 y Fn(2)100 +b(Principle)28 b(Design)f(Decisions)2049 1740 y Fm(Making)j(a)e(small)g +(Nucleus)h(or)g Fh(\026)p Fm(-k)o(ernel)g(multiprocessor)g(capable)h +(is)e(a)2049 1823 y(relati)n(v)o(ely)h(limited)g(problem.)54 +b(In)30 b(the)f(L4)g(Nucleus,)j(we)d(see)g(only)h(fe)n(w)2049 +1906 y(global)20 b(k)o(ernel)g(tables,)e(i.e.,)g(such)i(that)f(do)h +(not)f(e)o(xist)g(per)g(processor)h(or)g(per)2049 1989 +y(thread)28 b(and)g(that)f(in\003uence)i(the)e(global)h(system,)i +(i.e.,)e(potentially)g(each)2049 2072 y(thread')l(s)i(beha)o(vior)l(.) +54 b(Basically)-5 b(,)32 b(only)e(mapping)g(data)g(\(including)g(page) +2049 2155 y(tables\))d(and)h(the)f(coarse-grain)h(w)o(ak)o(eup)h +(queues)f(are)f(of)g(such)h(type)f(and)2049 2238 y(ha)o(v)o(e)19 +b(to)g(be)g(secured)h(for)f(cross-processor)h(access)g(in)f(general.) +2132 2330 y(Thread)45 b(control)g(blocks)h(\(tcbs\))f(require)g +(similar)f(general)i(cross-)2049 2413 y(processor)29 +b(access)g(synchronization)i(only)d(if)g(we)g(decide)h(to)g(ha)o(v)o(e) +f(\002ne-)2049 2496 y(grain)20 b(inter)o(-processor)h(scheduling)g(of)g +(threads.)27 b(In)20 b(that)g(case,)g(we)g(w)o(ould)2049 +2579 y(ha)o(v)o(e)36 b(to)g(e)o(xplicitly)g(synchronize)i(e)n(v)o(ery)f +(dispatch/scheduling)h(access)2049 2662 y(to)32 b(a)g(tcb,)j(e)n(v)o +(en)e(to)f(the)g(just)f(current)i(tcb)m(.)62 b(Otherwise,)35 +b(per)o(-processor)2049 2745 y(dispatch/scheduling)f(data)e(structures) +h(and)f(some)h(ipc)f(tricks)g(\(see)g(be-)2049 2828 y(lo)n(w\))h(w)o +(ould)g(enable)h(us)f(to)g(manage)h(tcbs)f(such)h(that)e +(cross-processor)2049 2911 y(access)k(can)g(be)g(restricted)f(to)g(v)o +(ery)h(special)g(cases:)57 b(basically)36 b(cross-)2049 +2994 y(processor)d(ipc,)h(e)o(xplicit)e(migration)g(to)f(a)h(ne)n(w)g +(processor)m(,)j(and)e(cross-)2049 3077 y(processor)24 +b(tcb)f(accesses)h(through)h(the)e(Nucleus)h(calls)f +Fg(lthread)p 3781 3077 23 4 v 24 w(e)n(x)p 3882 3077 +V 27 w(regs)2049 3160 y Fm(and)g Fg(thread)p 2397 3160 +V 25 w(schedule)p Fm(.)32 b(None)23 b(of)g(those)g(operations)h(\226)f +(remember)g(that)2049 3243 y(we)j(listed)h(only)g(cross-processor)h +(operations)g(\226)e(seem)h(to)g(be)g(\002rst-class)2049 +3326 y(time)19 b(critical.)2049 3580 y Fk(2.1)83 b(Pr)n(ocessor)n(-Sc)o +(heduling)25 b(Gran)o(ularity)2049 3729 y Fm(So)19 b(the)g(\002rst)f +(design)h(decision)h(has)f(to)g(be)g(about)h(scheduling)g(granularity) +-5 b(.)2132 3821 y(Old-f)o(ashioned)42 b(SMPs)d(with)h(little)f(cache)i +(memory)g(permitted)f(to)2049 3904 y(transfer)27 b(a)g(thread)h(ine)o +(xpensi)n(vly)g(to)f(another)h(processor)l(.)49 b(T)-6 +b(oday')l(s)28 b(sys-)2049 3987 y(tems)16 b(with)g(lar)o(ge,)g +(multi-le)n(v)o(el)g(caches)h(and)g(e)o(xtremenly)g(high)g(cache-miss) +2049 4070 y(costs)23 b(increased)g(transfer)g(costs)f +Fl(for)h(running)h(thr)m(eads)f Fm(dramaticlly)-5 b(.)34 +b(F)o(or)2049 4153 y(e)o(xample,)24 b(a)e(thread)h(currently)g(using)h +(50)f(cache)g(lines)f(read-only)i(and)f(50)2049 4236 +y(cache)16 b(lines)f(read-write)g(requires)h(10\22620)g +Fh(\026)p Fm(s)f(on)h(a)f(500)h(MHz)g(Pentium)f(III,)2049 +4319 y(i.e.)39 b(5,000\22610,000)27 b(c)o(ycles.)40 b(Note)25 +b(that)f(this)g(is)g(only)h(the)g(time)f(required)2049 +4402 y(to)e(transfer)g(the)g(dirty)f(\(minimum)h(time\))g(or)g(all)f +(\(maximum)i(time\))e(cache)2049 4485 y(lines)e(from)g(one)h(L2)f +(cache)h(via)f(the)g(memory)h(b)o(us)f(to)g(the)g(other)g(L2)g(cache.) +2049 4568 y(Since)25 b(b)o(us)h(load)g(is)f(typically)h(v)o(ery)g(high) +h(in)e(a)h(quad-processor)i(system,)2049 4651 y(the)21 +b(ef)n(fecti)n(v)o(e)g(costs)g(could)g(double,)h(i.e.)e(might)g +(increase)i(to)e(up)h(to)g(40)g Fh(\026)p Fm(s,)2049 +4734 y(because)g(the)e(b)o(us)g(is)g(not)h(a)o(v)n(ailable)g(for)f(the) +g(other)h(three)3544 4702 y Fj(2)3592 4734 y Fm(processors)h(dur)o(-) +2049 4817 y(ing)26 b(this)f(time.)43 b(This)25 b(analysis)i(is,)f +(e.g.,)h(corroborated)g(by)f(Kitche)n(w)o(an')l(s)2049 +4900 y(\(no)n(w)19 b(K42')l(s\))g(analysis)h(and)f(e)o(xperiences.)2132 +4992 y(Concluding,)33 b(it)28 b(seems)i(unreasonable)h(to)d(e)o(x)o +(ecute)i(thread)g(transfers)2049 5075 y(more)19 b(often)g(than)h(one)f +(per)g(200)h Fh(\026)p Fm(s)f(on)h(a)o(v)o(erage.)j(This)c(leads)g(to)p +2049 5163 901 4 v 2139 5219 a Fj(2)2169 5242 y Fi(The)j(destination)k +(processor)d(requests)h(those)g(cache)g(lines,)h(i.e.)d(will)h(not)g +(run)2049 5321 y(another)k(thread)f(during)g(this)f(acti)n(vity)l(.)47 +b(Ho)n(we)n(v)o(er)m(,)28 b(the)e(source)g(processor)f(is)g(not)2049 +5400 y(acti)n(v)o(ely)20 b(en)m(v)o(olv)o(ed,)f(and)e(can)h(thus)g(run) +f(another)h(thread.)p eop +%%Page: 2 2 +2 1 bop 1387 -300 a Fq(\227)20 b(Dr)o(aft)h(of)f(December)g(10,)f(1999) +g(\227)-64 -67 y Ff(\017)42 b Fe(Design)f(decision)g(1:)68 +b Fl(F)m(ine-gr)o(ain)41 b(dispatc)o(hing)i(and)f(sc)o(hedul-)16 +16 y(ing)30 b(will)f(not)i(implicitly)e(tr)o(ansfer)h(thr)m(eads)h(to)f +(other)h(pr)m(ocessor)o(s.)16 99 y(Thr)m(ead)20 b(tr)o(ansfer)f(has)g +(always)h(to)f(be)g(initiated)g(by)g(a)g(Nucleus)g(call.)-150 +269 y Fm(Conclusions)h(from)f(design)h(decision)g(1:)-82 +421 y(1.)42 b(Ready-list)23 b(and)g(short-w)o(ak)o(eup)i(queue)f(e)o +(xist)f(per)g(processor)l(.)36 b(Dis-)16 504 y(patching)20 +b(and)g(\002ne-grain)f(scheduling)h(w)o(orks)g(processor)o(-locally)-5 +b(.)-82 658 y(2.)42 b(The)26 b(Nucleus)g(call)g Fd(thread)p +752 658 23 4 v 28 w(switch)f Fm(operates)i(processor)o(-local.)45 +b(In)16 741 y(particular)m(,)32 b(switching)e(to)g(a)f(thread)h(that)g +(currently)g(resides)g(on)g(a)16 824 y(dif)n(ferent)17 +b(processor)i(w)o(orks)e(lik)o(e)h(an)f(unspeci\002c)h +Fd(thread)p 1516 824 V 27 w(switch)f Fm(op-)16 907 y(eration.)-82 +1060 y(3.)42 b(A)18 b(nucleus)h(call)f(is)f(needed)j(for)e(thread)g +(transfer)l(.)23 b(Of)17 b(course,)i(access)16 1143 y(to)26 +b(that)f(operation)i(has)f(to)f(be)h(someho)n(w)h(protected.)44 +b(An)25 b(ob)o(vious)16 1226 y(w)o(ay)d(to)f(do)h(so)g(is)f(to)g(use)h +(the)g(same)f(mechanism)i(that)e(already)h(con-)16 1309 +y(trols)g(other)h(scheduling)h(parameters)f(such)h(as)e(priority)h(and) +g(times-)16 1392 y(lice.)16 1475 y(Therefore)31 b(we)g(e)o(xtended)i +(the)e(Nucleus)h(call)e Fd(thread)p 1485 1475 V 28 w(schedule)i +Fm(is)16 1558 y(e)o(xtended)g(by)g(another)f(parameter)m(,)j(the)d +(processor)h(number)l(.)60 b(By)16 1641 y(changing)22 +b(this)f(parameter)m(,)g(a)g(user)o(-le)n(v)o(el)g(scheduler)h(can)f(e) +o(xplicitly)16 1724 y(transfer)e(a)g(thread)g(to)g(another)h(processor) +l(.)-150 1938 y Fk(2.2)83 b(Thread)23 b(Mobility)g(at)g(the)g(Nuc)n +(leus)g(Le)o(vel)-150 2073 y Fm(Mobility)f(is)g(a)f(thread')l(s)h +(ability)g(to)g(transfer)f(or)h(being)h(transferred)f(to)g(an-)-150 +2156 y(other)d(processor)l(.)-67 2240 y(The)28 b(Nucleus)h(has)g(to)f +(of)n(fer)g(an)h(operation)g(that)g(e)o(xplicitly)f(transfers)-150 +2323 y(a)h(thread)g(to)g(another)g(processor)l(.)54 b(Such)29 +b(an)g(operation)h(is)e(required)i(for)-150 2406 y(higher)o(-le)n(v)o +(el)c(\(user)o(-le)n(v)o(el\))f(serv)o(ers)h(that)f(implement)h +(arbitrary)g(schedul-)-150 2489 y(ing)d(policies.)34 +b(W)-6 b(e)21 b(e)o(xtended)j(the)f(Nucleus)g(call)f +Fd(thread)p 1364 2489 V 28 w(schedule)h Fm(as)g(de-)-150 +2572 y(scribed)c(in)g(conclusion)i(3)e(to)g(do)g(this.)-67 +2656 y(Implicit)h(thread)h(transfers)f(on)h(the)f(Nucleus)h(le)n(v)o +(el)g(through)g(\002ne-grain)-150 2739 y(Nucleus)33 b(scheduling)h +(were)e(already)h(rejected)f(by)h(design)g(decision)g(1.)-150 +2822 y(T)-6 b(w)o(o)21 b(potential)g(opportunities)h(for)f(Nucleus-le)n +(v)o(el)h(mobility)f(remain:)27 b(\(a\))-150 2905 y(restricted)g(e)o +(xplicit)g(thread)h(transfer)f(without)g(contacting)h(a)f(scheduling) +-150 2988 y(serv)o(er)m(,)19 b(and)g(\(b\))g(implicit)f(mobility)h(on)h +(IPC.)-67 3072 y(\(a\))25 b(A)f(scenario)i(might)f(include)g(that)g(a)g +(scheduler)h(can)f(specify)g(a)g(set)-150 3155 y(of)g(directly)g +(accessable)h(processors)f(for)g(a)g(thread)g(such)h(that)e(the)h +(thread)-150 3239 y(could)18 b(then)f(transfer)f(itself)g(to)h(an)o(y)g +(of)g(those)g(processors.)24 b(Ho)n(we)n(v)o(er)m(,)17 +b(since)-150 3322 y(the)27 b(costs)g(of)g(transferring)g(a)g(thread)g +(to)g(a)g(dif)n(ferent)g(processor)h(are)f(1\2262)-150 +3405 y(orders)18 b(of)g(magnitude)h(higher)g(than)f(a)g(short)g +(intra-processor)h(ipc,)f(there)g(is)-150 3488 y(no)f(reason)h(to)f +(add)g(such)h(a)f(feature)g(to)g(the)g(Nucleus.)23 b(It)16 +b(is)g(al)o(w)o(ays)i(feasible,)-150 3571 y(e)n(v)o(en)h(preferrable)g +(from)g(a)f(polic)o(y)h(point)g(of)f(vie)n(w)-5 b(,)19 +b(to)f(contact)h(a)g(user)o(-le)n(v)o(el)-150 3654 y(scheduler)h +(through)g(ipc.)-67 3738 y(\(b\))k(Mobility)g(on)h(cross-processor)g +(ipc)f(is)g(a)g(slightly)g(dif)n(ferent)g(prob-)-150 +3821 y(lem.)43 b(Firstly)-5 b(,)26 b(cross-address-space)h(ipc)f(is)f +(itself)f(an)i(e)o(xpensi)n(v)o(e)h(opera-)-150 3904 +y(tion)22 b(\226)g(although)h(probably)g(cheaper)g(than)f(a)g(thread)g +(transfer)l(.)32 b(Secondly)-5 b(,)-150 3987 y(transferring)20 +b(the)g(sender)h(or)f(recei)n(v)o(er)h(to)f(the)g(processor)h(of)f(its) +f(respecti)n(v)o(e)-150 4070 y(partner)h(can)f(ha)o(v)o(e)h(v)o(ery)f +(positi)n(v)o(e)h(ef)n(fects)f(if)g(either)g(\(i\))f(both)i(partners)g +(will)-150 4153 y(communicate)h(hea)o(vily)f(through)h(ipc)f(in)f(the)h +(near)g(future)g(or)f(\(ii\))g(both)h(use)-150 4236 y(a)f(lar)o(ge)g +(amount)g(of)g(shared)h(data)f(subsequently)i(to)e(the)g(ipc.)-67 +4320 y(Implicit)d(mobility)h(on)h(ipc)f(w)o(ould)h(enable)g(schedulers) +g(to)f(specify)-5 b(,)17 b(e.g.,)-150 4403 y(that)28 +b(a)h(certain)g(thread,)i(sender)e(or)g(recei)n(v)o(er)m(,)i(should)e +(be)g(automaticllay)-150 4486 y(transferred)e(to)g(the)g(respecti)n(v)o +(e)h(partner')l(s)f(processor)h(on)f(ipc.)47 b(A)27 b(serv)o(er)-150 +4569 y(thread)20 b(with)f(the)g(mobile-on-recei)n(v)o(e)i(option)f(w)o +(ould)g(then)f(automatically)-150 4652 y(run)j(on)f(its)g(clients)g +(processor)l(.)32 b(W)m(ith)20 b(mobile-on-send,)k(the)d(same)h(serv)o +(er)-150 4735 y(thread)c(w)o(ould)h(instead)f(al)o(w)o(ays)h(mo)o(v)o +(e)f(to)f(its)h(last)f(client')l(s)g(processor)i(after)-150 +4818 y(e)o(x)o(ecuting)k(its)f(\002rst)f(request.)34 +b(The)22 b(ne)o(xt)h(idea)f(is)g(ob)o(vious:)31 b(you)23 +b(probably)-150 4901 y(w)o(ant)e(the)f(serv)o(er)h(thread)g(to)f +(decide)i(on)f(a)f(case-by-case)i(basis)f(whether)f(it)-150 +4984 y(should)g(transfer)f(or)g(not,)g(etc.)-67 5068 +y(This)31 b(illustrates)h(clearly)g(that)f(mobility)h(on)h(ipc)e(is)h +(a)g Fl(policy)l(,)j Fm(not)d(a)-150 5151 y Fl(mec)o(hanism.)d +Fm(The)21 b(sk)o(etched)h(\223mobile-on-send/recei)n(v)o(e\224)h +(primiti)n(v)o(es)e(are)-150 5234 y(insuf)n(\002cient.)34 +b(An)o(y)23 b(such)g(mechanism)h(w)o(ould)f(probably)h(include)g +(unnec-)-150 5317 y(essary)18 b(polic)o(y)f(in)g(the)g(Nucleus,)h +(i.e.,)e(w)o(ould)i(thus)f(be)h(too)f(restricti)n(v)o(e.)22 +b(Per)o(-)-150 5400 y(formance)28 b(ar)o(guments)g(corroborate)h(to)e +(drop)i(implict)e(mobility)g(on)h(ipc:)2049 -67 y(Rpc)18 +b(to)g(a)g(user)o(-le)n(v)o(el)g(scheduler)h(follo)n(wed)g(by)f(an)h(e) +o(xplict)f(scheduling)h(op-)2049 16 y(eration)h(is)g(al)o(w)o(ays)g(ne) +o(gligible)h(compared)g(to)f(the)g(implicit)f(o)o(v)o(erhead)i(of)f(a) +2049 99 y(thread)e(transfer)l(.)k(Thus)17 b(arbitrary)g +(mobility-on-ipc)h(polic)o(y)g(can)f(be)h(imple-)2049 +182 y(mented)g(outside)h(the)f(Nucleus)g(pro)o(vided)h(user)o(-le)n(v)o +(el)f(softw)o(are)f(can)i(easily)2049 265 y(and)h(ine)o(xpensi)n(v)o +(ely)g Fl(detect)f(cr)m(oss-pr)m(ocessor)i(ipc.)2135 +456 y Ff(\017)42 b Fe(Design)19 b(decision)h(2:)25 b +Fl(The)19 b(Nucleus)h(will)f(not)h(of)o(fer)f(implicit)g(mobil-)2215 +539 y(ity)g(on)h(ipc.)26 b(Instead,)20 b(the)g(Nucleus)g(will)f +(support)h(c)o(heap)h(and)g(easily)2215 622 y(usable)f(mec)o(hanisms)g +(to)e(detect)i(cr)m(oss-pr)m(ocessor)g(ipc.)2049 813 +y Fm(Basically)-5 b(,)43 b(there)38 b(are)g(tw)o(o)h(dif)n(ferent)f(w)o +(ays)h(for)f(detection)h(of)g(cross-)2049 896 y(processor)22 +b(ipc:)27 b(either)21 b(\(a\))g(ipc)g(informs)g(the)g(in)m(v)o(ok)o(er) +h(about)f(its)g(partner')l(s)2049 979 y(processor)m(,)34 +b(or)d(\(b\))f(ipc)h(can)g(be)g(parametrized)h(such)f(that)f(it)g(f)o +(ails)h(on)g(a)2049 1062 y(cross-processor)26 b(ipc.)40 +b(Conceptually)-5 b(,)26 b(\(a\))f(is)f(a)g(trap,)h(i.e.)f(signals)h +(cross-)2049 1145 y(processor)30 b(ipc)f Fl(after)g Fm(it)f(completed,) +k(while)d(\(b\))g(is)f(a)h(f)o(ault,)i(i.e.)d(signals)2049 +1228 y Fl(befor)m(e)20 b Fm(ipc)f(is)f(e)o(x)o(ecuted.)2132 +1318 y(Mechanism)f(\(a\),)e(e)o(xtending)h(ipc)g(such)f(that)g(it)g +(reports)g(cross-processor)2049 1401 y(ipc)k(after)g(completion,)g(is)g +(good)h(for)f(e)o(xperimental)h(purposes)g(\(e)n(v)o(en)g(ideal)2049 +1484 y(for)f(serv)o(er)h(threads)f(that)g(try)h(to)f(adopt)h +(dynamically)g(to)f(clients\))g(and)h(easy)2049 1567 +y(to)14 b(implement.)22 b(Its)14 b(only)i(disadv)n(antage)g(seems)f(to) +f(be)h(that)f(in)h(some)g(cases)g(a)2049 1650 y(cross-processor)20 +b(ipc)e(might)g(be)h(detected)g(only)f(after)g(it)g(happened.)25 +b(Ho)n(w-)2049 1733 y(e)n(v)o(er)m(,)i(currently)f(the)g(authors)g(are) +g(not)g(a)o(w)o(are)g(of)f(a)h(scenario)g(where)g(this)2049 +1816 y(delayed)20 b(detection)g(could)f(mak)o(e)h(a)f(dif)n(ference.) +2132 1905 y(Mechanism)28 b(\(b\))f(w)o(ould)h(signal)f(cross-processor) +i(ipc)e(before)g(it)g(w)o(as)2049 1988 y(e)o(x)o(ecuted.)52 +b(Ho)n(we)n(v)o(er)m(,)31 b(puristically)-5 b(,)30 b(it)d(could)i(w)o +(ork)g(only)g(on)f(send/call)2049 2071 y(operations;)20 +b(applied)f(to)g(recei)n(v)o(e)h(operations,)f(it)f(de)o(generates)j +(to)e(\(a\).)2132 2161 y(In)c(f)o(act,)h(the)g(dif)n(ferences)g +(between)g(both)g(possibilities)f(seem)g(to)h(be)f(ne)o(g-)2049 +2244 y(ligible)h(for)h(an)f(e)o(xperimental)i(Nucleus.)k(F)o(or)16 +b(the)h(time)f(being,)h(we)g(decided)2049 2327 y(to)i(implement)h +(\(a\),)e(see)i(Section)f(4.2,)g(since)h(on)f(the)h(current)f(x86)h(v)o +(ersion,)2049 2410 y(the)25 b(small)g(number)h(of)g(a)o(v)n(ailable)f +(re)o(gisters)g(let)g(us)g(prefer)h(an)f(additional)2049 +2493 y(output)20 b(parameter)f(instead)g(of)g(another)h(input)f +(parameter)l(.)2049 2733 y Fk(2.3)83 b(Co)n(ver)r(t)23 +b(Channels)2049 2878 y Fm(Clearly)-5 b(,)16 b(an)o(y)h(method)h(of)e +(detecting)h(on)g(which)g(processor)g(another)g(thread)2049 +2961 y(or)31 b(e)n(v)o(en)h(the)f(current)h(is)f(running)h(could)g(be)g +(used)f(for)h(a)f(co)o(v)o(ert)g(chan-)2049 3044 y(nel.)39 +b(The)24 b(abo)o(v)o(e)h(discussed)g(Nucleus)g(features)f(for)g +(detection)h(of)f(cross-)2049 3127 y(processor)18 b(ipc)g(are)f(the)h +(\002rst)e(SMP-speci\002c)h(methods)h(inside)g(the)f(Nucleus)2049 +3210 y(that)25 b(inherently)h(of)n(fer)f(co)o(v)o(ert)g(channels.)43 +b(Besides)26 b(cross-processor)o(-ipc)2049 3293 y(detection,)36 +b(processor)o(-number)f(information)e(could)h(only)f(be)g(recei)n(v)o +(ed)2049 3376 y(through)40 b(a)e(user)o(-le)n(v)o(el)g(scheduler)l(.)83 +b(So)38 b(co)o(v)o(er)o(-channel-free)i(policies)2049 +3459 y(could)20 b(ha)o(v)o(e)f(been)h(implemented.)2132 +3548 y(No)n(w)-5 b(,)47 b(in)41 b(the)g(presence)h(of)g(Nucleus-based)g +(detection)g(of)g(cross-)2049 3631 y(processor)20 b(ipc,)f(the)g(ne)n +(w)g(co)o(v)o(er)g(channel)h(can)g(no)f(longer)h(be)f(controlled.)2132 +3721 y(W)-6 b(e)31 b(ha)o(v)o(e)g(slightly)g(decreased)h(the)g(channel) +g(by)f(not)h(deli)n(v)o(ering)g(the)2049 3804 y(processor)e(number)f(b) +o(ut)g(only)g(dif)n(ferentiate)g(between)g(\223my)h(processor\224)2049 +3887 y(and)21 b(\223another)h(processor\224.)30 b(Ho)n(we)n(v)o(er)m(,) +22 b(the)e(security)h(ef)n(fect)g(is)g(still)e(ques-)2049 +3970 y(tionable.)43 b(Finally)-5 b(,)26 b(e)n(v)o(en)h(without)e +(Nucleus-based)i(detection)f(of)g(cross-)2049 4053 y(processor)e(ipc,)h +(an)o(yone)f(could)h(easily)e(\002nd)g(out)h(whether)g(its)e(partner)i +(re-)2049 4136 y(sides)30 b(on)g(the)g(same)g(processor)h(or)e(not)h +(until)g(it)f(can)h(read)g(a)f(\002ne-grain)2049 4219 +y(clock.)2132 4308 y(Fundamentally)-5 b(,)28 b(the)e(non-transparenc)o +(y)i(goal)e(5)f(contradicts)h(the)g(re-)2049 4391 y(quest)e(to)g +(disable)g(co)o(v)o(ert)g(channels.)38 b(This)24 b(questions)g(remains) +g(open)h(for)2049 4474 y(discussion.)2132 4564 y(Assuming)j(that)f(we)g +(w)o(ould)h(later)e(conclude)j(that)e(we)g(ha)o(v)o(e)g(to)g(a)o(v)o +(oid)2049 4647 y(Nucleus-based)j(detection)g(of)f(cross-processor)h +(ipc,)h(we)d(could)i(switch)2049 4730 y(to)23 b(implicit)g +(mobility-on-recei)n(v)o(e)h(as)f(an)h(option.)37 b(\(Most)23 +b(threads)h(w)o(ould)2049 4813 y(run)f(in)f(a)g(no-mobility)h(mode.\)) +35 b(Processor)o(-number)23 b(information)g(w)o(ould)2049 +4896 y(then)j(no)f(longer)h(be)g(a)o(v)n(ailable)f(through)i(the)e +(Nucleus)h(pro)o(vided)g(that)f(no)2049 4979 y(clocks)d(were)g +(readable.)31 b(An)22 b(alternati)n(v)o(e)f(solution)i(w)o(ould)f(be)g +(to)f(drop)h(all)2049 5062 y(such)h(mechanisms)g(and)f(use)h(the)f +(projected)h(V)-8 b(ersion)22 b(5)g(mechanisms)h(for)2049 +5145 y(mapping)d(threads.)2132 5234 y(Since)h(the)g(absence)h(of)f +(clock-related)g(co)o(v)o(ert)g(channels)h(seems)g(to)e(un-)2049 +5317 y(realistic)f(for)g(the)h(near)f(future)h(and)g(since)g(V)-8 +b(ersion)19 b(5)h(is)f(not)g(yet)h(a)o(v)n(ailable,)2049 +5400 y(we)f(decide:)1931 5700 y(2)p eop +%%Page: 3 3 +3 2 bop 1387 -300 a Fq(\227)20 b(Dr)o(aft)h(of)f(December)g(10,)f(1999) +g(\227)-64 -67 y Ff(\017)42 b Fe(Design)18 b(decision)g(2a:)24 +b Fl(F)-8 b(or)18 b(the)g(time)g(being)o(,)h(co)o(vert-c)o(hannel)h(pr) +m(ob-)16 16 y(lems)25 b(ar)m(e)h(ignor)m(ed.)45 b(As)25 +b(soon)h(as)g(\(1\))f(we)h(have)g(enough)h(pr)o(actical)16 +99 y(e)o(xperiences)h(with)f(SMP)h(applications)h(and)f(\(2\))f(co)o +(vert)h(c)o(hannels)16 182 y(avoidance)21 b(seems)e(possible)o(,)g +(design)h(decision)g(2)f(will)f(be)h(r)m(e)o(visited.)16 +265 y(Design)f(decision)g(2)f(will)f(also)h(be)h(r)m(e)o(visited)f(for) +g(Nucleus)h(V)-8 b(er)o(sion)17 b(5.)-150 479 y Fk(2.4)83 +b(Cr)n(oss-Pr)n(ocessor)25 b(IPC)-150 615 y Fm(Ipc)36 +b(across)g(processor)h(boundaries)h(is)d(basically)i(an)f +(implementation)-150 698 y(problem.)53 b(The)28 b(compatibility)h(goal) +g(1)f(and)h(the)g(transparenc)o(y)h(goals)f(2)-150 781 +y(and)20 b(3)f(enforce)g(almost)g(automatically)h(the)f(ne)o(xt)g +(design)h(decision:)-64 951 y Ff(\017)42 b Fe(Design)36 +b(decision)h(3:)58 b Fl(Ipc)37 b(works)f(intr)o(a-pr)m(ocessor)i(as)f +(well)f(as)16 1034 y(cr)m(oss-pr)m(ocessor)-8 b(.)57 +b(The)29 b(functionality)i(is)e(identical)h(for)g(both)g(\003a-)16 +1117 y(vor)o(s.)49 b(Ipc)27 b(can)h(be)f(used)h(tr)o(anspar)m(ently)l +(,)i(i.e)o(.)d(communicating)h(do)16 1200 y(not)g(have)g(to)g(car)m(e)g +(about)h(on)f(whic)o(h)f(r)m(espective)i(pr)m(ocessor)o(s)g(the)n(y)16 +1283 y(run.)24 b(Howe)o(ver)-8 b(,)18 b(the)n(y)h(can)h(car)m(e)g +(about)f(that)g(detail)g(\(see)g(abo)o(ve\).)-150 1497 +y Fk(2.5)83 b(VM)24 b(Primitives)-150 1633 y Fm(This)h(paper)i(focuses) +g(on)f(threads.)45 b(As)25 b(of)h(our)g(current)h(kno)n(wledge,)i(the) +-150 1716 y(VM)d Fl(interface)f Fm(does)h(not)g(need)g(to)g(be)f(e)o +(xtended)i(for)e(SMPs.)42 b(The)25 b(SMP)-150 1799 y +Fl(implementation)30 b Fm(of)f(VM,)f(ho)n(we)n(v)o(er)m(,)33 +b(is)28 b(performance-critical)i(and)g(not)-150 1882 +y(tri)n(vial.)45 b(The)27 b(implementation)g(topic)g(will)e(be)i +(discussed)h(in)e(detail)g(in)h(a)-150 1965 y(further)d(paper)l(.)37 +b(Whether)24 b(the)g(current)g(VM)f(primiti)n(v)o(es)h(and)g +(abstraction)-150 2048 y(are)29 b(suf)n(\002cient)g(for)g(higher)o(-le) +n(v)o(el)h(VM)f(policies)g(on)h(SMPs,)g(e.g.)f(enable)-150 +2131 y(K42')l(s)18 b(split)f(address-space)i(technology)-5 +b(,)20 b(will)d(be)g(discussed)i(in)f(the)f(same)-150 +2214 y(paper)l(.)-150 2453 y Fn(3)100 b(API)28 b(Extensions)-150 +2615 y Fm(SMP-speci\002c)15 b(API)g(e)o(xtensions)i(are)f(described.)23 +b(The)16 b(logical)g(description)-150 2698 y(is)23 b(complemented)h(by) +g(the)f(current)g(and)h(pro)o(visional)g(description)g(of)f(the)-150 +2781 y(x86)29 b(interf)o(ace.)53 b(Note)28 b(that)h(the)g(x86)g(interf) +o(ace)g(will)f(change)i(when)f(the)-150 2864 y(v)o(ersion)20 +b(4)f(and)g(5)g(binary)h(interf)o(aces)f(are)g(de\002ned.)-150 +3062 y Fc(ipc)74 b Fm(Output)29 b(parameters)h(are)f(complemented)i(by) +e(a)g Fl(cr)m(oss-pr)m(ocessor)-150 3145 y(\003a)o(g)p +Fm(.)50 b(It)27 b(is)g(set)g(when)h(the)g(last)f(communictation)i(w)o +(as)f(cross)g(processor)-150 3228 y(boundaries,)22 b(reset)f +(otherwise.)28 b(F)o(or)20 b(tw)o(o-phase)h(ipc)g(operations,)g(i.e.)f +Fl(call)-150 3311 y Fm(and)28 b Fl(r)m(eply/wait)p Fm(,)i(\223last)d +(communication\224)i(means)g(the)e(second)i(part;)j(for)-150 +3394 y(single-phase)26 b(ipcs,)g(it)e(refers)h(to)g(the)f(\002rst)g +(part.)41 b(Note)25 b(that)f(no)h(ef)n(fecti)n(v)o(e)-150 +3477 y(communication,)20 b(i.e.)f(timeouts,)g(cancelations,)g(and)h +(aborts)g(do)f(ne)n(v)o(er)h(set)-150 3560 y(the)15 b(cross-processor)i +(\003ag.)22 b(User)15 b(programs)h(may)g(deliberately)g(ignore)g(the) +-150 3643 y(\003ag.)-150 3727 y Fb(Pr)m(o)o(visional)j(x86)e +(implementation:)-150 3810 y Fi(The)i(cross-processor)i(\003ag)f(is)f +(encoded)j(in)d(the)i(processor')l(s)f(Z-\003ag.)28 b +Fb(Anyone)20 b(who)-150 3893 y(wants)j(to)g(r)n(ead)g(the)g(cr)m +(oss-pr)m(ocessor)h(\003a)o(g)f(after)h(ipc)f(has)f(to)h(set)g(the)h +(pr)m(ocessor')m(s)-150 3976 y(Z-\003a)o(g)19 b(prior)f(to)h(in)m(vok)o +(e)i(the)e(ipc)g(Nucleus)h(call.)25 b Fi(If)18 b(this)h(w)o(as)g(done,) +g(NZ)e(after)j(com-)-150 4059 y(pletion)j(of)e(the)g(Nucleus)h(call)g +(means)f(cross-processor)i(\003ag)e(set,)g(Z)f(means)h(cross-)-150 +4142 y(process)d(\003ag)f(reset.)-150 4340 y Fc(thread)p +84 4340 23 4 v 25 w(s)o(witc)o(h)74 b Fm(A)85 b(speci\002c)h +Fd(thread)p 1054 4340 V 28 w(switch)f(\()p Fh(t)p Fd(\))g +Fm(w)o(orks)i(as)-150 4423 y Fd(thread)p 40 4423 V 28 +w(switch)35 b(\(0\))g Fm(if)f(the)h(thread)h Fh(t)e Fm(currently)i +(resides)f(on)h(a)f(proces-)-150 4506 y(sor)19 b(dif)n(ferent)g(from)g +(the)g(in)m(v)o(oking)h(thread')l(s)f(processor)l(.)-150 +4703 y Fc(thread)p 84 4703 V 25 w(sc)o(hedule)72 b Fm(Input)46 +b(and)h(output)f(parameters)g(are)g(comple-)-150 4786 +y(mented)20 b(by)f(the)g Fl(pr)m(ocessor)h(number)-8 +b(.)-150 4870 y Fb(Pr)m(o)o(visional)19 b(x86)e(implementation:)-150 +4953 y Fi(Bits)f(16\22619)g(of)g(the)g Fb(par)o(am)g(wor)n(d)p +Fi(,)f(re)o(gister)j(EAX,)c(are)i(used)g(to)g(encode)h(the)g(proces-) +-150 5036 y(sor)i(number)l(.)29 b(V)-7 b(alid)20 b(processor)h(numbers) +e(are)h(1\22615.)29 b(F)o(or)19 b(compatibility)k(reasons,)-150 +5119 y(the)18 b(processor)g(number)f(0)g(means)h(\223in)m(v)n +(alid\224.)-150 5317 y Fc(Clari\002cation)72 b Fm(T)-6 +b(ask)27 b(and)h(thread)f(creation)h(is)f(not)g(changed.)50 +b(Ne)n(wly)-150 5400 y(created)19 b(threads)h(will)e(initially)g(run)h +(on)h(the)f(creator')l(s)g(processor)l(.)2049 -67 y Fc(K)o(ernel)25 +b(Inf)o(o)g(P)n(a)o(g)q(e)73 b Fm(The)24 b(k)o(ernel)h(info)f(no)n(w)g +(also)h(contains)f(the)g(max-)2049 16 y(imum)31 b(processor)g(number)l +(.)58 b(\()p Fh(k)32 b Fm(processors)g(are)e(numbered)i(1)f(to)f +Fh(k)r Fm(,)j(0)2049 99 y(means)20 b(in)m(v)n(alid\))2049 +183 y Fb(Pr)m(o)o(visional)f(x86)e(implementation:)2049 +266 y Fi(Maximum)24 b(processor)h(number)f(is)f(contained)k(in)d(an)g +(8-bit)g(w)o(ord)h(at)f(relati)n(v)o(e)i(po-)2049 349 +y(sition)g(0xB8)f(in)g(the)g(k)o(ernel-info)j(page.)44 +b(The)24 b(higher)i(24)f(bits)g(of)f(that)i(w)o(ord)f(are)2049 +432 y(reserv)o(ed)19 b(for)e(future)h(use,)f Fa(n)p Fi(-w)o(ay)g(SMPs)f +(and)i(NUMAs.)2049 669 y Fn(4)100 b(Implementation)2049 +831 y Fm(A)42 b(fundamental)i(in)m(v)n(ariant)f(for)g(the)f(\002rst)g +(e)o(xperimental)h(V)-8 b(ersion)43 b(of)2049 914 y(L4/SMP)18 +b(is)2215 1065 y(Internally)-5 b(,)23 b(thread)f(control)g(blocks)h +(are)f(ne)n(v)o(er)g(written)f(cross)2215 1148 y(processor)34 +b(boundaries.)66 b(Thus)33 b(the)g(thread)g(that)f(currently)2215 +1231 y(e)o(x)o(ecutes)f(on)f(processor)h Fh(i)e Fm(has)i(complete)f +(control)g(o)o(v)o(er)g(all)2215 1314 y(threads)20 b(that)e(are)h +(currently)h(assigned)g(to)e(processor)i Fh(i)p Fm(.)2049 +1466 y(On)27 b(the)f(one)i(hand,)h(the)e(Nucleus)g(can)g(al)o(w)o(ays)g +(directly)g(access)g(threads)2049 1549 y(that)17 b(reside)g(on)g(the)g +(same)g(processor)m(,)h(e.g.)f(for)g(ipc,)g(scheduling,)h(dispatch-) +2049 1632 y(ing,)27 b(and)g(e)o(xchange)g(of)f(thread)g(re)o(gisters.) +43 b(No)25 b(synchronization)j(primi-)2049 1715 y(ti)n(v)o(es)19 +b(are)g(required)g(for)g(these)g(v)o(ery)h(frequent)f(cases.)2132 +1798 y(On)i(the)g(other)g(hand,)i(accessing)f(a)f(thread)g(that)g +(resides)g(on)h(a)f(dif)n(ferent)2049 1881 y(processor)27 +b(requires)g(al)o(w)o(ays)g(to)f(send)h(the)f(access)h(request)g(to)f +(the)g(desti-)2049 1964 y(nation)i(process)g(and)h(e)o(x)o(ecute)f(it)f +(there.)49 b(By)27 b(f)o(ar)h(most)f(cross-processor)2049 +2047 y(acti)n(vities,)i(e.g.)e(ipc,)j(e)n(v)o(entually)e(require)g(an)o +(yho)n(w)h(destination)f(proces-)2049 2130 y(sor')l(s)22 +b(acti)n(vity)-5 b(.)34 b(\(Remember)22 b(there)h(is)f(no)h(implicit)e +(\002ne-grain)i(processor)2049 2213 y(scheduling.\))38 +b(Therefore,)24 b(it)f(is)g(hoped)h(that)g(in)f(total)g(this)g +(mechanism)h(is)2049 2297 y(not)f(only)h(simpler)f(b)o(ut)g(also)g(f)o +(aster)g(than)h(al)o(w)o(ays)f(locking)h(all)f(participat-)2049 +2380 y(ing)16 b(data)f(structures.)23 b(\(Remember)m(,)16 +b(we)f(e)o(xclude)i(memory)f(mapping)h(from)2049 2463 +y(this)i(discussion.\))2049 2675 y Fk(4.1)83 b(Nuc)n(leus)24 +b(Pr)n(o)n(xy)f(Threads)2049 2809 y Fm(The)g(Nucleus)g(establishes)g +(on)h(e)n(v)o(ery)f(processor)h(a)f(set)f(of)h Fl(pr)m(oxy)h(thr)m +(eads)2049 2893 y Fm(that)i(are)g(responsible)h(to)f(handle)h(all)e +(cross-processor)j(acti)n(vities.)44 b(Only)2049 2976 +y(the)22 b(Nucleus)g(can)g(communicate)h(with)e(those)i(threads.)32 +b(From)21 b(user)o(-le)n(v)o(el)2049 3059 y(perspecti)n(v)o(e,)33 +b(the)o(y)d(do)g(not)g(e)o(xist.)54 b(Nucleus)31 b(communication)g(to)e +(those)2049 3142 y(threads)21 b(is)g(via)g(per)o(-processor)h(mailbox)o +(es)f(for)g(information)g(interchange)2049 3225 y(and)i(through)h +(inter)o(-processor)f(interrupts)g(to)f(trigger)h(acti)n(vities.)33 +b(Incom-)2049 3308 y(ing)19 b(proxy)h(requests)f(are)g(distrib)o(uted)f +(stackwise)h(to)g(the)g(proxy)h(threads)f(of)2049 3391 +y(the)k(destination)h(processor)l(.)36 b(So)23 b(the)g(number)i(of)e +(proxies)g(per)h(processor)2049 3474 y(determines)d(ho)n(w)g(man)o(y)h +(long-lasting)f(acti)n(vities,)f(e.g.)g(long)i(ipcs,)e(can)h(be)2049 +3557 y(handled)16 b(in)f(parallel.)21 b(One)15 b(proxy)h(is)e(al)o(w)o +(ays)i(reserv)o(ed)f(for)g(short)g(acti)n(vities)2049 +3640 y(lik)o(e)k(short)g(ipcs,)g(thread)g(scheduling)i(and)e(e)o +(xchange)i(of)e(thread)g(re)o(gisters.)2132 3723 y(T)-6 +b(o)19 b(reduce)i(cross-processor)g(interrupts,)e(e)n(v)o(ery)h +(processor)h(constantly)2049 3806 y(publishes)30 b(when)g(it)e +(approximately)i(will)e(check)i(its)f(mailbox)g(the)g(ne)o(xt)2049 +3889 y(time)18 b(and)h(the)g(number)g(of)g(currently)g(acti)n(v)o(e)f +(short)h(and)g(long)g(proxy)h(acti)n(v-)2049 3972 y(ities.)38 +b(Cross-processor)25 b(interrupts)g(are)f(then)g(skipped)i(if)d(the)h +(originator)2049 4055 y(could)c(e)o(xpect)f(handling)h(of)f(its)g +(request)g(early)g(enough.)2049 4268 y Fk(4.2)83 b(Ipc)2049 +4402 y Fm(If)26 b(destination)g(and)h(source)g(thread)f(reside)h(on)f +(the)g(same)h(processor)g(the)2049 4485 y(Nucleus)22 +b(w)o(orks)g(e)o(xactly)g(lik)o(e)g(in)g(the)f(uniprocessor)i(case.)32 +b(Otherwise,)21 b(it)2049 4568 y(encodes)27 b(the)g(current)f +(operation)h(and)g(sends)f(it)g(to)g(the)g(destination)h(pro-)2049 +4651 y(cessor')l(s)e(mailbox.)42 b(Ev)o(entually)-5 b(,)27 +b(a)e(proxy)h(will)e(e)o(x)o(ecute)i(the)f(ipc)g(on)h(the)2049 +4734 y(destination)h(processor)m(,)i(i.e.)d(we)g(basically)h(again)g +(ha)o(v)o(e)g(a)f(uniprocessor)2049 4818 y(ipc.)2132 +4901 y(While)17 b(the)h(proxy)g(transfers)g(the)g(message,)g(the)g +(source)g(thread)g(is)f(w)o(ait-)2049 4984 y(ing)26 b(for)f(completion) +h(on)g(the)g(source)g(processor)l(.)43 b(The)26 b(thread)g(is)f(lock)o +(ed)2049 5067 y(b)o(ut)19 b(has)g(released)g(the)g(source)h(processor)l +(.)2132 5151 y(It)26 b(is)g(currently)h(open)g(whether)g(such)g(a)f +(mechanism)h(is)f(good)i(or)e(bad)2049 5234 y(from)d(the)h(cache')l(s)g +(point)g(of)f(vie)n(w)-5 b(.)38 b(Although)24 b(reading)g(a)g(long)g +(message)2049 5317 y(on)h(the)f(destination)h(processor)h(will)d +(surely)i(lead)g(to)f(cache)h(read)g(misses)2049 5400 +y(and)e(according)h(b)o(us)e(traf)n(\002c,)g(writing)g(the)h(data)f +(allocates)h(cache)g(lines)f(on)1931 5700 y(3)p eop +%%Page: 4 4 +4 3 bop 1387 -300 a Fq(\227)20 b(Dr)o(aft)h(of)f(December)g(10,)f(1999) +g(\227)-150 -67 y Fm(the)h(destination)h(processor)l(.)27 +b(This)19 b(is)g(a)h(wide)g(\002eld)g(for)f(tricks)h(\(e.g.)g(write-) +-150 16 y(through)g(on)g(source,)f(uncacheable)i(on)e(dest,)g(etc.\))k +(and)c(e)o(xperiments.)-150 226 y Fk(4.3)83 b(Thread)23 +b(T)-7 b(ransf)o(er)i(,)24 b(etc.)-150 359 y Fm(Explicit)39 +b(thread)g(transfer)g(through)i Fd(thread)p 1080 359 +23 4 v 27 w(schedule)g Fm(uses)e(a)g(similar)-150 442 +y(scheme:)e(the)25 b(thread)h(is)f(\226)g(potentially)h(through)h(a)e +(proxy)h(request)g(to)f(its)-150 525 y(old)19 b(processor)g(\226)f +(frozen)h(on)g(its)f(old)g(processor)h(and)g(then)g(unfrozen)h(on)e +(its)-150 608 y(ne)n(w)i(processor)l(.)25 b(If)19 b(a)h(destination)g +(thread)g(of)f(an)h(ipc)f(is)g(transferred)h(while)-150 +691 y(ipc)k(is)f(still)g(running,)j(ipc)e(is)g(simply)g(restarted)g(by) +g(the)g(source)g(thread)h(of)-150 774 y(the)19 b(ipc)g(operation.)-67 +858 y(Cross-processor)26 b(operations)g Fd(lthread)p +986 858 V 28 w(e)o(x)p 1083 858 V 27 w(re)o(gs)f Fm(w)o(ork)h(through)g +(prox-)-150 941 y(ies.)-150 1150 y Fk(4.4)83 b(K)o(ernel)24 +b(Data)f(Structures)-150 1284 y Fc(4.4.1)73 b(Read)o(y-list)18 +b(and)h(shor)q(t-wakeup)f(queue)-150 1418 y Fm(As)31 +b(discribed)g(in)g(the)g(\002rst)e(conclusion)k(of)d(the)h(\002rst)f +(design)i(principle,)-150 1501 y(each)19 b(processor)h(has)f(to)g +(maintain)g(its)f(o)n(wn)h(ready-list)f(and)i(short-w)o(ak)o(eup)-150 +1584 y(queue.)46 b(The)27 b(implementation)g(of)f(this)g(tw)o(o)h +(lists)e(dif)n(fers)h(slightly)h(from)-150 1667 y(the)c(single)h +(processor)g(v)o(ersion,)g(because)h(the)e(transfered)h(threads)f(has)h +(to)-150 1750 y(be)16 b(remo)o(v)o(ed)g(from)f(the)h(ready)g(list)e +(and)i(short)g(w)o(ak)o(eup)h(queue)f(and)g(inserted)-150 +1833 y(to)j(the)g(destination)g(processor')l(s)h(lists.)-150 +2026 y Fc(4.4.2)73 b(Thread)19 b(Contr)o(ol)g(Bloc)o(k)f(TCB)-150 +2159 y Fm(Because)j(of)g(design)g(decision)g(2)g(it)f(is)g(suf)n +(\002cient)g(to)h(store)f(the)h(actual)g(pro-)-150 2242 +y(cessor)f(number)h(of)f(each)g(thread.)26 b(That)19 +b(is)g(the)h(id)g(of)f(the)h(destination)h(pro-)-150 +2325 y(cessor)m(,)f(the)f(thread)h(w)o(as)f(last)g(mo)o(v)o(ed)i(to.)j +(This)19 b(number)h(will)f(be)g(stored)h(in)-150 2408 +y(the)f(tcb)m(.)-150 2492 y Fb(Pr)m(o)o(visional)g(x86)e +(implementation:)-150 2575 y Fi(Bits)23 b(16\22619)f(of)g(the)h +Fb(pr)m(oc)f(id)h Fi(\002eld,)g(added)g(to)g(the)f(TCB,)g(are)h(used)f +(to)g(encode)i(the)-150 2658 y(processor)i(number)l(.)44 +b(V)-7 b(alid)25 b(processor)h(numbers)f(are)g(1\22615.)43 +b(F)o(or)25 b(compatibility)-150 2741 y(reasons,)17 b(the)h(processor)g +(number)g(0)f(means)g(\223in)m(v)n(alid\224.)-150 2950 +y Fk(4.5)83 b(Current)23 b(Status)-150 3084 y Fm(The)f(current)g +(implementation)h(is)f(in)f(the)h(startup)g(phase.)34 +b(The)21 b(Bootstrap)-150 3167 y(Processor)c(starts)f(up)h(the)g +(single)f(processor)i(v)o(ersion)f(of)g(L4)f(and)i(initialises)-150 +3250 y(its)i(o)n(wn)g(and)h(all)f(global)g(data)h(structures.)27 +b(Then)20 b(it)g(sends)h(a)f(startup)g(ipi)g(to)-150 +3333 y(all)e(processors)i(e)o(xcept)g(him)f(and)h(w)o(aits)e(for)h +(them)g(to)g(initialise)f(themself.)-67 3416 y(Ne)o(xt)d(step)h(is)f +(to)g(implement)h(the)g(initialisation)f(of)g(the)h(local)f(data)h +(struc-)-150 3499 y(tures)24 b(and)g(get)f(the)h(APs)f(into)h(a)f +(state)g(where)h(to)g(w)o(ait)f(for)g(a)h(thread)g(to)f(be)-150 +3582 y(mo)o(v)o(ed)d(to)f(them)g(e)o(xplicitely)-5 b(,)19 +b(i.e.)j(bring)d(up)h(the)f(local)g(dispatcher)h(thread.)-150 +3665 y(Then)g(we)g(ha)o(v)o(e)g(to)f(focus)i(on)f(the)g(changed)h +(system)f(calls)g(and)g(implement)-150 3748 y(the)f(system)g(calls.) +-150 3983 y Fn(A)100 b(x86)28 b(SMP)h(Har)n(d)o(ware)-150 +4143 y Fm(In)17 b(the)g(x86)h(Symmetric)f(Multi)g(Processors)g(Ppro,)g +(PII)f(and)i(PIII)e(each)i(pro-)-150 4226 y(cessor)28 +b(has)f(pri)n(v)n(ate)h(L1)f(and)h(L2)f(caches)h(the)f(ram)h(and)g +(other)f(the)g(other)-150 4310 y(periferal)20 b(components)i(are)e +(shared)h(and)g(accessible)f(via)g(the)h(system)f(b)o(us.)-150 +4393 y(In)e(addition)g(an)g(APIC-based)g(inter)o(-processor)g +(interrupt)g(netw)o(ork)g(e)o(xists.)-150 4476 y(The)30 +b(follo)n(wing)g(sections)g(describe)h(some)f(hardw)o(aremechanisms)j +(pro-)-150 4559 y(vided)20 b(by)f(in)g(a)g(x86)h(SMP)e(machine.)-150 +4768 y Fk(A.1)83 b(Bus)23 b(loc)n(king)-150 4902 y Fm(In)28 +b(multi)f(processor)i(systems)f(read,)j(modify)-5 b(,)30 +b(write)d(memory)i(accesses)-150 4985 y(lik)o(e)20 b(bts,)f(xchg,)i +(xadd,)g(...)j(are)c(coherenc)o(y)i(critical,)c(because)j(tw)o(o)f +(concur)o(-)-150 5068 y(rent)f(threads)h(may)g(read)g(the)f(same)h +(memory)g(location,)g(modify)g(the)f(v)n(alue)-150 5151 +y(and)h(write)f(it)f(back)j(in)e(some)h(order)l(.)k(The)c(contents)g +(of)f(this)g(memory)i(loca-)-150 5234 y(tion)j(is)g(unde\002ned,)i +(because)g(either)e(the)g(\002rst)f(or)h(the)h(second)g(may)f(write) +-150 5317 y(its)c(v)n(alue)i(\002rst.)29 b(So)20 b(some)i(hardw)o(are)g +(mechanism)g(is)f(needed)h(to)f(serialise)-150 5400 y(this)26 +b(combined)i(instructions.)47 b(The)26 b(x86)h(SMP)f(hardw)o(are)i +(does)f(this)f(by)2049 -67 y(locking)19 b(the)f(system)g(b)o(us)g(for)g +(the)g(duration)h(of)f(this)f(single)h(instruction,)h(so)2049 +16 y(before)g(reading)g(the)f(memory)h(location,)g(the)f(b)o(us)g(is)g +(lock)o(ed,)h(the)g(read)f(and)2049 99 y(the)f(modify)h(are)g +(performed)g(and)g(after)f(writing)g(the)g(changed)i(v)n(alue)f(back,) +2049 182 y(the)26 b(b)o(us)h(is)f(released.)46 b(T)-6 +b(o)26 b(a)o(v)o(oid)g(b)o(us)g(locking)h(for)g(read,)h(modify)-5 +b(,)28 b(write)2049 265 y(operations)d(to)e(non)h(critical)f(memory)i +(locations,)f(the)g(x86)g(hardw)o(are)h(in-)2049 348 +y(troduces)f(the)e(lock)i(pre\002x)e(to)h(de\002ne)g(wheter)g(the)g(b)o +(us)g(should)g(be)h(lock)o(ed)2049 431 y(during)c(this)e(operation)i +(or)f(not.)2049 678 y Fk(A.2)83 b(Cac)o(he)24 b(coherenc)o(y)2049 +825 y Fm(In)19 b(the)g(old)g(P1)f(SMPs)g(all)g(accesses)i(to)f(shared)g +(memory)h(locations)f(passes)2049 908 y(the)h(caches)h(and)f(touches)h +(the)f(memory)h(directly)-5 b(.)27 b(In)20 b(Ppro)f(and)i(later)f(pro-) +2049 991 y(cessors,)f(shared)g(memory)h(locations)f(are)f(cached,)i +(too.)j(T)-6 b(o)18 b(k)o(eep)i(the)f(data)2049 1074 +y(coherent,)j(the)e(L2)h(caches)g(snoop)h(the)f(system)g(b)o(us)f(and)h +(perform)g(a)g(Mod-)2049 1157 y(i\002ed)j(Exclusi)n(v)o(e)h(Shared)g +(In)m(v)n(alidate)g(\(MESI\))f(protocol.)40 b(If)24 b(a)h(processor) +2049 1240 y(reads)g(a)f(memory)i(location)f(initially)-5 +b(,)25 b(it)e(gets)i(e)o(xclusi)n(v)o(e)g(access)h(for)e(that)2049 +1323 y(memory)f(location.)34 b(That)22 b(line)g(is)g(cached)h(in)f(its) +g(local)g(L2)g(cache.)34 b(In)23 b(the)2049 1406 y(case)k(that)f +(another)h(processor)h(then)f(reads)g(from)f(the)h(same)g(place,)h +(both)2049 1489 y(cachelines)20 b(are)f(shared.)k(No)n(w)-5 +b(,)19 b(if)f(one)i(processor)g(modi\002es)f(a)f(shared)i(line)2049 +1572 y(the)f(snooping)h(mechanism)g(of)f(the)g(L2)f(caches)i(detects,)f +(that)f(this)h(speci\002c)2049 1655 y(line)i(is)g(modi\002ed)g(in)g(a)g +(dif)n(ferent)g(cache)h(and)g(in)m(v)n(alidates)f(it.)29 +b(The)21 b(writing)2049 1738 y(processor)f(gets)f(e)o(xclusi)n(v)o(e)h +(o)n(wnership)g(of)f(this)g(line.)2049 1984 y Fk(A.3)83 +b(The)23 b(APIC)g(netw)n(ork)2049 2131 y Fm(In)h(the)h(x86)g(SMP)f +(machines)h(each)g(processor)h(has)e(to)h(ha)o(v)o(e)f(a)g(local)h(Ad-) +2049 2214 y(v)n(anced)i(Programmable)f(Interrupt)g(Controller)f(that)h +(replicates)f(the)h(PIC)2049 2297 y(functions)g(and)g(adds)f(some)h +(more)f(features)g(lik)o(e)g(Inter)g(Processor)h(Inter)o(-)2049 +2380 y(rupts)21 b(IPIs.)28 b(The)21 b(peripherals)g(are)g(connected)i +(to)e(one)g(or)g(more)g(IO-APIC)2049 2463 y(units)30 +b(that)f(performs)i(the)f(other)g(side)g(of)f(the)h(PICs.)55 +b(All)29 b(local)h(APICs)2049 2546 y(and)24 b(the)g(IO-APICs)e(are)i +(connected)h(via)f(a)f(three)h(line)f(APIC)g(b)o(us)h(with)f(a)2049 +2629 y(frequenc)o(y)i(of)e(32)h(MHz.)37 b(F)o(or)23 b(hardw)o(are)i +(interrupts,)f(the)f(IO-APICs)g(get)2049 2712 y(the)e(interrupt)h(and)f +(sends)h(it)f(via)g(the)g(APIC)g(b)o(us)g(to)g(the)g(assigned)i(w)o +(aiting)2049 2795 y(APIC)k(unit)h(\(That)g(earlier)f(performed)i(an)f +(IRQ,...\).)49 b(The)28 b(local)g(APICs)2049 2878 y(add)19 +b(some)h(more)f(functionality:)k(self)c(interrupts)f(and)i(inter)e +(processor)i(in-)2049 2961 y(terrupts)25 b(IPIs.)40 b(Self)24 +b(interrupts)i(are)f(usually)g(timer)g(interrupts)g(from)g(the)2049 +3044 y(local)e(APIC)g(clock.)37 b(Inter)23 b(processor)i(interrupts)e +(are)g(softw)o(are)h(initiated)2049 3128 y(interrupts)j(on)g(a)f +(speci\002ed)h(set)f(of)h(destination)g(processors.)47 +b(Similar)25 b(to)2049 3211 y(hardw)o(are)20 b(interrupts,)f(IPIs)f +(are)h(transmitted)g(via)g(the)f(APIC)g(b)o(us.)2132 +3301 y(Lik)o(e)j(interrupts)g(from)g(hardw)o(are)g(the)g(IPIs)f(may)h +(be)h(used)f(to)g(enter)g(the)2049 3384 y(k)o(ernel)i(mode)h +(asynchronus)h(from)e(the)f(destinations)i(processor)g(point)f(of)2049 +3467 y(vie)n(w)-5 b(,)28 b(b)o(ut)e(synchronus)i(from)e(the)h(IPI')l(s) +e(source,)j(thought)f(the)o(y)g(may)f(be)2049 3550 y(used)20 +b(to)e(synchronize)j(operations)f(on)g(tw)o(o)f(processors.)2132 +3641 y(At)e(startup)i(each)f(processor)h(is)f(halted)g(and)h(its)e +(local)h(APIC)f(w)o(aits)h(for)g(a)2049 3724 y(speci\002c)h(startup)g +(IPI.)2049 3995 y Fn(B)100 b(Long)27 b(IPC)2049 4169 +y Fm(At)19 b(last)h(we)f(lik)o(e)h(to)g(present)h(some)f(prethoughts)h +(on)g(implementing)f(cross)2049 4252 y(processor)29 b(IPC)f(for)g(the)g +(long)h(IPC)e(case.)52 b(W)-6 b(e)28 b(ha)o(v)o(e)g(not)h(yet)f +(startet)g(to)2049 4335 y(implement)g(cross)f(processor)i(IPC)d(at)h +(all,)h(so)g(the)f(stuf)n(f)g(in)g(this)g(chapter)2049 +4418 y(will)18 b(be)i(much)g(speculati)n(v)o(e)g(and)g(without)g(we)f +(are)g(not)h(sure)g(if)e(we)i(need)g(to)2049 4501 y(implement)f(an)o(y) +h(of)f(this)f(ideas)i(and)f(what)g(we)g(get)g(of)g(it.)2049 +4747 y Fk(B.1)83 b(T)-5 b(emporarl)o(y)23 b(transf)o(ering)g(the)g +(Sender)2049 4894 y Fm(F)o(or)h(long)h(IPC,)e(the)h(mailbox)o(es)h(of)f +(the)h(destination)g(processors)g(proxies)2049 4977 y(may)18 +b(be)f(a)h(bottleneck,)g(so)g(it)e(might)i(perhaps)g(pay)h(to)e +(transfer)g(the)h(sending)2049 5060 y(thread)e(to)g(the)g(recei)n +(ving')l(s)h(processor)f(for)g(the)g(time)f(of)h(the)g(long)h(IPC.)d +(This)2049 5143 y(of)24 b(course)g(has)g(to)f(be)h(transparent)g(to)g +(all)f(other)h(user)f(le)n(v)o(el)h(threads.)37 b(F)o(or)2049 +5227 y(the)19 b(k)o(ernel)g(point)g(of)f(vie)n(w)-5 b(,)19 +b(this)f(thread)h(simply)f(replaces)h(a)g(k)o(ernel)g(proxy)-5 +b(.)2132 5317 y(This)21 b(idea)h(may)g(e)n(v)o(en)h(be)e(impro)o(v)o +(ed)i(by)f(ha)o(ving)g(a)g(set)f(of)h(proxies)g(and)2049 +5400 y(using)e(this)e(temporary)i(transfer)f(only)g(if)g(all)f(proxies) +i(are)f(b)o(usy)-5 b(.)1931 5700 y(4)p eop +%%Page: 5 5 +5 4 bop 1387 -300 a Fq(\227)20 b(Dr)o(aft)h(of)f(December)g(10,)f(1999) +g(\227)-150 -67 y Fk(B.2)83 b(IPC)24 b(within)e(a)h(Thread)g(T)-7 +b(ransf)o(er)-150 66 y Fm(Especially)20 b(for)g(long)h(cross)f +(processor)h(IPC)e(it)g(is)h(hard)g(to)g(restart)g(the)g(IPC)-150 +150 y(if)g(the)h(destination)g(is)g(transfered)g(to)f(another)i +(processor)l(.)30 b(Se)n(v)o(eral)20 b(copies)-150 233 +y(are)c(still)g(made)h(and)g(ha)o(v)o(e)g(to)f(be)h(redone,)h(though)f +(the)o(y)g(are)g(v)n(alid.)22 b(Imagine)-150 316 y(a)g(long)g(IPC)f(of) +h(full)f(4)h(MB)g(and)h(by)f(accident)h(each)f(time)g(the)f(last)h +(byte)g(is)-150 399 y(to)f(be)h(wrote,)f(the)g(thread)h(is)f +(transfered.)30 b(It)21 b(is)g(then)h(a)f(bad)h(idea)f(to)g(restart) +-150 482 y(with)e(the)g(\002rst)e(byte.)-150 674 y Fc(B.2.1)73 +b(Conceptual)18 b(Pr)o(ob)o(lems)-150 807 y Fm(As)h(long)i(as)e(we)h +(implement)g(the)g(\002rst)f(mechanism,)h(enabling)h(a)f(thread)g(to) +-150 890 y(detect)f(IPC)f(if)g(it)h(happens,)h(there)f(is)f(no)i +(conceptual)g(problem.)k(W)-6 b(e)18 b(de\002ne)-150 +973 y(IPC)29 b(to)g(be)h(cross)g(processor)h(if)e(the)h(last)f(byte)h +(transfered)g(is)g(via)f(cross)-150 1056 y(processor)20 +b(IPC.)-67 1139 y(The)h(second)h(mechanism)g(is)e(quite)h(more)g(dif)n +(\002cult,)g(because)h(we)f(ha)o(v)o(e)-150 1222 y(to)29 +b(in)m(v)o(ok)o(e)h(a)g(f)o(ault)f(during)h(IPC)e(and)i(return)g(suf)n +(\002cient)f(information)h(to)-150 1305 y(restart)22 +b(the)h(communication)h(on)f(that)g(e)o(xactly)g(point.)34 +b(W)-6 b(e)22 b(not)h(yet)g(kno)n(w)-150 1389 y(if)d(we)h(need)h(this)e +(second)j(mechanism)f(at)e(all,)h(so)g(this)f(point)i(is)e(f)o(ar)h +(specu-)-150 1472 y(lati)n(v)o(e.)-150 1664 y Fc(B.2.2)73 +b(Implementation)18 b(of)j(IPC)f(within)g(a)g(Thread)f(T)-6 +b(ransf)o(er)-150 1797 y Fm(As)16 b(long)g(as)g(cross)g(processor)h +(IPC)e(is)g(performed)i(via)f(proxies)h(IPC)d(is)i(redi-)-150 +1880 y(reted)23 b(to)g(another)h(processor')l(s)g(proxie,)h(using)f +(serv)o(er)o(-side)f(propagation.)-150 1963 y(If)15 b(we)h(implement)f +(to)h(temporarly)g(transfer)g(threads)g(to)f(the)h(recei)n(v)o(er')l(s) +g(pro-)-150 2046 y(cessor)m(,)j(we)g(ha)o(v)o(e)g(to)g(transfer)g +(both,)g(the)g(recei)n(v)o(er)g(and)h(the)f(sender)l(.)1931 +5700 y(5)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/l4-x86/smp/lx/kern/DISPATCH.asm b/l4-x86/smp/lx/kern/DISPATCH.asm new file mode 100644 index 0000000..988818b --- /dev/null +++ b/l4-x86/smp/lx/kern/DISPATCH.asm @@ -0,0 +1,1584 @@ +include l4pre.inc + + + Copyright IBM, L4.DISPATCH, 11,03,99, 9089, K + +;********************************************************************* +;****** ****** +;****** Dispatcher ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_dispatcher + public init_schedcb + public start_dispatch + public dispatch + public rtc_timer_int + public insert_into_ready_list + public dispatcher_open_tcb + public dispatcher_close_tcb + public induce_timeouts_at_present_waitees + + + extrn switch_context:near + extrn ipcman_wakeup_tcb:near + extrn get_bottom_state:near + extrn define_idt_gate:near + extrn init_rtc_timer:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include cpucb.inc +.list +include schedcb.inc +.nolist +include lbmac.inc +include syscalls.inc +include kpage.inc +include apic.inc +include pagconst.inc +.list + + +ok_for x86 + + + public apic_timer_int + + extrn attach_small_space:near + extrn get_small_space:near + extrn apic_millis_per_pulse:abs + extrn apic_micros_per_pulse:abs + + + align 4 + + +present_chain_version dd 0 + + + + + + +;---------------------------------------------------------------------------- +; +; init schedcb data area +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + + +init_schedcb: + + ; fill schedule control block area with 0 schedcb needed per processor + mov edi,offset pulse_counter + mov ecx,(scheduler_control_block_size-(offset pulse_counter))/4 + sub eax,eax + cld + rep stosd + + ; clear dispatcher table first tcb for each prio in list + mov edi,offset dispatcher_table + mov ecx,dispatcher_table_size/4 + sub eax,eax ; haengt + cld + rep stosd + + ; set thread of prio 0 to invalid: FFFFFFFF + mov dword ptr ds:[dispatcher_table],-1 + + ; set highest active prio to 0 + mov ds:[highest_active_prio],0 + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init dispatcher & dispatcher tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES linear space +; +; interrupt & memory controller have to be already initialized +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,EBP,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + + +init_dispatcher: + + ;load address of dispatcher tcb + mov ebp,esp + and ebp,-sizeof tcb + + ; set remaining timeslice in dispatcher tcb (baseaddress: ebp) to 1. Ts will never reach 0 + mov [ebp+rem_timeslice],1 ; dispatcher ts will never reach 0 ! + + ; set lower byte system clock in schedcb to 1 + mov ds:[system_clock_low],1 + + lno___prc eax + IFZ eax,1 + ; define Interrupt vector for thread switch + mov bl,thread_switch + mov bh,3 SHL 5 + mov eax,offset switch_sc + call define_idt_gate + + ; define Interrupt vector for thread schedule + mov bl,thread_schedule + mov bh,3 SHL 5 + mov eax,offset thread_schedule_sc + call define_idt_gate + FI + + ret + + + + + +init_dispatcher_tcb: + + mov ebx,offset dispatcher_tcb + + ; set dispatchers priority to 0 + mov [ebx+prio],0 + + ; initialise present list and insert dispatcher + llinit ebx,present + + ; initialise soon and late wakeup queues + linit soon_wakeup + linit late_wakeup + + ret + + + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; dispatcher_open_tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- + + +dispatcher_open_tcb: + + pushad + pushfd + + cli + + ; increase version of present chain + inc [present_chain_version+PM] + + ; if thread is not in present list + test [ebp+list_state],is_present + IFZ + ; insert thread into present list + mov ecx,offset present_root ; Attention: may already linked into + llins ebp,ecx,eax,present ; the present chain by + FI ; concurrent tcb faults + + ; if thread is dispatcher + IFZ ebp, + ; init dispatcher tcb + call init_dispatcher_tcb + ELSE_ + + ; if thread is wake + test [ebp+fine_state],nwake + IFNZ + ; set wakeup high to system clock high + mov cl,ds:[system_clock_high] + mov [ebp+wakeup_high],cl + ; if thread is ready and not in ready list + test [ebp+fine_state],nready + IFZ + test [ebp+list_state],is_ready + CANDZ + ; insert thread into ready list + mov ebx,ebp + call insert_into_ready_list + FI + FI + FI + + popfd + popad + ret + + +;---------------------------------------------------------------------------- +; +; dispatcher close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb eliminated from all dispatcher lists +; +;---------------------------------------------------------------------------- + + +dispatcher_close_tcb: + + pushad + pushfd + + cli + + ; increase version of present list + inc [present_chain_version+PM] ; aborts concurrent parsing of + ; the present chain + ; load current tcb address + mov ebx,esp + and ebx,-sizeof tcb + + ; if thread to close is present + test [ebp+list_state],is_present + IFNZ + ; delete thread from present list + lldel ebp,edx,eax,present + FI + + ; if thread to close is ready + test [ebp+list_state],is_ready + IFNZ + ; delete from ready list + call delete_from_ready_list + FI + + ; delete from late wakeup list + mov edx,offset late_wakeup_link + mov cl,is_late_wakeup + call delete_from_single_linked_list + + ; delete from soon wakeup list + mov edx,offset soon_wakeup_link + mov cl,is_soon_wakeup + call delete_from_single_linked_list + + ; reset bit 31 in wakeup low + btr [ebp+wakeup_low],31 + IFC + ; load current system clock to wakeup high + mov al,ds:[system_clock_high] + mov [ebp+wakeup_high],al + FI + +;;lno___thread edx,ebp +;;test [ebp+fine_state],nbusy +;;IFZ +;; call signal_scheduler_reactivation +;;ELSE_ +;; mov eax,ebp +;; test [eax+fine_state],nwake +;; IFZ +;; mov ecx,[eax+wakeup_low] +;; mov dx,[eax+wakeup_high] +;; call signal_scheduler_wakeup +;; FI +;; test [eax+fine_state],nwait+nclos +;; IFZ +;; mov ecx,[eax+waiting_for] +;; lno___thread ecx,ecx +;; call signal_scheduler_waitfor +;; FI +;;FI + + popfd + popad + ret + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +; NOTE: all lists are processor local, so no synch is needed to perform operations on lists + +;---------------------------------------------------------------------------- +; +; delete from single linked list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb to be deleted, write addr +; EDX list offset +; CL list mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb deleted from list +; +;---------------------------------------------------------------------------- + + + +delete_from_single_linked_list: + + ; if thread is in list (cl) + test [ebp+list_state],cl + IFNZ + push esi + push edi + + ; load dispatcher tcb address + mov edi,offset dispatcher_tcb + klign 16 + ; while any more threads in list (tcb != 0) and (list_tcb != own_tcb) + DO + ; load next tcb from list + mov esi,edi + mov edi,[edi+edx] + ; Exit loop if no more threads in list + test edi,edi + EXITZ + ; repeat until list_tcb == thread to delete + cmp edi,ebp + REPEATNZ + + ; reset bit in list state of the tcb + not cl + and [edi+list_state],cl + ; list.previous = list.next + mov edi,[edi+edx] + mov [esi+edx],edi + OD + + pop edi + pop esi + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; insert thread into ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX thread tcb +; *not* in ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; in ready list +; +;---------------------------------------------------------------------------- + + + +insert_into_ready_list: + + ; load thread priority + movzx eax,[ebx+prio] + + ; if thread is not yet in ready list + test [ebx+list_state],is_ready + IFZ + ; load list root of thread's priority + mov edi,[eax*4+dispatcher_table] + ; if list is empty + test edi,edi + IFZ + ; if thread's priority above current highest active priority + IFA eax,ds:[highest_active_prio] + ; set new highest active priority + mov ds:[highest_active_prio],eax + FI + ; set list root to thread's tcb + mov [eax*4+dispatcher_table],ebx + ; initialise ready list and return + llinit ebx,ready + ret + FI + ; else insert thread into ready list and return + llins ebx,edi,eax,ready + + ret + + FI + + ke 'ihhh' + ret + + +;---------------------------------------------------------------------------- +; +; delete thread from ready list +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP thread tcb +; *in* ready list +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX next prio +; EDI next tcb +; +; EDX scratch +; +; NOT in ready list +; +;---------------------------------------------------------------------------- + + + +delete_from_ready_list: + + ; if thread in ready list + test [ebp+list_state],is_ready + IFNZ + ; get current threads prio + movzx eax,[ebp+prio] + ; if current thread and its successor are not equal + IFNZ ebp,[ebp+ready_llink].succ + ; get head of ready list + mov edi,dword ptr ds:[eax*4+dispatcher_table] + ; if current thread is head of ready list + IFZ edi,ebp + ; set new head = successor of current thread + mov edi,[ebp+ready_llink].succ + mov dword ptr ds:[eax*4+dispatcher_table],edi + FI + ; delete currnet thread and return + lldel ebp,edi,edx,ready + ret + FI + + ; only one thread in ready list for this priority + ; mark thread is not in ready list + and [ebp+list_state],NOT is_ready + ; set head of ready list to nilthread + sub edi,edi + mov dword ptr ds:[eax*4+dispatcher_table],edi + + ; if threads prio was highest active + cmp eax,ds:[highest_active_prio] + IFZ + ; search queue from top to button to find the next highest active thread + DO + mov edi,dword ptr ds:[eax*4+dispatcher_table-4] + dec eax + test edi,edi + REPEATZ + OD + ; reset highest active priority thread and return + mov ds:[highest_active_prio],eax + ret + ELIFB + ; else reload highest active priority + mov eax,ds:[highest_active_prio] + ret + FI + + FI + + ke 'grrr' + ret + + + + + + +;---------------------------------------------------------------------------- +; +; dispatcher thread +; +;---------------------------------------------------------------------------- +; +; REP +; enable interrupts ; +; disable interrupts ; +; IF interrupted threads stack is empty +; THEN get thread from busy que +; ELSE pop thread from interrupted threads stack +; FI ; +; IF thread found +; THEN switch to thread +; FI +; PER . +; +;---------------------------------------------------------------------------- +; Remark: The dispatcher runs on its own thread, but for sake of efficiency +; no complete switch_context (only a temporary stack switch) is used +; for switching from any other thread to the dispatcher. Whenever a +; new thread is picked up by the dispatcher or by a hardware interrupt +; the last threads stackpointer is restored and a complete context +; switch from the last to the new thread is executed. (Note that the +; dispatcher thread can run in any address space.) +; Pros: +; 1. Only one instead of two switches are necessary for dispatch, +; especially at most one switching of address space. +; 2. If there is only one thread (and the dispatcher) busy in the +; moment, address space switch and deallocate/allocate ressources +; (numeric coprocesor) can be omitted. +; +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write address of actual thread ( <> dispatcher ! ) +; +; DS, ES linear space +; +; interrupts disabled +; +;----------------------------------------------------------------------------- + + + + + +start_dispatch: + + ; load dispatcher_tcb address + mov ebx,dispatcher_tcb + jmp short dispatch + + + + + align 16 + + + +dispatch: + + ; save current thread pointer + mov [ebx+thread_esp],esp + + +restart_dispatch: + + ; enable interrupts (note: interrupts won't occur before next instruction) + sti + ; load dispatcher's stack pointer = end of tcb - interrupted stack + mov esp,offset dispatcher_tcb+sizeof pl0_stack-sizeof int_pm_stack + + ; at this point pending interrupts may pass + ; disable interrupts + cli + + ; get highest active prio + mov eax,ds:[highest_active_prio] + + ; restart dispatching if only dispatcher thread is active + test eax,eax + jz restart_dispatch + + ; else get tcb of runnable thread with highest priority + mov ebp,dword ptr ds:[eax*4+dispatcher_table] + + lno___prc edx + ; if current thread equals new thread + CORZ ebp,ebx + ; or on different processor + CORNZ [ebp+proc_id],edx + ; or new thread is not ready + test [ebp+fine_state],nready + CORNZ + ; or remaining timeslice of new thread less than 0 + IFLE [ebp+rem_timeslice],0 + + ; search for next ready thread: + ; get next thread from ready list + mov ebp,[ebp+ready_llink].succ + ; do + DO + ; exit if new thread is ready and on same processor + IFZ [ebp+proc_id],edx + test [ebp+fine_state],nready + EXITZ + FI + + ; delete thread from ready list (returns next prio and tcb) + call delete_from_ready_list + mov ebp,edi + + ; edx is scratch after deletion from ready list so reload it. + lno___prc edx + + ; while prio not 0 (only dispatcher thread has a prio of 0) + test eax,eax + REPEATNZ + + ; restart dispatch loop + jmp restart_dispatch + OD + + ; update hread pointer to new thread + mov dword ptr ds:[eax*4+dispatcher_table],ebp + + ; update remaining timeslice + mov al,[ebp+rem_timeslice] + IFLE al,0 + add al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + FI + FI + + ; load stack pointer of new thread + mov esp,[ebx+thread_esp] + + ; switch to new thread if different from current + cmp ebp,ebx + jnz switch_context + + ret + + + + + +;---------------------------------------------------------------------------- +; +; switch_sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI 0 : dispatch +; +; ESI <>0 : if thread on same processor then donate, thread id (low) +; else dispatch +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REG scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + +switch_sc: + + tpre switch_code,ds + + ; load tcb of current thread + mov ebp,esp + and ebp,-sizeof tcb + + mov ebx,ebp + + ; mark source tcb ready + mark__ready ebx + + ; if blocked or dead sw_block + mov al,[ebp+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + xc nz,sw_block + + ; safe return point + push offset switch_ret + + ; if switch to dispatcher, dispatch + lea___tcb ebp,esi + cmp ebp,dispatcher_tcb + jbe dispatch + + ; if destination tcb != source tcb + IFNZ ebp,ebx + ; cand dest_tcb writeable + test__page_writable ebp + CANDNC + ; cand thread on same processor + lno___prc eax + CANDNZ [ebp+proc_id],eax + ; cand esi = id (dest tcb) + CANDZ esi,[ebp+myself] + ; switch_context if ready + mov al,[ebp+fine_state] + test al,nready + jz switch_context + + ;; and al,NOT nwake + ;; IFZ al,closed_wait + ;; cmp [ebp+waiting_for],0 + ;; jz switch_context + ;; FI + FI + ; dispatch + jmp dispatch + + + + align 4 + + + +XHEAD sw_block + ; if not virtual-86 mode and rpl of code not 3, set fine state not ready + bt [esp+ip_eflags+4],vm_flag + CORC + test byte ptr [esp+ip_cs+4],11b + IFNZ + or [ebp+fine_state],nready + FI + xret + + + + + + + align 16 + + +switch_ret: + + tpost eax,ds,es + + + + + +;####################################### + +;---------------------------------------------------------------------------- +; +; timer interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; INTR return vector +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; +; PROC timer interrupt : +; +; pulse counter DECR thousand div milliseconds per pulse ; +; IF pulse counter <= 0 +; THEN pulse counter INCR pulses per second ; +; timer tick ; +; IF end of timeslice +; THEN mark busy (myself) +; FI ; +; inspect wakeup lists ; +; IF wakeup pending COR end of timeslice +; THEN IF myself in kernel mode +; THEN mark pending dispatch +; ELSE dispatch +; FI +; FI +; FI . +; +; delta t : milliseconds per pulse . +; +; timer tick : +; increment system clocks ; +; cpu clock (me) INCR delta t ; +; remaining timeslice (me) := max (remaining timeslice - delta t, 0) . +; +; increment system clocks : +; system clock offset INCR delta t ; +; propagate new clock to ipcman ; +; IF ready threads = 0 +; THEN idle clock INCR delta t +; ELSE ready clock INCR (ready threads * delta t) ; +; IF kernel active +; THEN kernel clock INCR delta t +; FI +; FI . +; +; inspect wakeup lists : +; IF system clock MOD 1024 = 0 +; THEN parse all present tcbs +; FI ; +; IF system clock MOD 128 = 0 +; THEN parse mid term wakeup list +; FI ; +; IF system clock MOD 4 = 0 +; THEN parse short term wakeup list +; FI . +; +; +; parse short term wakeup list : +; actual := first (short term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset +; THEN push interrupted (myself) ; {happens only once!} +; remaining timeslice (actual) := intr timeslice length ; +; push interrupted (actual) +; delete from short term wakeup list (actual) +; FI +; ELSE delete from short term wakeup list (actual) +; FI +; actual := next (short term wakeup) +; PER . +; +; parse mid term wakeup list : +; actual := first (mid term wakeup) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN delete from mid term wakeup list (actual) +; insert into short term wakeup list (actual) +; FI +; ELSE delete from mid term wakeup list (actual) +; FI +; actual := next (mid term wakeup) +; PER . +; +; parse long term wakeup list : +; actual := first (present) ; +; WHILE actual <> nil REP +; abort wakeup handling if necessary ; +; IF fine state (actual).wait +; THEN IF wakeup (actual) <= system clock offset + 128 +; THEN insert into mid term wakeup list (actual) +; FI +; FI +; actual := next (present) +; PER . +; +;---------------------------------------------------------------------------- + + + + + ; for Pentium and higher, presence of APIC + ; is considered to be default. RTC timer intr + kcod ends ; for non 486 processors therfore not in kcode + ; segment. + ; NOTE: RTC timer will be used if no APIC ! + + + + align 16 + + + +rtc_timer_int: + + ipre fault + + reset_rtc_timer_intr + + + mov esi,offset system_clock_low + + sub [esi+pulse_counter-offset system_clock_low],rtc_thousand_div_millis + ja timer_int_iret + + add [esi+pulse_counter-offset system_clock_low],rtc_pulses_per_second + mov edx,rtc_millis_per_pulse + mov ecx,rtc_micros_per_pulse + + jmp timer_int + + + + + kcode + + + + align 16 + + + + + +apic_timer_int: + + ipre fault + + mov esi,offset system_clock_low + + mov edx,apic_millis_per_pulse + mov ecx,apic_micros_per_pulse + + sub eax,eax + mov ds:[local_apic+apic_eoi],eax + + + + + +timer_int: + + mov ebx,esp + and ebx,-sizeof tcb + + mov edi,offset user_clock+offset logical_info_page + + add dword ptr ds:[esi],edx + xc c,inc_system_clock_high + + add dword ptr ds:[edi],ecx + xc c,inc_user_clock_high + + add [ebx+cpu_clock_low],edx + xc c,inc_cpu_clock_high + + + sub ds:[late_wakeup_count],dl + xc c,late_wakeup,long + + sub esi,esi + + sub ds:[soon_wakeup_count],dl + xc c,soon_wakeup + + + IFNZ ebx,dispatcher_tcb + + sub [ebx+rem_timeslice],dl + + CORLE + test esi,esi + IFNZ + + mark__ready ebx + + mov al,[ebx+coarse_state] + and al,nblocked+ndead + cmp al,nblocked+ndead + IFNZ + or [ebx+fine_state],nready + FI + + push offset timer_int_ret + + test esi,esi + jz dispatch + + mov ebp,esi + jmp switch_context + + + timer_int_ret: + FI + FI + + + +timer_int_iret: + + ipost + + + + +XHEAD inc_system_clock_high + + inc [esi+system_clock_high-offset system_clock_low] + xret + + +XHEAD inc_user_clock_high + + inc dword ptr ds:[edi+4] + xret + + +XHEAD inc_cpu_clock_high + + inc [ebx+cpu_clock_high] + xret + + + + + +XHEAD soon_wakeup + + mov ds:[soon_wakeup_count],soon_wakeup_interval + + movl__root ebp,soon_wakeup + mov eax,ds:[system_clock_low] + DO + movl__next ebp,ecx,soon_wakeup + xret z + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + IFNZ ebx,dispatcher_tcb + mov al,[ebx+prio] + CANDA [ebp+prio],al + + mov esi,ebp + mark__interrupted ebx + FI + call ipcman_wakeup_tcb + ;mark__ready ebp + FI + ldel ebp,ecx,soon_wakeup + REPEAT + OD + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +XHEAD late_wakeup + + mov ds:[late_wakeup_count],late_wakeup_interval + + sub ds:[late_late_wakeup_count],1 + xc c,late_late_wakeup,long + + mov eax,ds:[system_clock_low] + add___eax late_wakeup_interval + movl__root ebp,late_wakeup + clign 16 + DO + movl__next ebp,ecx,late_wakeup + xret z,long + + test [ebp+fine_state],nwake + IFZ + cmp [ebp+wakeup_low],eax + REPEATG + + test [ebp+list_state],is_soon_wakeup + IFZ + lins ebp,esi,soon_wakeup + FI + FI + ldel ebp,ecx,late_wakeup + REPEAT + OD + + + + + + +XHEAD late_late_wakeup + + mov ds:[late_late_wakeup_count],late_late_wakeup_interval/late_wakeup_interval + mov eax,ds:[system_clock_low] + add eax,late_late_wakeup_interval + push edx + sub dl,dl + mov esi,ds:[present_chain_version+PM] + + mov ebp,offset dispatcher_tcb + clign 16 + DO + + sub dl,4 + xc c,permit_interrupts + + mov ebp,[ebp+present_llink].succ + cmp ebp,offset dispatcher_tcb + EXITZ + + test [ebp+fine_state],nwake + REPEATNZ + + test [ebp+list_state],is_late_wakeup + REPEATNZ + + cmp [ebp+wakeup_low],eax + REPEATG + + lins ebp,esi,late_wakeup + REPEAT + +late_late_wakeup_od: + + OD + pop edx + + xret ,long + + + + +XHEAD permit_interrupts + + sti + nop + nop + cli + cmp esi,ds:[present_chain_version+PM] + xret z + + mov ds:[late_late_wakeup_count],10 + jmp late_late_wakeup_od + + + + + +;---------------------------------------------------------------------------- +; +; thread schedule sc +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX param word (bits 16..19 proc no) +; EBX ext preempter / 0 +; ESI dest thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX old param word (bits 16..19 proc no) +; ECX time low +; EDX time high +; EBX old preempter +; ESI partner +; +;---------------------------------------------------------------------------- + + + + +thread_schedule_sc: + + tpre trap2,ds,es + + ; get scheduler's tcb = current thread + mov edi,esp + and edi,-sizeof tcb + + mov ch,[edi+max_controlled_prio] + +thread_schedule_proxy_code: ; Precondition: tpre, thread schedule sc, ch 0 mcp proc_id already set + + ; load address of tcb in esi + mov edx,esi + lea___tcb esi + + ; if target thread on same processor + lno___prc edi + ;; edi + ;; eax: 16-19 proc_id + + ;; (eax.procid = esi.procid || eax.procid = 0) => no migration + ;; schedule on eax.procid || (if eax.procid = 0: esi.procid) + + ; test for migration + push eax + shr eax,16 + and eax,0Fh + IFNZ al,0 + CANDNZ [esi+proc_id],eax + ke 'migrate thread (esi) to processor (al)' + ;; the remaining registers are in use + FI + pop eax + + ; schedule if on destination CPU + IFZ [esi+proc_id],edi,long + ; schedule thread normally + + ; if thread exists and tid is valid + cmp [esi+myself],edx + IFZ ,,long + + ; save current values to old param word = edx, old ext preemter = e + push eax + push ebx + + ; param Word = tsAsSSPr: timeslice(8) A(4) ThreadState(4) SmallSpaceNr(8) Prio(8) + mov dl,[esi+timeslice] + shl edx,4 + add edx,10 + shl edx,8 + + xchg ebp,esi + call get_bottom_state ; gets fine state in eax, com partner in ebx + xchg ebp,esi + + ; store current thread_state in dl + mov dl,0F0h + IFZ al,running + mov dl,00h + FI + IFZ al,locked_running + mov dl,40h + FI + IFZ al,locked_waiting + mov dl,80h + FI + test al,nwait + IFZ al,closed_wait + mov dl,0C0h + FI + IFZ al,polling + mov dl,0D0h + FI + ; if locked or running and not running + IFB_ dl,0C0h + test [esi+fine_state],nready + CANDNZ + ; ongoing IPC with: pager, int preempter, ext preempter + mov ebx,[esi+waiting_for] + IFZ ebx,[esi+pager] + add dl,10h + ELIFZ ebx,[esi+int_preempter] + add dl,20h + ELIFZ ebx,[esi+ext_preempter] + add dl,30h + FI + FI + + shl edx,12 + + ; get small space number + call get_small_space + mov dh,al + + ; get priority + mov dl,[esi+prio] + + pop ebx + pop eax + + ; cand prio <= max controlled prio + CANDBE dl,ch,long + + + ; set external preemter + IFNZ ebx,-1 + mov [esi+ext_preempter],ebx + FI + + ; if param word valid + IFNZ eax,-1 + ; cand new prio <= max controlled prio + CANDBE al,ch + + ; parse new param word and set values + push eax + + ; prio >= 1 (Prio 0 reservered for dispatcher thread) + cmp al,1 ; al := max (al,1) + adc al,0 ; + + ; if current prio != new prio + IFNZ dl,al + ; if in ready list + test [esi+list_state],is_ready + IFNZ + ; delete from ready list + pushad + mov ebp,esi + push eax + call delete_from_ready_list + pop eax + ; set new prio + mov [esi+prio],al + mov ebx,esi + ; reinsert to ready list + call insert_into_ready_list + popad + ELSE_ + ; else set new prio + mov [esi+prio],al + FI + FI + + ; set new timeslice + mov ecx,eax + shr ecx,20 + and cl,0Fh + add cl,2 + shr eax,cl + shr eax,cl + IFA eax,127 + mov al,127 + FI + mov [esi+timeslice],al + + pop eax + + ; attach new small space + IFB_ ah,max_small_spaces + call attach_small_space + FI + + FI + + mov ebx,edx + + mov edi,1000 + + sub ecx,ecx + test [esi+fine_state],nwake + IFZ + dec ecx + mov eax,[esi+wakeup_low] + sub eax,ds:[system_clock_low] + mul edi + mov al,dl + test eax,0FF0000FFh + IFZ + rol eax,16 + add cl,80h + FI + test al,al + IFZ + rol eax,8 + add cl,40h + FI + test al,0F0h + IFZ + shl eax,4 + add cl,20h + FI + test al,0C0h + IFZ + shl eax,2 + add cl,10h + FI + mov ch,cl + shl ecx,16 + FI + + ; read current time values + mov eax,[esi+cpu_clock_low] + mul edi + add edx,ecx + movzx ecx,[esi+cpu_clock_high] + imul ecx,edi + add edx,ecx + mov ecx,eax + + mov eax,ebx + + ; get external preempter + mov ebx,[esi+ext_preempter] + + ; get communication partner + mov esi,[esi+waiting_for] + + ELSE_ + ; else return with invalid param word + sub eax,eax + dec eax + + FI + tpost ,ds,es + ELSE_ + ke 'thread schedule sc mp case' + + ; setup proxy thread command: + ; eax: param word, ebx: ext preempter, esi: dest thread, edi: scheduler thread, ch: mcp + ; send cp ipc to proxy thread + ; block scheduler in wait for cp-ipc from proxy thread + ; eax: old param word, ebx old ext preempter, ecx,edx: time low / high, esi: comm partner + + FI + tpost ,ds,es + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; induce timeouts at present waitees +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread id (low) +; EDI thread id (high) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; all present threads waiting for got receive timeout +; +;---------------------------------------------------------------------------- + + align 16 + + + +XHEAD permit_interrupts_while_inducing_timeouts + + mov eax,[present_chain_version+PM] + sti + mov cl,16 + mov cl,cl ; due to 486 bug (1 cycle enabled too short) + cli + cmp [present_chain_version+PM],eax + xret z + + pop eax ; restart induce_timeouts_at_present_waitees + popfd ; if someone changed the present chain by + popad ; interrupt + + + + clign 4 + + + + +induce_timeouts_at_present_waitees: + + pushad + pushfd + + cli + mov cl,16 + + mov ebx,offset dispatcher_tcb + + clign 16 + DO + mov ebx,[ebx+present_llink].succ + cmp ebx,offset dispatcher_tcb + EXITZ + + dec cl + xc z,permit_interrupts_while_inducing_timeouts + + cmp [ebx+waiting_for],esi + REPEATNZ + + test [ebx+coarse_state],ndead + REPEATZ + + mov al,[ebx+fine_state] + test al,npoll + IFNZ + and al,nwait+nlock+nclos + cmp al,nlock + REPEATNZ + FI + + mov ebp,ebx + call ipcman_wakeup_tcb + REPEAT + OD + + + popfd + popad + ret + + + + + + + + + + + code ends + end + + + \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/EMUCTR.asm b/l4-x86/smp/lx/kern/EMUCTR.asm new file mode 100644 index 0000000..a402c33 --- /dev/null +++ b/l4-x86/smp/lx/kern/EMUCTR.asm @@ -0,0 +1,519 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.EMUCTR, 24,08,99, 40030 + + +;********************************************************************* +;****** ****** +;****** Emulation Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 13.09.97 ****** +;****** ****** +;********************************************************************* + + +; 24.08.99 jl : rdtsc, rd/wrmsr emulated on 486 or other processor without such hw features + +; 13.09.97 jl : special real-mode INT n handling for Yoonho and Seva, unsafe!! +; 31.10.94 jl : rdmsr, wrmsr emulated on pentium for pl3 threads in kernel task + + + public init_emuctr + + + extrn define_idt_gate:near + extrn exception:near + + public signal_virtual_interrupt + + extrn emu_load_dr:near + extrn emu_store_dr:near + extrn emu_lidt_eax:near + extrn real_mode_int_n:near + + ;extrn sti_v86emu:near + ;extrn cli_v86emu:near + ;extrn lock_v86emu:near + ;extrn pushf_v86emu:near + ;extrn pushfd_v86emu:near + ;extrn popf_v86emu:near + ;extrn popfd_v86emu:near + ;extrn int_v86emu:near + ;extrn iret_v86emu:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for x86 + + +cli_ equ 0FAh +sti_ equ 0FBh +lock_ equ 0F0h +pushf_ equ 09Ch +popf_ equ 09Dh +int_ equ 0CDh +iret_ equ 0CFh + +osp_ equ 066h +asp_ equ 067h +rep_ equ 0F3h +repne_ equ 0F2h +es_ equ 026h +ss_ equ 036h +cs_ equ 02Eh +ds_ equ 03Eh + +nop_ equ 090h + +ldr_ equ 230Fh +sdr_ equ 210Fh +scr_ equ 200Fh + +rdtsc_ equ 310Fh +wrmsr_ equ 300Fh +rdmsr_ equ 320Fh + + + + align 16 + + +v86_emu_tab dd gp_exception ; 0 + dd gp_exception ; 1 + dd gp_exception ; 2 + dd gp_exception ; 3 + dd gp_exception ; 4 + dd gp_exception ; 5 + dd gp_exception ; 6 + dd gp_exception ; 7 + dd gp_exception ; 8 + +;v86_emu_tab dd gp_exception ; 0 +; dd int_v86emu ; 1 +; dd iret_v86emu ; 2 +; dd pushf_v86emu ; 3 +; dd popf_v86emu ; 4 +; dd cli_v86emu ; 5 +; dd sti_v86emu ; 6 +; dd lock_v86emu ; 7 +; dd osp_v86operation ; 8 + + + +nil equ 0 +int_op equ 1 +iret_op equ 2 +pushf_op equ 3 +popf_op equ 4 +cli_op equ 5 +sti_op equ 6 +lock_op equ 7 +os_pre equ 8 + + + + +opcode_type db 16 dup (0) ; 80 + db 0,0,0,0,0,0,0,0, 0,0,0,0,pushf_op,popf_op,0,0 ; 90 + db 16 dup (0) ; A0 + db 16 dup (0) ; B0 + db 0,0,0,0,0,0,0,0, 0,0,0,0,0,int_op,0,iret_op ; C0 + db 16 dup (0) ; D0 + db 16 dup (0) ; E0 + db lock_op,0,0,0,0,0,0,0 ; F0 + db 0,0,cli_op,sti_op,0,0,0,0 ;*F8 + + + + align 8 + +rdtsc_486 dd 0,0 + + + + +;---------------------------------------------------------------------------- +; +; init emu ctr +; +;---------------------------------------------------------------------------- + + + + assume ds:codseg,ss:codseg + + + icode + + +init_emuctr: + ; IF bootstrap (IDT shared) + lno___prc eax + IFZ eax,1 + ; load general protection handler to IDT + mov bl,general_protection + mov bh,0 SHL 5 + mov eax,offset general_protection_handler ;seems to be reentrant + call define_idt_gate + + ; load invalid opcode handler to IDT + mov bl,invalid_opcode + mov bh,0 SHL 5 + mov eax,offset invalid_opcode_handler ;seems to be reentrant + call define_idt_gate + FI + + ;enable enhanced v86 features if present + bt ds:[cpu_feature_flags],enhanced_v86_bit + IFC + db 0Fh,20h,0E0h + ; mov eax,cr4 + bts eax,0 ; enable enhanced v86 features + ; mov cr4,eax + db 0Fh,22h,0E0h + FI + + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; signal virtual interrupt +; +;---------------------------------------------------------------------------- + + + align 16 + + + +signal_virtual_interrupt: + + ; load current tcb address + push ebp + mov ebp,esp + and ebp,-sizeof tcb + + ; load ip bottom address + lea___ip_bottom ebp,ebp + ; set virtual interrupt flag + bts [ebp+iv_eflags],vip_flag + + pop ebp + ret + + + + +;---------------------------------------------------------------------------- +; +; general protection handler +; +;---------------------------------------------------------------------------- + + + align 16 + + +XHEAD virtual_interrupt_pending + + ; return if virtual interrupt flag is not set + test eax,(1 SHL vif_flag) + xret z + + ; reset virtual interrupt pending flag + btr [esp+iv_eflags],vip_flag + ; set nmi and jump to exception + mov al,nmi + jmp exception + + + +;################################################################# + + + align 16 + + + + +general_protection_handler: + + + ipre ec_present,no_ds_load + + test byte ptr [esp+ip_cs],11b + jz short gp_exception + + + + mov eax,[esp+ip_error_code] + and eax,0000FFFFh + IFZ + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + ; note: V86 has always large + test eax,(1 SHL vip_flag) ; space! + xc nz,virtual_interrupt_pending ; + + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + + IFNZ al,0Fh + movzx ebp,al + movzx ebp,ss:[ebp+opcode_type-80h+PM] + jmp ss:[(ebp*4)+v86_emu_tab+PM] + FI + ELSE_ + + mov esi,[esp+ip_eip] + mov eax,ds:[esi] + + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + ELSE_ + + xor eax,10b + test eax,11b + IFZ + shr eax,3 + CANDAE eax,10h + cmp eax,1Fh + jbe int_1X_operation + FI + + FI + + + +gp_exception: + + mov al,general_protection + jmp exception + + + + + + align 16 + + +;;osp_v86operation: +;; +;;cmp ah,pushf_ +;;jz pushfd_v86emu +;;cmp ah,popf_ +;;jz popfd_v86emu + + clign 4 + + + + + +;---------------------------------------------------------------------------- +; +; invalid opcode handler +; +;---------------------------------------------------------------------------- + + + +invalid_opcode_handler: + + + ipre fault,no_ds_load + + push linear_space + pop ds + + mov eax,ss:[esp+ip_eflags] + test eax,(1 SHL vm_flag) + IFNZ + movzx eax,[esp+iv_ip] + movzx esi,[esp+iv_cs] + add esi,esi + mov eax,ds:[eax+(esi*8)] + ELSE_ + mov esi,[esp+ip_eip] + test byte ptr [esp+ip_cs],11b + IFZ + mov eax,cs:[esi] + ELSE_ + mov eax,ds:[esi] + FI + FI + IFZ al,0Fh + call prefix_0F_operation + FI + + +ud_exception: + + mov al,invalid_opcode + jmp exception + + + + + + + +;---------------------------------------------------------------------------- +; +; prefix 0F operations +; +;---------------------------------------------------------------------------- + + + + +prefix_0F_operation: + + + lea edi,[esp+ip_edi+4] + shr eax,8 + + cmp al,HIGH ldr_ + jz emu_load_dr + + cmp al,HIGH sdr_ + jz emu_store_dr + + cmp ax,1801h + jz emu_lidt_eax + + cmp al,HIGH rdtsc_ + jz emu_rdtsc + + cmp al,HIGH rdmsr_ + jz emu_rdmsr + + cmp al,HIGH wrmsr_ + jz emu_wrmsr + + ret + + + + + + + + clign 16 + + +gp_ud_emu_2_return: + + add [esp+ip_eip+4],2 + + pop eax + ipost + + + + + +int_1X_operation: + + push linear_kernel_space + pop ds + + mov edi,esp + call real_mode_int_n + + push eax + jmp gp_ud_emu_2_return + + + + + + +emu_rdmsr: + + sub eax,eax + sub edx,edx + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + mov ecx,ss:[edi+ip_ecx-ip_edi] + rdmsr + FI + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + +emu_wrmsr: + + mov eax,ss:[edi+ip_eax-ip_edi] + mov ecx,ss:[edi+ip_ecx-ip_edi] + mov edx,ss:[edi+ip_edx-ip_edi] + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + IFC + wrmsr + FI + + jmp gp_ud_emu_2_return + + + + +emu_rdtsc: + + mov eax,ss:[rdtsc_486+PM] + mov edx,ss:[rdtsc_486+4+PM] + add eax,1 + adc edx,0 + mov ss:[rdtsc_486+PM],eax + mov ss:[rdtsc_486+4+PM],edx + + mov ss:[edi+ip_eax-ip_edi],eax + mov ss:[edi+ip_edx-ip_edi],edx + + jmp gp_ud_emu_2_return + + + + + + code ends + end + + + + + + + diff --git a/l4-x86/smp/lx/kern/INTCTR.asm b/l4-x86/smp/lx/kern/INTCTR.asm new file mode 100644 index 0000000..f58956d --- /dev/null +++ b/l4-x86/smp/lx/kern/INTCTR.asm @@ -0,0 +1,552 @@ +include l4pre.inc + + + Copyright IBM, L4.INTCTR, 07,01,00, 57 + + +;********************************************************************* +;****** ****** +;****** Interrupt Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 7.1.00 ****** +;****** ****** +;********************************************************************* + + + + public init_intctr + public define_idt_gate + public emu_lidt_eax + public exception + + + ;extrn intr_from_v86:near + extrn shutdown_thread:near + extrn machine_check_exception:near + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include pagmac.inc +include cpucb.inc +.list +include intrifc.inc +include syscalls.inc +.nolist +include kpage.inc +.list + + + extrn make_own_address_space_large:near + + +ok_for x86 + + + icode + + +idtvec dw sizeof idt-1 + dd offset idt + + + align 4 + + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +ar_byte record dpresent:1,dpl:2,dtype:4,daccessed:1 + +d_bit equ 22 + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ 0 shl 5 +dpl1 equ 1 shl 5 +dpl2 equ 2 shl 5 +dpl3 equ 3 shl 5 + + + +;----------------------------------------------------------------------- +; +; init interrupt controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; IDT initialized +; IDTR initialized +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + +init_intctr: + ; IF bootstrap + lno___prc eax + IFZ eax,1 + ; clear idt area with 0 + sub eax,eax + mov edi,offset idt + mov ecx,sizeof idt/4 + cld + rep stosd + + ; copy initial idt to idt (valid as long as idt is shared) + mov bl,0 + mov esi,offset initial_idt+PM + DO + mov eax,[esi] + mov bh,[esi+4] + call define_idt_gate + inc bl + add esi,5 + cmp esi,offset end_of_initial_idt+PM + REPEATB + OD + FI + + ; load idtr + lidt fword ptr ds:[idtvec+PM] + + ret + + + + + align 4 + + +initial_idt dd offset divide_error_handler + db dpl3 + dd offset initial_debug_exception_handler + db dpl0 + dd 0 + db dpl0 + dd offset breakpoint_handler + db dpl3 + dd offset overflow_handler + db dpl3 + dd offset bound_check_handler + db dpl3 + dd offset invalid_opcode_handler + db dpl0 + dd 0 + db dpl0 + dd offset double_fault_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset seg_not_present_handler + db dpl0 + dd offset stack_exception_handler + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd 0 + db dpl0 + dd offset co_error_handler + db dpl0 + dd offset alignment_check_handler + db dpl0 + dd offset machine_check_exception + db dpl0 + +end_of_initial_idt equ $ + + + icod ends + + + +;-------------------------------------------------------------------------- +; +; define idt gate +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; BH dpl +; +; DS linear_space +; +;--------------------------------------------------------------------------- + + + assume ds:codseg + + +define_idt_gate: + + push ebx + push edi + + ; idt entry = offset idt + 8 * interrupt nr + movzx edi,bl + shl edi,3 + add edi,offset idt + + ; define idt entry ebx:eax + ; idt gate descriptor: +4 ofs:31-16 p:15 dpl:14-13 descr type:12-8= 0D110 0/res:7-0 + ; +0 sgm descr: 31-16 ofs:15-0 + shld ebx,eax,16 + rol ebx,16 + rol eax,16 + mov ax,phys_mem_exec + rol eax,16 + mov bl,0 + add bh,80h+intrgate + + ; store descriptor entry in idt + mov [edi],eax + mov [edi+4],ebx + + pop edi + pop ebx + + ret + + + +;-------------------------------------------------------------------------- +; +; multi level interrupt switches +; +;-------------------------------------------------------------------------- + + assume ds:nothing + + + icode + + +initial_debug_exception_handler: + + + ipre debug_ec + + ; set debug_exception code and jump to exception + mov al,debug_exception + jmp exception + + + icod ends + + + + + align 16 + + + + +multi_handler macro intr,icode + + align 4 + +intr&_handler: + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + push icode + ENDIF + pushad + mov al,intr + jmp short multi_exception + endm + + + + + multi_handler divide_error,fault + multi_handler breakpoint,trap1 + multi_handler overflow,fault + multi_handler bound_check,fault + multi_handler invalid_opcode,fault + multi_handler double_fault,ec_present + multi_handler stack_exception,ec_present + multi_handler seg_not_present,ec_present + multi_handler co_error,fault + multi_handler alignment_check,ec_present + + + + +;---------------------------------------------------------------------------- +; +; std exception handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre, (multi exception: but seg regs not yet pushed!) +; +; AL intr number +; +;---------------------------------------------------------------------------- + + + + + + + align 16 + + + + + +multi_exception: + + push ds + +; Standard exception handler +exception: + + ; load current tcb address + mov ebp,esp + and ebp,-sizeof tcb + + ; exception code in al (mask rest of eax) + and eax,000000FFh + + ; if (segment not present) or (stack exception) or (general protection) + CORZ al,seg_not_present ; ensures that seg regs are valid + CORZ al,stack_exception ; + IFZ al,general_protection ; recall: linear_space is only valid + + movzx ebx,word ptr ss:[esp+ip_error_code] + + IFB_ ebx,sizeof gdt + ; data segment + mov ecx,linear_space ; + CORNZ [esp+ip_ds],ecx ; + mov edx,es ; + IFNZ edx,ecx ; + test byte ptr ss:[esp+ip_cs],11b + IFNZ ; + mov [esp+ip_ds],ecx; do not update DS + FI ; if within kernel ! + mov es,ecx ; (DS might be kernel seg) + ipost ; + FI ; + + test ebx,ebx + IFZ + test byte ptr [esp+ip_eflags+2],1 SHL (vm_flag-16) + CANDZ + + lno___task edi,esp + push eax + shl edi,max_cpu + lno___prc eax + add edi,eax + pop eax + test byte ptr ss:[edi*8+task_proot+3-8].switch_ptr,80h + CANDNZ + + push linear_kernel_space + pop ds + + call make_own_address_space_large + + ipost + FI + FI + FI + ; else + + cmp esp,PM + jae kd_exception + + test byte ptr [esp+ip_cs],11b + jz kd_exception + + mov ebp,[ebp+thread_idt_base] + test ebp,ebp + jz short perhaps_kd_exception + + + ; note: define_pl3_idt ensures that + lea edi,[eax*8+ebp] ; idt_base is always valid + ; (inside virtual_space) + mov ebx,[edi+4] + mov bx,[edi] + + test ebx,ebx + jz short perhaps_kd_exception + cmp ebx,virtual_space_size + ja short perhaps_kd_exception + + + + mov edx,[esp+ip_esp] + + bt [esp+ip_eflags],vm_flag + IFC + ke 'v86_exc' + FI + ;;;;; jc intr_from_v86 + + sub edx,3*4 + jc short perhaps_kd_exception + + mov edi,edx + + IFAE al,8 + CANDBE al,17 + CANDNZ al,16 + sub edi,4 + jc short perhaps_kd_exception + movzx eax,word ptr [esp+ip_error_code] + mov [edi],eax + FI + + mov eax,[esp+ip_eip] + mov [edx+iret_eip],eax + mov cx,[esp+ip_cs] + mov [edx+iret_cs],cx + mov eax,[esp+ip_eflags] + mov [edx+iret_eflags],eax + + btr eax,t_flag + mov [esp+ip_eflags],eax + mov [esp+ip_eip],ebx + mov [esp+ip_cs],cx + mov [esp+ip_esp],edi + + ipost + + + + + + + +perhaps_kd_exception: + + + movzx ebx,ss:[logical_info_page].kdebug_max_task + test ebx,ebx + IFNZ + lno___task ecx,esp + cmp ecx,ebx + ja shutdown_thread + FI + + + +kd_exception: + + jmp dword ptr ss:[logical_info_page].kdebug_exception + + + + + + + +;---------------------------------------------------------------------------- +; +; emulate LIDT [EAX] +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; EBP scratch +; +;---------------------------------------------------------------------------- + + + + ; buggy, not jet updated from current version. faulty on 486: racing condition + + +emu_lidt_eax: + + mov ebp,esp + and ebp,-sizeof tcb + + mov eax,ss:[edi+7*4] + + CORA eax, + mov eax,[eax+2] + IFA eax, + sub eax,eax + FI + + mov [ebp+thread_idt_base],eax + + mov al,3 + ret + + + + + + + + + + + code ends + end diff --git a/l4-x86/smp/lx/kern/KDIOPC.asm b/l4-x86/smp/lx/kern/KDIOPC.asm new file mode 100644 index 0000000..328080e --- /dev/null +++ b/l4-x86/smp/lx/kern/KDIOPC.asm @@ -0,0 +1,1369 @@ +include l4pre.inc + + dcode + + Copyright IBM, L4.KDIO.PC, 17,02,99, 26 + + +;********************************************************************* +;****** ****** +;****** LN KDIO.PC ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 17.02.99 ****** +;****** ****** +;********************************************************************* + + + public init_kdio + public set_remote_info_mode + public open_debug_keyboard + public close_debug_keyboard + public open_debug_screen + public kd_outchar + public kd_inchar + public kd_incharety + public kd_kout + public local_outbar + public old_pic1_imr + + extrn reset:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list + + +ok_for x86 + + +cga_crtc_base equ 3D4h +hercules_crtc_base equ 3B4h + + +cga_base equ 0B8000h +hercules_base equ 0B0000h + +lines equ 25 +columns equ 80 + + +video_control_data_area struc + + db 449h dup (0) + display_mode_set db 0 + db 19h dup (0) + crtc_base dw 0 + +video_control_data_area ends + + +cursor_addr_high equ 0Eh +cursor_addr_low equ 0Fh + +screen_start_high equ 0Ch +screen_start_low equ 0Dh + + + + + +deb_screen_base dd cga_base +deb_crtc_base dw 3DAh + + + + +;---------------------------------------------------------------------------- +; +; init kdio +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL 'a' automatic +; AL 'c' CGA screen +; AL 'm' monochrom screen +; AL 'h' hercules screen +; +;---------------------------------------------------------------------------- + + + +assume ds:codseg + + + +init_kdio: + + push ds + + IFAE esp, + mov edx,phys_mem + mov ds,edx + FI + + mov dx,cga_crtc_base + IFZ al,'c' + mov eax,cga_base + + ELIFZ al,'m' + mov eax,hercules_base + ELIFZ al,'h' + mov dx,hercules_crtc_base + mov eax,hercules_base + ELSE_ + mov eax,hercules_base + mov dx,ds:[crtc_base] + IFNZ ds:[display_mode_set],7 + mov eax,cga_base + FI + FI + + mov [deb_screen_base],eax + mov [deb_crtc_base],dx + + push eax + mov al,00001001b ; alpha, 80*25 + add edx,4h ; + out dx,al + pop eax + + pop ds + ret + + + + + + + + + + +kd_incharety: + + DO + call buffer_incharety + EXITNC + call local_soft_incharety + EXITNC + call remote_incharety + OD + ret + + + + +;---------------------------------------------------------------------------- +; +; kd inchar +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX char +; +;---------------------------------------------------------------------------- + + +kd_inchar: + + push ebx + sub ebx,ebx + DO + call buffer_incharety + EXITNC + call local_incharety + EXITNC + call remote_incharety + REPEATC + + cmp al,'~' + REPEATZ + + IFZ al,27 + mov bl,al + REPEAT + FI + IFZ al,'[' + CANDZ bl,27 + mov bl,al + REPEAT + FI + IFZ bl,'[' + IFZ al,'A' + mov al,3 + FI + IFZ al,'B' + mov al,10 + FI + IFZ al,'C' + mov al,2 + FI + IFZ al,'D' + mov al,8 + FI + IFZ al,0 + mov al,1 + FI + IFZ al,'5' + mov al,11h + FI + IFZ al,'6' + mov al,10h + FI + FI + OD + pop ebx + ret + + + + + + +;********************************************************************* +;****** ****** +;****** local info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + + +kout_ptr dd 0 + + +cursor_x db 0 +cursor_y db 0 + +de_facto_xy dw 0 + +charmode db 0 + + + +shift_status db 0 + +old_pic1_imr db 0 + + +local_console_enabled db true + +break_is_pending db false + + + + align 4 + +debug_keyboard_level dd 0 + + +shift_left equ 2Ah +shift_right equ 36h + +break_mask equ 80h + +esc_ equ 01h +num_lock equ 45h + +kb_data equ 60h +kb_status equ 64h +kb_cmd equ 64h + +disable_keyboard equ 0ADh +enable_keyboard equ 0AEh + +pic1_icw1 equ 20h +pic1_imr equ 21h + +seoi_kb equ 61h + + + + align 4 + +chartab db 0, 0 ; 00 + db 1Bh,1Bh ; 01 esc + db '1','!' ; 02 1 + db '2',22h ; 03 2 + db '3','#' ; 04 3 + db '4','$' ; 05 4 + db '5','%' ; 06 5 + db '6','^' ; 07 6 + db '7','/' ; 08 7 + db '8','*' ; 09 8 ; US + db '9',')' ; 0A 9 + db '0','=' ; 0B 0 + db '-','?' ; 0C á ; US + db 27h,'+' ; 0D ' ; US + db 08h,08h ; 0E backspace + db 09h,09h ; 0F tab + db 'q','Q' ; 10 Q + db 'w','W' ; 11 W + db 'e','E' ; 12 E + db 'r','R' ; 13 R + db 't','T' ; 14 T + db 'y','Y' ; 15 Y + db 'u','U' ; 16 U + db 'i','I' ; 17 I + db 'o','O' ; 18 O + db 'p','P' ; 19 P + db 219,216 ; 1A š + db '+','*' ; 1B + + db 0Dh,0Dh ; 1C enter + db 0, 0 ; 1D (left) ctrl + db 'a','A' ; 1E A + db 's','S' ; 1F S + db 'd','D' ; 20 D + db 'f','F' ; 21 F + db 'g','G' ; 22 G + db 'h','H' ; 23 H + db 'j','J' ; 24 J + db 'k','K' ; 25 K + db 'l','L' ; 26 L + db 218,':' ; 27 ™ / : ; US + db 217,214 ; 28 Ž + db 35, 39 ; 29 Þ + db 0, 0 ; 2A (left) shift + db 3Ch,3Eh ; 2B < + db 'z','Z' ; 2C Z + db 'x','X' ; 2D X + db 'c','C' ; 2E C + db 'v','V' ; 2F V + db 'b','B' ; 30 B + db 'n','N' ; 31 N + db 'm','M' ; 32 M + db ',',';' ; 33 , + db '.',':' ; 34 . + db '-','_' ; 35 - + db 0, 0 ; 36 (right) shift + db '+','+' ; 37 + + db 0, 0 ; 38 (left) alt + db 20h,20h ; 39 space + db 0, 0 ; 3A caps lock + db 81h,91h ; 3B f1 + db 82h,92h ; 3C f2 + db 83h,93h ; 3D f3 + db 84h,94h ; 3E f4 + db 85h,95h ; 3F f5 + db 86h,96h ; 40 f6 + db 87h,97h ; 41 f7 + db 88h,98h ; 42 f8 + db 89h,99h ; 43 f9 + db 8Ah,9Ah ; 44 f10 + db 0, 0 ; 45 num lock + db '*','*' ; 46 * + db 01h,01h ; 47 7 home + db 03h,03h ; 48 8 up arrow + db 10h,10h ; 49 9 page up + db 0, 0 ; 4A + db 08h,08h ; 4B 4 left arrow + db 01h,01h ; 4C 5 + db 02h,02h ; 4D 6 right arrow + db 0Dh,0Dh ; 4E enter + db 10h,10h ; 4F 1 end + db 0Ah,0Ah ; 50 2 down arrow + db 11h,11h ; 51 3 page down + db 0Bh,0Bh ; 52 0 ins + db 0Ch,0Ch ; 53 . del + db 0, 0 ; 54 sys req + db 0, 0 ; 55 + db '<','>' ; 56 < + db 8Bh,9Bh ; 57 f11 + db 7, 7 ; 58 f12 + db 0, 0 ; 59 + db 0, 0 ; 5A + db 0, 0 ; 5B + db 0, 0 ; 5C + db 0, 0 ; 5D + db 0, 0 ; 5E + db 0, 0 ; 5F + db 0, 0 ; 60 + db 0, 0 ; 61 + db 0, 0 ; 62 + db 0, 0 ; 63 + db 0, 0 ; 64 + db 0, 0 ; 65 + db 0, 0 ; 66 + db 0, 0 ; 67 + db 0, 0 ; 68 + db 0, 0 ; 69 + db 0, 0 ; 6A + db 0, 0 ; 6B + db 0, 0 ; 6C + db 0, 0 ; 6D + db 0, 0 ; 6E + db 0, 0 ; 6F + db 0, 0 ; 70 + db 0, 0 ; 71 + db 0, 0 ; 72 + db 0, 0 ; 73 + db 0, 0 ; 74 + db 0, 0 ; 75 + db 0, 0 ; 76 + db 0, 0 ; 77 + db 0, 0 ; 78 + db 0, 0 ; 79 + db 0, 0 ; 7A + db 0, 0 ; 7B + db 0, 0 ; 7C + db 0, 0 ; 7D + db 0, 0 ; 7E + db 0, 0 ; 7F + + +;---------------------------------------------------------------------------- +; +; open / close debgug terminal +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +open_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + in al,pic1_imr + IFZ [debug_keyboard_level],0 + mov [old_pic1_imr],al + FI + inc [debug_keyboard_level] + + test al,00000010b + IFZ + CANDZ [local_console_enabled],true + + or al,00000010b + out pic1_imr,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,disable_keyboard + out kb_cmd,al + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,0F4h ; nop command, because may be + out kb_data,al ; within set led sequence + DO + in al,kb_status + test al,1 + REPEATZ + OD + in al,kb_data + DO + in al,kb_status + test al,2 + REPEATNZ + OD + mov al,enable_keyboard + out kb_cmd,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +close_debug_keyboard: + + push eax + push ds + pushfd + cli + + mov eax,cr0 + bt eax,31 + IFC + mov eax,phys_mem + mov ds,eax + FI + + dec [debug_keyboard_level] + IFZ + IFZ [break_is_pending],true + push ecx + mov ecx,10000000 + DO + dec ecx + EXITZ + + in al,kb_status + test al,1 + REPEATZ + + in al,kb_data + test al,break_mask + REPEATZ + OD + pop ecx + mov [break_is_pending],false + FI + + in al,pic1_imr + and al,11111101b + mov ah,[old_pic1_imr] + and ah,00000010b + or al,ah + out pic1_imr,al + FI + + popfd ; Rem: change of NT impossible + pop ds + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; local incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX 0, no input char available +; +; NC: EAX input char +; +;---------------------------------------------------------------------------- + + +local_incharety: + + call update_cursor + + + +local_soft_incharety: + + IFZ [local_console_enabled],true + + in al,kb_status + test al,1 + + IFZ + sub eax,eax + stc + ret + FI + + sub eax,eax + in al,kb_data + + + cmp al,esc_ + IFNZ + cmp al,num_lock + FI + IFZ + CANDZ [shift_status],1 + mov cl,1 + jmp reset + FI + + CORZ al,shift_left + IFZ al,shift_right + mov [shift_status],1 + + ELIFZ al,shift_left+break_mask + mov [shift_status],0 + ELIFZ al,shift_right+break_mask + mov [shift_status],0 + FI + + test al,break_mask + IFZ + mov [break_is_pending],true + + add al,al + add al,[shift_status] + mov al,[eax+chartab] + test al,al ; NC! + IFNZ + ret + FI + FI + + mov [break_is_pending],false + + FI + + sub eax,eax + stc + ret + + + + +;---------------------------------------------------------------------------- +; +; open / init debug screen +; +;---------------------------------------------------------------------------- + + + + + + +open_debug_screen: + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; kout +; +;---------------------------------------------------------------------------- + + + +kd_kout: + + IFZ [local_console_enabled],true + push ebx + push ecx + + mov ebx,[deb_screen_base] + mov ecx,[kout_ptr] + + mov byte ptr [(ecx*2)+ebx],al + mov byte ptr [(ecx*2)+ebx+1],0Fh + + inc ecx + IFAE ecx,10*80 + sub ecx,ecx + FI + mov word ptr [(ecx*2)+ebx],0 + + mov [kout_ptr],ecx + + pop ecx + pop ebx + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; update cursor +; +;---------------------------------------------------------------------------- + + + +update_cursor: + + push eax + push edx + + mov ax,word ptr [cursor_x] + IFNZ [de_facto_xy],ax + CANDZ [local_console_enabled],true + + mov [de_facto_xy],ax + + movzx edx,al + movzx eax,ah + imul eax,columns + add eax,edx + shl eax,8 + + mov dx,[deb_crtc_base] + mov al,cursor_addr_low + out dx,al + inc edx + mov al,ah + out dx,al + dec edx + mov al,cursor_addr_high + out dx,al + inc edx + shr eax,16 + out dx,al + + FI + pop edx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; kd outchar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + + +kd_outchar: + + mov ah,[charmode] + IFZ ah,1 + mov [cursor_y],al + mov [charmode],2 + ret + FI + IFZ ah,2 + mov [cursor_x],al + mov [charmode],0 + + mov ah,[cursor_y] + call set_remote_cursor + ret + FI + IFZ al,6 + mov [charmode],1 + ret + FI + IFZ al,1 + mov [cursor_x],0 + mov [cursor_y],0 + push eax + mov al,'H' + call vt100_control + pop eax + ret + FI + IFZ al,5 + pushad + IFZ [local_console_enabled],true + movzx edi,[cursor_y] + imul edi,columns*2 + movzx eax,[cursor_x] + lea edi,[(eax*2)+edi] + add edi,[deb_screen_base] + mov ecx,columns + sub ecx,eax + IFNC + mov ax,0720h + cld + rep stosw + FI + FI + mov al,'K' + call vt100_control + popad + ret + FI + IFZ al,8 + IFNZ [cursor_x],0 + dec [cursor_x] + FI + call remote_outbyte + ret + FI + IFZ al,13 + mov [cursor_x],0 + call remote_outbyte + ret + FI + IFZ al,10 + IFB_ [cursor_y],24 + inc [cursor_y] + ELIFZ [local_console_enabled],true + pushad + mov eax,07200720h + mov edi,[deb_screen_base] + lea esi,[edi+columns*2] + mov ecx,(lines-1)*columns*2/4 + cld + rep movsd + mov ecx,columns*2/4 + rep stosd + popad + FI + call remote_outbyte + ret + FI + + push ecx + push edx + IFZ [local_console_enabled],true + movzx ecx,[cursor_y] + imul ecx,columns + add cl,[cursor_x] + adc ch,0 + add ecx,ecx + add ecx,[deb_screen_base] + mov [ecx],al + mov byte ptr [ecx+1],7 + FI + inc [cursor_x] + pop edx + pop ecx + + IFB_ al,20h + mov al,' ' + FI + call remote_outbyte + + ret + + + + + + +;---------------------------------------------------------------------------- +; +; local outbar +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; EBX 100% value +; CL width +; DL x +; DH y +; +; DS linear space +; +;---------------------------------------------------------------------------- + + + + +local_outbar: + + IFNZ [local_console_enabled+PM],true + ret + FI + + pushad + + mov esi,columns*2 + movzx edi,dh + imul edi,esi + movzx edx,dl + lea edi,[(edx*2)+edi+PM] + add edi,[deb_screen_base+PM] + + movzx ecx,cl + imul eax,ecx + sub edx,edx + idiv ebx + shr ebx,1 + cmp edx,ebx + cmc + adc al,0 + IFA al,cl + + FI + + mov ch,0 + + IFNZ al,0 + dec al + mov byte ptr [edi],0DFh + sub edi,esi + add ch,2 + FI + DO + sub al,2 + EXITB + mov byte ptr [edi],0DBh + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + OD + IFZ al,-1 + CANDBE ch,cl + mov byte ptr [edi],0DCh + sub edi,esi + add ch,2 + FI + IFBE ch,cl + DO + test ch,2 + IFNZ + mov byte ptr [edi],20h + ELSE_ + mov byte ptr [edi],0C4h + FI + sub edi,esi + add ch,2 + cmp ch,cl + REPEATBE + + OD + FI + + popad + ret + + +;********************************************************************* +;****** ****** +;****** remote info (kernel debug) support ****** +;****** ****** +;********************************************************************* + + + align 4 + +remote_info_port dw 0 + +remote_io_open db false + + + + +;---------------------------------------------------------------------------- +; +; 8250 ports and masks +; +;---------------------------------------------------------------------------- + + +sio_rbr equ 0 ; receiver buffer register +sio_thr equ 0 ; transmitter holding register +sio_ier equ 1 ; interrupt enable register +sio_iir equ 2 ; interrupt identification register +sio_lcr equ 3 ; line control register +sio_mcr equ 4 ; modem control register +sio_lsr equ 5 ; line status register +sio_msr equ 6 ; modem status register +sio_scratch equ 7 ; scratch pad register +sio_dllow equ 0 ; baud rate divisor latch (low) +sio_dlhigh equ 1 ; baud rate divisor latch (high) + + +lsr_receiver_full equ 00000001b +lsr_thr_empty equ 00100000b +lsr_tsr_empty equ 01000000b +lsr_receiver_full_bit equ 0 +lsr_thr_empty_bit equ 5 +lsr_tsr_empty_bit equ 6 +lsr_overrun_bit equ 1 + +lcr_dlab_bit equ 7 + +mcr_dtr equ 00001b +mcr_rts equ 00010b +mcr_enable equ 01000b + +iir_no_intr equ 001b +iir_modem_status equ 000b +iir_thr_empty equ 010b +iir_data_avail equ 100b +iir_line_status equ 110b + +ier_data_avail equ 0001b +ier_thr_empty equ 0010b +ier_line_status equ 0100b +ier_modem_status equ 1000b + + + + +;---------------------------------------------------------------------------- +; +; IO macros +; +;---------------------------------------------------------------------------- + + +outdx macro relative_port,reg + + jmp $+2 + jmp $+2 + if relative_port eq 0 + out dx,reg + else + add dl,relative_port + out dx,reg + sub dl,relative_port + endif + endm + + +indx macro reg,relative_port + + jmp $+2 + jmp $+2 + if relative_port eq 0 + in reg,dx + else + add dl,relative_port + in reg,dx + sub dl,relative_port + endif + endm + + + +;---------------------------------------------------------------------------- +; +; set remote info mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX BIT 16..4 = 0 : remote info off +; +; EAX BIT 16..4 > 0 : 8250 port base address +; EAX BIT 3..0 : baud rate divisor +; +; DS phys mem +; +; kernel debug available +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +set_remote_info_mode: + + push ds + pushad + pushfd + + cli + push phys_mem + pop ds + + mov edx,eax + shr edx,4 + and dx,0FFFh + mov [remote_info_port],dx + + IFNZ ,,long + + mov ebx,eax ; set LCR and baud rate divisor + mov al,80h ; + outdx sio_lcr,al ; + mov al,bl ; + and al,0Fh ; + outdx sio_dllow,al ; + mov al,0 ; + outdx sio_dlhigh,al ; + mov al,03h ; + outdx sio_lcr,al ; + + indx al,sio_iir ; reset 8250 + indx al,sio_lsr ; + indx al,sio_iir ; + indx al,sio_rbr ; + indx al,sio_iir ; + indx al,sio_msr ; + indx al,sio_iir ; + + mov al,0 ; disable all 8250 interrupts + outdx sio_ier,al ; + + mov al,mcr_dtr+mcr_rts+mcr_enable + outdx sio_mcr,al + + mov [local_console_enabled],false + + ELSE_ + + mov [local_console_enabled],true + + FI + + popfd ; Rem: change of NT impossible + popad + pop ds + ret + + + + + +;---------------------------------------------------------------------------- +; +; set remote cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +set_remote_cursor: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + push eax + mov al,ah + inc al + call remote_outdec8 + mov al,';' + call remote_outbyte + pop eax + inc al + call remote_outdec8 + mov al,'H' + call remote_outbyte + ret + + + + +;---------------------------------------------------------------------------- +; +; remote outbyte +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL char +; +; remote info port <> 0, valid +; +; DS phys mem +; +;---------------------------------------------------------------------------- + + +remote_outbyte: + + push eax + push edx + + mov ah,al + movzx edx,[remote_info_port] + test edx,edx + IFNZ + DO + indx al,sio_lsr + test al,lsr_thr_empty + lsr_tsr_empty + REPEATZ + OD + mov al,ah + outdx sio_thr,al + FI + + pop edx + pop eax + ret + + + + +vt100_control: + + push eax + mov al,27 + call remote_outbyte + mov al,'[' + call remote_outbyte + pop eax + call remote_outbyte + ret + + + + +remote_outdec8: + + IFAE al,10 + push eax + push edx + mov ah,0 + mov dl,10 + div dl + push eax + call remote_outdec8 + pop eax + mov al,ah + call remote_outdec8 + pop edx + pop eax + ret + FI + + push eax + add al,'0' + call remote_outbyte + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; remote incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, remote info mode = off OR no input char available +; +; NC: EAX inpu char +; +;---------------------------------------------------------------------------- + + +remote_incharety: + + push edx + + movzx edx,[remote_info_port] + test edx,edx + IFNZ + + indx al,sio_lsr + + test al,lsr_receiver_full + IFNZ + indx al,sio_rbr + + IFZ [remote_io_open],true + + and eax,0FFh ; NC ! + pop edx + ret + FI + IFZ al,'+' + mov [remote_io_open],true + FI + FI + FI + + pop edx + sub eax,eax + stc + ret + + + + + + +;---------------------------------------------------------------------------- +; +; buffer incharety +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C : EAX undefined, buffer empty +; +; NC: EAX next char from buffer +; +;---------------------------------------------------------------------------- + + + align 4 + + +inchar_buffer_pointer dd 0 + + + + +buffer_incharety: + + mov eax,[inchar_buffer_pointer] + test eax,eax + IFNZ + mov al,[eax] + test al,al + IFNZ + inc [inchar_buffer_pointer] + ret ; NC ! + FI + + sub eax,eax + mov [inchar_buffer_pointer],eax + FI + stc + ret + + + + + + dcod ends + + + code ends + end diff --git a/l4-x86/smp/lx/kern/MEMCTR.asm b/l4-x86/smp/lx/kern/MEMCTR.asm new file mode 100644 index 0000000..e3b0bac --- /dev/null +++ b/l4-x86/smp/lx/kern/MEMCTR.asm @@ -0,0 +1,544 @@ +include l4pre.inc + + Copyright IBM, L4.MEMCTR, 30,09,97, 20 + + +;********************************************************************* +;****** ****** +;****** Memory Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 30.09.97 ****** +;****** ****** +;********************************************************************* + + public init_memctr + public init_sigma0_1 + public grab_frame + public phys_frames + + extrn create_kernel_including_task:near + extrn map_ur_page_initially:near + extrn physical_kernel_info_page:dword + extrn dcod_start:byte + extrn default_kdebug_end:byte + extrn default_sigma0_end:byte + extrn ktest_end:byte + + + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include cpucb.inc +include tcb.inc +include pagconst.inc +include pagmac.inc +include syscalls.inc +include msg.inc +include kpage.inc +.list + + +ok_for x86 + + + IF kernel_x2 + extrn generate_x2_info_page:near + ENDIF + + + + align 4 + + +phys_frames dd 0 + +lowest_allocated_frame dd 0,0 + + + + align 4 + + +;---------------------------------------------------------------------------- +; +; grab frame / grab mem +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX size of grabbed area / - +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; phys_mem:EAX begin of grabbed mem (4096 bytes / n*4096 bytes) +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + +grab_frame: + + push ebx + push ecx + push edx + push esi + push edi + push ebp + + ; edx = 0 + ; if stack pointer within tcb space (tcb in kernel mode) + sub edx,edx + IFAE esp, + CANDB esp, + ; edx = Physical Memory + add edx,PM + FI + + ; load lowest allocated frame + mov eax,[edx+lowest_allocated_frame] + + ; if not 0 grab frame initially + test eax,eax + jnz initial_grab_frame + + ; setup ipc to sigma 0 + sub eax,eax ; send register only + mov ecx,eax ; timeout 0 + lea edx,[eax-2] ; w0 = FFFFFFFE (request grant of free page) + + log2 <%physical_kernel_mem_size> + + mov ebp,log2_*4+map_msg ; receive mapping in physical kernel memory area + + mov esi,sigma0_task ; dest sigma0 + sub edi,edi ; open receive + + ; send ipc + int ipc + + ; if error occured or no map message or page not granted or not exactly one page granted + test al,ipc_error_mask + CORNZ + test al,map_msg + CORZ + test bl,fpage_grant + CORZ + shr bl,2 + IFNZ bl,log2_pagesize + ; kernel exception due to false mapping from sigma0 + ke <'-',0E5h,'0_err'> + FI + + ; return offset of physical page + mov eax,edx + and eax,-pagesize + + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icode + + +initial_grab_frame: + + ; decrease pointer to lowest allocated frame by one page + sub eax,pagesize + + ; memory underflow if pointer below 1 MB + IFB_ eax,MB1 + ke '-memory_underflow' + FI + + ; store current pointer to lowest allocated frame + mov [edx+lowest_allocated_frame],eax + + pop ebp + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + + + + icod ends + + + +;----------------------------------------------------------------------- +; +; init memory controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode, paging not yet enabled +; +; disable interrupt +; +; DS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_memctr: + + mov edi,offset physical_kernel_info_page + + ; set end main memory to minimum of current and kernel memory size + IFA [edi+main_mem].mem_end,physical_kernel_mem_size + mov [edi+main_mem].mem_end,physical_kernel_mem_size + FI + + ; x2 info page for second kernel + sub edx,edx + ;lno___prc edx + IF kernel_x2 + shl edx,2 + test edx,edx + IFNZ + call generate_x2_info_page + FI + ENDIF + + ; set resevered memory area to correct size including: + ; kernel debugger + mov eax,offset dcod_start + mov ecx,ds:[edi+kdebug_end] + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + + ; sigma 0 + mov ecx,ds:[edi+sigma0_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + +; mov ecx,ds:[edi+sigma1_ktask].ktask_end +; IFZ ecx, +; CANDA ecx,eax +; mov eax,ecx +; FI + + ; booter task + mov ecx,ds:[edi+booter_ktask].ktask_end + IFZ ecx, + CANDA ecx,eax + mov eax,ecx + FI + add eax,pagesize-1 + and eax,-pagesize + + mov ecx,ds:[edi+reserved_mem0].mem_end + test ecx,ecx + CORZ + IFA eax,ecx + mov ds:[edi+reserved_mem0].mem_end,eax + FI + + ; set reserved memory 0 information in physical kernel info page + mov eax,offset physical_kernel_info_page + test ecx,ecx + CORZ + IFB_ eax,ds:[edi+reserved_mem0].mem_begin + mov ds:[edi+reserved_mem0].mem_begin,eax + FI + + ; set physical regions to correct size + mov eax,ds:[edi+main_mem].mem_end + + mov ch,kpage_mem_regions + DO + + lea esi,[edi+reserved_mem0] + mov cl,kpage_mem_regions + DO + IFAE [esi].mem_end,eax + CANDB [esi].mem_begin,eax + mov eax,[esi].mem_begin + FI + add esi,sizeof mem_descriptor + dec cl + REPEATNZ + OD + + dec ch + REPEATNZ + OD + + + ; set reserved memory 1 region + mov ds:[edi+reserved_mem1].mem_begin,eax + IFB_ ds:[edi+reserved_mem1].mem_end,eax + mov ds:[edi+reserved_mem1].mem_end,eax + FI + + ; set lowest allocated frame + mov [edx+lowest_allocated_frame],eax + + ;set physical frame number + mov eax,ds:[edi+main_mem].mem_end + shr eax,log2_pagesize + mov [phys_frames],eax + + ret + + + + + + +;----------------------------------------------------------------------- +; +; init sigma 0 and 1 +; +; +; PRECONDITION: +; +; interrupts disabled +; +;----------------------------------------------------------------------- + + + + + +xpush macro reg + + ; push macro using ecx instead of esp + sub ecx,4 + mov [ecx],reg + + endm + + + + + + +init_sigma0_1: + + ; read kernel task stack pointer of sigma0 + mov ecx,ds:[logical_info_page+sigma0_ktask].ktask_stack + + ; push physical kernel info page address on stack + mov edi,offset physical_kernel_info_page + xpush edi + + ; set new stack pointer of sigma0 + lea ebx,ds:[logical_info_page+sigma0_ktask] + mov [ebx].ktask_stack,ecx + + ; create new kernel including task for sigma0 + ;task id: sigma0 task in eax, pointer to logical info page task information in ebx + mov eax,sigma0_task + call create_kernel_including_task + + ; initialise sigma 0 space + call init_sigma0_space + + ; create task for sigma1 + mov eax,sigma1_task + lea ebx,ds:[logical_info_page+offset sigma1_ktask] + call create_kernel_including_task + + ret + + + +;############################################################################################ + +;----------------------------------------------------------------------- +; +; init sigma 0 address space ptabs +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; EAX addr of first available page +; +;---------------------------------------------------------------------------- + + +init_sigma0_space: + + load__proot ebx,<((sigma0_task AND mask task_no) SHR task_no)> + mov ebx,dword ptr [ebx+PM] + and ebx,-pagesize + mov ecx,MB4/pagesize + DO + mov eax,dword ptr [ebx+PM] + test eax,page_present + IFNZ + and eax,-pagesize + mov esi,eax + mov dl,page_present+page_write_permit+page_user_permit + call map_ur_page_initially + FI + add ebx,4 + dec ecx + REPEATNZ + OD + + sub eax,eax + mov edi,ds:[logical_info_page+reserved_mem0].mem_begin + call map_ur_pages + + mov eax,offset physical_kernel_info_page + mov esi,eax + mov dl,page_user_permit+page_present + call map_ur_page_initially + + ;; lno___prc eax + sub eax,eax + + sub edi,edi + xchg [eax*4+lowest_allocated_frame+PM],edi ; turn off simple grabbing + mov ds:[logical_info_page+reserved_mem1].mem_begin,edi + + + pushad + mov ebx,offset logical_info_page+dedicated_mem0 + DO + mov esi,[ebx].mem_begin + mov edi,[ebx].mem_end + test edi,edi + IFNZ + push eax + push ebx + mov ebx,offset logical_info_page + + ;; mov eax,[ebx+reserved_mem0].mem_end + mov eax,KB64 + IFB_ esi,eax + mov esi,eax + FI + mov eax,[ebx+reserved_mem1].mem_begin + IFBE esi,eax + CANDA edi,eax + mov edi,eax + FI + mov eax,[ebx+main_mem].mem_end + IFA esi,eax + mov esi,eax + FI + IFA edi,eax + mov edi,eax + FI + + IFB_ esi,edi + mov eax,esi + call map_ur_pages + FI + + pop ebx + pop eax + FI + add ebx,sizeof mem_descriptor + cmp ebx,offset logical_info_page+dedicated_mem4 + REPEATBE + OD + popad + + mov eax,ds:[logical_info_page+reserved_mem0].mem_end + + call map_ur_pages + + + mov eax,ds:[logical_info_page+main_mem].mem_end + add eax,MB4-1 + and eax,-MB4 + DO ; explicitly map free physical + cmp eax,2*GB1 ; mem beyond main mem 4M + EXITAE ; aligned up to 2G + mov esi,eax + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add eax,MB4 + REPEAT + OD + + + ; explicitly map 2...3 GB + mov esi,2*GB1 ; to physical 3...4 GB + DO ; for devices + lea eax,[esi+GB1] + mov dl,superpage+page_user_permit+page_write_permit+page_present + call map_ur_page_initially + add esi,MB4 + cmp esi,3*GB1 + REPEATB + OD + + ret + + + +map_ur_pages: + mov esi,eax + DO + mov ebx,pagesize + mov dl,page_user_permit+page_write_permit+page_present + bt dword ptr ds:[cpu_feature_flags],page_size_extensions_bit + IFC + test esi,MB4-1 + CANDZ + test eax,MB4-1 + CANDZ + mov ecx,edi + sub ecx,esi + CANDAE ecx,MB4 + or dl,superpage + mov ebx,MB4 + FI + + call map_ur_page_initially + add eax,ebx + add esi,ebx + cmp esi,edi + REPEATB + OD + + ret + + + icod ends + + + + code ends + end diff --git a/l4-x86/smp/lx/kern/PAGFAULT.asm b/l4-x86/smp/lx/kern/PAGFAULT.asm new file mode 100644 index 0000000..fb09220 --- /dev/null +++ b/l4-x86/smp/lx/kern/PAGFAULT.asm @@ -0,0 +1,792 @@ +include l4pre.inc + + + Copyright IBM, L4.PAGFAULT, 11,03,99, 9163, K + + +;********************************************************************* +;****** ****** +;****** Page Fault Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 11.03.99 ****** +;****** ****** +;********************************************************************* + + + public init_pagfault + public page_fault_handler + + + extrn map_system_shared_page:near + + extrn ipc_sc:near + extrn ipc_critical_region_begin:near + extrn ipc_critical_region_end:near + extrn tcb_fault:near + extrn pagmap_fault:near + extrn push_ipc_state:near + extrn pop_ipc_state:near + extrn cancel_if_within_ipc:near + extrn tunnel_to:near + extrn define_idt_gate:near + extrn exception:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +.nolist +include msg.inc +.list + + + +ok_for x86 + + + extrn set_small_pde_block_in_pdir:near + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGFAULT INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;----------------------------------------------------------------------- +; +; init page fault handling +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; pm32 +; +; DS,ES linear space +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX...EBP scratch +; +;----------------------------------------------------------------------- + + icode + + + +init_pagfault: + + ; set interrupt vector for page fault handler + mov eax,offset page_fault_handler + mov bl,page_fault + mov bh,0 + call define_idt_gate + + ret + + + icod ends + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; Page Fault Handler +; +;---------------------------------------------------------------------------- +; +; Analyzes Page Faults and passes valid Page Faults to kernel. +; +;---------------------------------------------------------------------------- +; Remark: +; +; The linear addresses 1 MB ... 1 MB + 64 KB - 1 are aliased with +; 0 ... 64 KB - 1 to emulate 8086 wrap around. +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + + + + ; concurrent fault on the same address has to be handled + +page_fault_handler: + ; check if there is a real PF + + + + + + ; call pl0 handler if faulting code was pl0 + cmp ss:[esp+iret_cs+4],phys_mem_exec + xc z,page_fault_pl0,long + + ; ipre present with exception code + ipre ec_present + + ; safe stack pointer + mov ebp,esp + + ; else load interrupted instruction pointer + mov ebx,-1 + IFNZ + mov ebx,[ebp+ip_eip] + FI + + ; load faulting address + mov edx,cr2 + + ; check for read or write fault + mov cl,byte ptr [ebp+ip_error_code] + if fpopn_write gt page_fault_due_to_write_bit + shl cl,fpopn_write - page_fault_due_to_write_bit + endif + if fpopn_write lt page_fault_due_to_write_bit + shr cl,page_fault_due_to_write_bit - fpopn_write + endif + and cl,page_fault_due_to_write + + and dl,NOT 3 + or dl,cl + + ; load tcb address + and ebp,-sizeof tcb + + ; call special pagefault handler for small address space pf + cmp edx,offset small_virtual_spaces + xc ae,perhaps_small_pf,long + + ; if pagefault within big hw address space + IFB_ edx,,long + + ; if thread is locked running + IFNZ [ebp+fine_state],locked_running + cmp ebx,-1 + ; pf within ipc + xc z,occurred_within_ipc,long + CANDNZ ; else + + ;; mov eax,[ebp+rcv_descriptor] ; dirty! this branch might be entered + ;; push eax ; if deceit_pre leads to PF even though + ;; push ebp ; status is not (yet) locked_running + + ; setup PF ipc to pager + mov esi,[ebp+pager] ; dest = pager id + sub edi,edi ; mw2 = 0 + sub ecx,ecx ; timeout snd, rcv, pf = infinity + sub eax,eax ; snd dope = register ipc only + mov ebp,32*4+map_msg ; rcv dope = entire address space (fpage = 0,32) + map message + ; edx mw0 = faulting address/4,write fault, ~ + ; ebx mw1 = user lvl eip + push 0 + push phys_mem_exec + push offset ipcret + jmp ipc_sc + ipcret: + + ;; pop ebp ; see above + ;; pop ebx + ;; mov [ebp+rcv_descriptor],ebx + + test al,ipc_error_mask + mov al,page_fault + jnz exception + + ipost + FI + + ; PF happend within IPC + ; store IPC state + call push_ipc_state + + IFNZ + ; setup ipc to pager + mov esi,[ebp+pager] + sub edi,edi + sub eax,eax + push edx + push ebp + mov ebp,32*4+map_msg + push ds + int ipc + pop ds + pop ebp + pop edx + + ; if PF ipc did not fail + test al,ipc_error_mask + IFZ + ; and page is present + test__page_present edx + CANDNC + ; reload IPC state and continue + call pop_ipc_state + + ipost + FI + FI + ; otherwise cancel IPC + jmp cancel_if_within_ipc + + FI + + ; PF in upper memory region + + ; if PF eip != -1 (PF occured in kernel code) => PF Exception + mov al,page_fault + cmp ebx,-1 + jnz exception + + mov eax,edx + + ; if Faulting address below small space area => addressing error + cmp eax,shared_table_base + jb short addressing_error + + ; if Faulting address in shared table area => shared table fault + cmp eax,shared_table_base+shared_table_size-1 + jbe shared_table_fault + + ; PF before io page base map => addressing error + cmp eax,offset iopbm + jb short addressing_error + + ; PF in IO page base map => iopbm fault + cmp eax,offset iopbm+sizeof iopbm-1 + jbe own_iopbm_fault + + ; PF before com0 space => addressing error + cmp eax,offset com0_space + jb short addressing_error + + ; PF in com1 space => com space write fault + cmp eax,offset com1_space+com1_space_size-1 + jbe com_space_write_fault + + + + + + +addressing_error: + +internal_addressing_error: + + ke '-inv_addr' + + + +XHEAD occurred_within_ipc + + ; set PF EIP to 0 if within short IPC path + mov eax,[esp+ip_eip] + IFAE eax,offset ipc_critical_region_begin + CANDBE eax,offset ipc_critical_region_end + sub eax,eax ; Z ! + FI ; NZ else ! + xret ,long + + + + + +;---------------------------------------------------------------------------- +; +; small space page fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX faulting virtual address +; EBP tcb write addr +; +; DS linear_kernel_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC small table fault (INT CONST address, attributes) : +; +; IF current pdir has ptab for this small space address +; THEN handle pf (address MOD small space size, attributes) +; ELIF related large space has pdir for related large address +; THEN copy large pdes to small pdes +; ELSE handle pf (address MOD small space size, attributes) +; (* instr restart will re-raise pf which then will be +; resolved by 'copy ...' *) +; FI +; +; ENDPROC small table fault +; +;---------------------------------------------------------------------------- + + + +XHEAD perhaps_small_pf + + cmp edx,offset small_virtual_spaces+small_virtual_spaces_size + xret ae,long + + mov ch,ds:[log2_small_space_size_DIV_MB4] + + mov ah,byte ptr ds:[gdt+(linear_space AND -8)+7] + mov al,byte ptr ds:[gdt+(linear_space AND -8)+4] + shl eax,16 + xor eax,edx + shr eax,22 + mov cl,ch + shr eax,cl + + mov esi,ebp + IFNZ + mov esi,[ebp+com_partner] + FI + lno___task esi,esi + load__proot esi,esi + add esi,PM + + + xpdir eax,edx + mov edi,ds:[cpu_cr3] + mov cl,32-22 + lea edi,[(eax*4)+edi+PM] + sub cl,ch + shl edx,cl + shr edx,cl + + test byte ptr [edi],page_present + xret nz,long + + xpdir eax,edx + test byte ptr [(eax*4)+esi],page_present + xret z,long + + mov cl,ch + sub cl,22-2-22 + shr edi,cl + shl edi,cl + call set_small_pde_block_in_pdir + + ipost + + + + + + + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; shared table fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; DS linear_space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC shared table fault (INT CONST address, attributes) : +; +; IF kernel has ptab for this address CAND +; actual task has no ptab for this address +; THEN enter kernel ptab link into actual pdir +; ELSE decode access {and enter into kernel pdir too} +; FI +; +; ENDPROC shared table fault +; +;---------------------------------------------------------------------------- +; shared table INVARIANT: +; +; all shared table ptabs are linked to kernel pdir +; +;---------------------------------------------------------------------------- + + align 16 + + +shared_table_fault: + + shr eax,22 + lea eax,[(eax*4)+PM] + lno___prc edi + mov edi,ds:[kernel_proot+8*edi-8] + mov ebx,[eax+edi] + test bl,page_present + IFNZ + mov edi,cr3 + and edi,-pagesize + xchg [eax+edi],ebx + test bl,page_present + IFZ + ipost + FI + FI + mov eax,edx + + cmp eax,offset tcb_space+tcb_space_size + jb tcb_fault + + cmp eax,offset pdir_space + jb addressing_error + + cmp eax,offset pdir_space+pdir_space_size + jb pdir_space_fault + + cmp eax,offset chapter_map + jb addressing_error + + cmp eax,offset chapter_map+(max_ptabs*chapters_per_page) + jb pagmap_fault + + jmp addressing_error + + + + +;---------------------------------------------------------------------------- +; +; own iopbm fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; + + + + +own_iopbm_fault: + + ke 'iopbm_fault' + + ret + + + +;---------------------------------------------------------------------------- +; +; com space write fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address +; EDX = EAX +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- +; +; PROC com space write fault (addr) : +; +; calc addr in dest task ; +; ensure ptab existing and write mapped in dest task ; +; copy entry . +; +; ensure ptab existing and write mapped in dest task : +; REP +; IF NOT ptab existing +; THEN map ptab ; +; enter new ptab into comspace +; ELIF NOT write mapped in dest task +; THEN user space read write fault (dest task, dest task addr, write) +; ELSE LEAVE +; PER . +; +; ENDPROC com space write fault +; +;---------------------------------------------------------------------------- + + align 4 + + +com_space_write_fault: + + + mark__ressource ebp,com_used + + mov esi,[ebp+com_partner] ; com partner is tcb address + + sub eax,com0_base + CORB + IFAE eax,MB8 + sub eax,com1_base-com0_base + FI + sub edx,com0_base + shr edx,23-1 + mov edi,[ebp+waddr] + test edx,10b + IFNZ + shl edi,16 + FI + + and edi,-MB4 + add eax,edi + + + DO + lea___pdir ebx,esi + xpdir ecx,eax + mov ebx,[(ecx*4)+ebx] + and bl,NOT page_user_permit + mov edi,ebx + + and bl,page_present+page_write_permit + IFZ bl,page_present+page_write_permit + and ebx,-pagesize + xptab ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + and bl,page_present+page_write_permit + CANDZ bl,page_present+page_write_permit + + mov [(edx*4)+pdir+(offset com0_space SHR 20)],edi + + ipost + FI + + push esi + + mov edi,ebp + mov ebp,[ebp+com_partner] + call tunnel_to + + add byte ptr [eax],0 + + xchg edi,ebp + call tunnel_to + + mov ebp,edi + pop esi + REPEAT + OD + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; pdir space fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting virtual address within pdir_space +; EDX = EAX +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +;---------------------------------------------------------------------------- + + align 4 + + +pdir_space_fault: + + sub eax,offset pdir_space + shr eax,12 + load__proot eax,eax + + mov esi,edx + call map_system_shared_page + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; Special PL0 Page Fault Handling +; +;---------------------------------------------------------------------------- + + + + +iret_ equ 0CFh + + + + + align 16 + + + + +XHEAD page_fault_pl0 + + + test byte ptr ss:[esp+iret_eflags+4+2],(1 SHL (vm_flag-16)) + xret nz,long + + push eax + + test esp,(sizeof tcb-1) AND (-512) + IFZ + CANDA esp, + CANDB esp, + ke 'esp < 512' + FI + + mov eax,ss:[esp+iret_eip+4+4] + + mov eax,cs:[eax] + ; if PF happens at IRET (in PL0) + IFZ al,iret_ ; new iret vector is dropped + ; and faulting vector is taken + ; instead. This ensures correct + ; load of seg reg. + mov eax,ss:[esp+4] + or al,page_fault_from_user_level + mov ss:[esp+3*4+4+4],eax + + pop eax + add esp,3*4+4 ; NZ ! + xret ,long + + FI + + and ah,NOT 7 ; + IFNZ eax,0FF0040F6h ; test byte ptr [reg],FF + CANDNZ eax,0FF006080h ; and byte ptr [reg],FF + pop eax ; are skipped upon PF and result in C + cmp eax,eax ; + xret ,long ; Z ! + FI + + push ebx + push ecx + + mov ecx,cr3 + and ecx,-pagesize + mov eax,cr2 + xpdir ebx,eax + + IFAE eax,shared_table_base + CANDB eax,shared_table_base+shared_table_size + lno___prc ecx + mov ecx,ss:[kernel_proot+8*ecx-8] + FI + + mov ecx,dword ptr ss:[(ebx*4)+ecx+PM] + test cl,page_present + IFNZ + and ecx,-pagesize + xptab eax,eax + test byte ptr ss:[(eax*4)+ecx+PM],page_present + CANDNZ + and byte ptr ss:[esp+iret_eflags+4*4],NOT (1 SHL c_flag) + ELSE_ + or byte ptr ss:[esp+iret_eflags+4*4],1 SHL c_flag + FI + add ss:[esp+iret_eip+4*4],4 + + pop ecx + pop ebx + pop eax + add esp,4 + + iretd + + + + + + + + + + code ends + end + + + + + diff --git a/l4-x86/smp/lx/kern/Pagctr.asm b/l4-x86/smp/lx/kern/Pagctr.asm new file mode 100644 index 0000000..9541668 --- /dev/null +++ b/l4-x86/smp/lx/kern/Pagctr.asm @@ -0,0 +1,1365 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGCTR, 24,08,99, 116 + + +;********************************************************************* +;****** ****** +;****** Paging Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + public enable_paging_mode + public init_fresh_frame_pool + public map_page_initially + public alloc_kernel_pages + public alloc_shared_kernel_pages + public ptabman_init + public ptabman_start + public insert_into_fresh_frame_pool + public request_fresh_frame + public map_fresh_ptab + public map_system_shared_page + public flush_system_shared_page + public gen_kernel_including_address_space + + + + extrn alloc_initial_pagmap_pages:near + extrn define_idt_gate:near + extrn grab_frame:near + extrn phys_frames:dword + extrn max_kernel_end:near + extrn physical_kernel_info_page:dword + extrn pre_paging_cpu_feature_flags:dword + + extrn ltr_pnr:near + + +.nolist +include l4const.inc +include uid.inc +.list +include adrspace.inc +.nolist +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include pagcb.inc +include msg.inc +include syscalls.inc +include kpage.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGCTR INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; enable paging mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; ES phys mem +; +; paging disabled +; +;---------------------------------------------------------------------------- + + + icode + + + +enable_paging_mode: ; alloc shared pages + ; establish initial Address space + pushad + + ; Grab Frame for new Page Directory + call grab_frame + mov edx,eax + + ; load Directory Address in CR3 + mov cr3,eax + mov ebx,eax + + ; clear Page for Page Directory + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + ; set page directory entry + lea eax,[ebx+page_present+page_write_permit] + ; ebx = physical address of pdir + ptab space + mov [ebx+offset ptab_space SHR 20],eax + + + ; map kernel pages to the beginning of the address space + sub eax,eax + sub esi,esi + mov edi,offset max_kernel_end+pagesize-1 + shr edi,log2_pagesize + DO + mov cl,page_present+page_write_permit+page_user_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + + ; Map Physical Memory (with 4MB Pages if present) + bt ds:[pre_paging_cpu_feature_flags],page_size_extensions_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_superpages_bit + mov cr4,eax + + mov edi,[phys_frames] + add edi,1024-1 + shr edi,10 + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_superpage_initially + add eax,1024*pagesize + add esi,1024*pagesize + dec edi + REPEATNZ + OD + ELSE_ + mov edi,[phys_frames] + mov esi,PM + sub eax,eax + DO + mov cl,page_present+page_write_permit + call map_page_initially + add eax,pagesize + add esi,pagesize + dec edi + REPEATNZ + OD + FI + + + ; allocate page nodes and chapter map + call alloc_initial_pagmap_pages + + ; allocate kernel pages ;first page after gdt is local + mov esi,offset gdt+first_kernel_sgm + mov eax,pagesize + call alloc_kernel_pages + + lno___prc eax + IFZ eax,1 + mov esi,offset gdt+first_kernel_sgm+pagesize + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm)-pagesize + call alloc_kernel_pages + ELSE_ + mov esi,offset gdt+first_kernel_sgm+pagesize + mov eax,kernel_r_tables_size-(offset gdt+first_kernel_sgm)-pagesize + call alloc_shared_kernel_pages + FI + + ;-------- special try: PWT on gdt page set ------ + ;pushad + ;mov edi,cr3 + ;mov esi,offset gdt+first_kernel_sgm + ;xpdir ebx,esi + ;xptab esi,esi + ;mov edi,dword ptr [(ebx*4)+edi+PM] + ;and edi,-pagesize + ;or byte ptr [(esi*4)+edi+PM],page_write_through + ;popad + ;------------------------------------------------ + + ; map local apic + mov eax,0FEE00000h + mov esi,offset local_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + ; map io apic + mov eax,0FEC00000h + mov esi,offset io_apic + mov cl,page_present+page_write_permit+page_write_through+page_cache_disable + call map_page_initially + + ; map logical kernel info page + mov eax,offset physical_kernel_info_page + mov esi,offset logical_info_page + mov cl,page_present+page_write_permit + call map_page_initially + + ; allocate frames for page table backlink + mov esi,offset ptab_backlink + mov eax,[phys_frames] + lea eax,[eax*4] + lno___prc ebx + IFZ ebx,1 + call alloc_kernel_pages + ELSE_ + call alloc_shared_kernel_pages + FI + + ; allocate frame for processor local tcbs: dispatcher + 3 + mov esi,offset dispatcher_tcb + mov eax,pagesize + call alloc_kernel_pages + + ; grab frame and clear page for empty task page root + call grab_frame + + mov ebx,eax + + mov edi,eax + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + + lea eax,[ebx+page_present+page_write_permit] + mov [ebx+offset ptab_space SHR 20],eax + + ; copy kernel pages to free page + lea esi,[edx+shared_table_base SHR 20] + lea edi,[ebx+shared_table_base SHR 20] + mov ecx,shared_table_size SHR 22 + cld + rep movsd + + + ;; ke 'first done before paging' + ;; call ltr_pnr + ;; jmp enable_paging_mode + + ; enable paging + mov eax,cr0 + bts eax,31 + mov cr0,eax + + + + ; set all task page roots to the clear page + lno___prc eax + IFZ eax,1 + mov edi,offset task_proot ; ?????????????????????????? + lea eax,[ebx+root_chief_no] + sub ecx,ecx + DO + mov [edi],eax + mov [edi+4],ecx + add edi,8 + cmp edi,offset proot_end_marker + REPEATB + OD + dec ecx + mov [edi],ecx + mov [edi+4],ecx + + mov [bootstrap_page_root],edx + FI + + ; set kernel page root ;get processor number + lno___prc edi + + lea ecx,[empty_proot+8*edi-8] + lea edi,[kernel_proot+8*edi-8] + mov [ecx],ebx + mov [ecx+4],ebx + mov [edi],edx + mov [edi+4],edx + + + popad + ret + + bootstrap_page_root dd 0 + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; alloc kernel pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX area size (will be rounded upwards to multiple of 4K) +; CL page attributes (U/S, RW, Cacheability, Global) +; ESI linear address (only bits 31...12 relevant) +; +; CR3 physical address of kernel page directory +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; frames grabbed and mapped S/W +; +;---------------------------------------------------------------------------- + + + icode + + +alloc_kernel_pages: + + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + ; while pages to be mapped > 0 + DO + push eax + mov cl, page_present+page_write_permit + ; grab physical frame + call grab_frame + ; map page to grabbed frame + call map_page_initially + pop eax + ; get offset of next page + add esi,pagesize + ; decrease pages to be mapped + sub eax,1 + REPEATA + OD + + popad + ret + + +alloc_shared_kernel_pages: + pushad + + mov edx,cr3 + + add eax,pagesize-1 + shr eax,12 + ; while pages to be mapped > 0 + DO + push eax + mov cl, page_present+page_write_permit + ; get physical address of kernel_proot 1 + xpdir edi,esi + + + mov eax,ds:[bootstrap_page_root] + ;; mov eax,ds:[kernel_proot] ; be sure address is value of bootstraps cr3 + + lea edi,[edi*4] + add eax,edi + IFAE esp, + add eax,PM + FI + mov eax,[eax] + and eax,-pagesize + + xptab edi,esi + lea edi,[edi*4] + add edi,eax + IFAE esp, + add edi,PM + FI + mov eax,ds:[edi] + and eax,-pagesize + + ; map page to same location as in bootstrap kernel + call map_page_initially + pop eax + ; get offset of next page + add esi,pagesize + ; decrease pages to be mapped + sub eax,1 + REPEATA + OD + + popad + ret + + + icod ends + +;; ################################################################################ + +;---------------------------------------------------------------------------- +; +; map page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot OR sigma0 proot +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX PTE address +; +; mapped +; +;---------------------------------------------------------------------------- + + + icode + + + +map_page_initially: + + push edi + push ebp + + sub ebp,ebp + IFAE esp, + mov ebp,PM + FI + add edx,ebp + + xpdir edi,esi + shl edi,2 + + mov ebx,[edx+edi] + test bl,page_present + IFZ + push eax + push ecx + push edi + call grab_frame + mov ebx,eax + lea edi,[eax+ebp] + mov ecx,pagesize/4 + sub eax,eax + cld + rep stosd + pop edi + pop ecx + pop eax + + mov bl,cl + or bl,page_present+page_write_permit + mov [edx+edi],ebx + + FI + and ebx,-pagesize + + xptab edi,esi + lea ebx,[(edi*4)+ebx] + add ebx,ebp + + mov [ebx],eax + mov [ebx],cl + + sub edx,ebp + pop ebp + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map superpage (4M) initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4M aligned) +; CL access attributes (U/S, R/W, P-bit) +; EDX kernel proot +; ESI linear address (only bits 31...22 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (always resident) +; +;---------------------------------------------------------------------------- + + +map_superpage_initially: + + push eax + push edi + + xpdir edi,esi + shl edi,2 + add edi,edx + + mov al,cl + or al,superpage + + mov [edi],eax + + pop edi + pop eax + ret + + + icod ends + + + +;################################################################################## + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** Fresh Frame Pool and PTAB Management ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +;---------------------------------------------------------------------------- +; +; init fresh frame pool +; +;---------------------------------------------------------------------------- +; +; NOTE: fresh frames are always (!) 0-filled +; +;---------------------------------------------------------------------------- + + + +initial_fresh_frames equ 32 + + + icode + + +init_fresh_frame_pool: + + ; clear free_fresh_frames structure + sub eax,eax + mov ds:[first_free_fresh_frame],eax + mov ds:[free_fresh_frames],eax + + ; grab 32 frames and insert them into fresh frame pool + mov ecx,initial_fresh_frames + + DO + call grab_frame + call insert_into_fresh_frame_pool + dec ecx + REPEATNZ + OD + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; insert into fresh frame pool +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physcial frame address (bits 0..11 ignored) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; inserted into ptab pool +; +; initialized to 0 (all entries except first one) +; offset 0: link to next frame in pool / 0 +; +;---------------------------------------------------------------------------- + + +insert_into_fresh_frame_pool: + + push eax + push ecx + push edi + pushfd + + ; clear interrupts + cli + + ; aquire lock + lock bts ds:[fresh_frame_pool_lock],0 + IFC + ins_fresh_frame_pool_lock_aquired: + + ; mask out bits 0..11 and load address of frame + and eax,-pagesize + lea edx,[eax+PM] + + ; set new first free fresh frame + xchg ds:[first_free_fresh_frame],eax + ; first double links to next free fresh frame + mov [edx],eax + + ; increase number of free fresh frames + inc ds:[free_fresh_frames] + ELSE_ + ; spin for lock + DO + DO + bt ds:[fresh_frame_pool_lock],0 + REPEATS + OD + lock bts ds:[fresh_frame_pool_lock],0 + jc ins_fresh_frame_pool_lock_aquired + REPEAT + OD + FI + ; release lock + lock btr ds:[fresh_frame_pool_lock],0 + + ; clear remaining part of the page + lea edi,[edx+4] + mov ecx,pagesize/4-1 + sub eax,eax + cld + rep stosd + + popfd + pop edi + pop ecx + pop eax + ret + + + + +;---------------------------------------------------------------------------- +; +; request fresh frame +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh frame's physical address +; +; fresh frame is all 0 +; +; C: EAX scratch +; +; no fresh frame available +; +;---------------------------------------------------------------------------- + + +request_fresh_frame: + + ; aquire lock + lock bts ds:[fresh_frame_pool_lock],0 + IFC + request_fresh_frame_lock_aquired: + + sub ds:[free_fresh_frames],1 + IFNC + push edi + + mov eax,ds:[first_free_fresh_frame] + sub edi,edi + xchg edi,dword ptr [eax+PM] + mov ds:[first_free_fresh_frame],edi + + ; release lock + lock btr ds:[fresh_frame_pool_lock],0 + + pop edi + ret + + FI + ELSE_ + ; spin for lock + DO + DO + bt ds:[fresh_frame_pool_lock],0 + REPEATS + OD + lock bts ds:[fresh_frame_pool_lock],0 + jc request_fresh_frame_lock_aquired + REPEAT + OD + FI + + inc ds:[free_fresh_frames] + + ; release lock + lock btr ds:[fresh_frame_pool_lock],0 + + ke '-fframe_underflow' + + stc + ret + + + +;---------------------------------------------------------------------------- +; +; request fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; +; C: EAX scratch +; +; no fresh ptab available +; +;---------------------------------------------------------------------------- + + +request_fresh_ptab: + + ; request fresh frame + call request_fresh_frame + IFNC + push esi + + ; test location in chapter map + mov esi,eax + shr esi,log2_chaptersize + add esi,offset chapter_map + + test__page_present esi + IFC + push eax + ; get page for chapter map + call request_fresh_frame + IFNC + ; map page to chapter map area + call map_system_shared_page + IFC + ; if mapping failed, reinsert page into pool + call insert_into_fresh_frame_pool + ; no free pagetable available + stc + FI + FI + pop eax + FI + pop esi + FI + + ret + + + +;##################################################################################################### + + + +;---------------------------------------------------------------------------- +; +; map fresh ptab +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX dest task (kernel if system shared space) +; ECX pointer to pdir entry +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: EAX fresh ptab's physical address +; +; fresh ptab is all 0 +; corresponding chapter entries are 0 +; pdir link set +; ptab marked present, write permitted +; ptab marked user permitted iff pdir entry corresponds to user space +; +; +; C: EAX scratch +; +; no fresh ptab available +; +; +;---------------------------------------------------------------------------- + + + + +map_fresh_ptab: + + + push ebx + + push linear_kernel_space + pop es + + push edx + lno___prc edx + + + mov ebx,ecx + and ebx,pagesize-1 + + CORB ebx, + IFAE ebx,<(shared_table_base+shared_table_size) SHR 20> + + lea eax,[ecx-PM] + sub eax,ebx + cmp eax,ds:[empty_proot+8*edx-8] + xc z,generate_own_pdir + FI + + IFB_ ebx, + + call request_fresh_ptab + jc short map_ptab_exit + mov al,page_present+page_write_permit+page_user_permit + + ELSE_ + + call request_fresh_frame ; kernel ptabs don't (!) get + jc short map_ptab_exit ; associated chapter maps !! + mov al,page_present+page_write_permit + + IFAE ebx, + CANDB ebx,<(shared_table_base+shared_table_size) SHR 20> + + add ebx,ds:[kernel_proot+8*edx-8] ; ptab inserted into kernel + mov dword ptr [ebx+PM],eax ; *and empty* proot ! + and ebx,pagesize-1 ; Sharing ptabs ensures that later + add ebx,ds:[empty_proot+8*edx-8] ; mapped pages (tcbs) are shared + mov dword ptr [ebx+PM],eax ; automatically. This is required + FI ; to permit switching to empty space !! + FI + + mov [ecx],eax + + shr eax,log2_pagesize + IFAE esp, + CANDB esp, + mov [(eax*4)+ptab_backlink],ecx + FI + shl eax,log2_pagesize + ; NC ! + + +map_ptab_exit: + + pop edx + pop ebx + ret + + + + +XHEAD generate_own_pdir + + call request_fresh_ptab ; new pdir for task, copy of empty + jc map_ptab_exit + + and ecx,pagesize-1 + lea ecx,[eax+ecx+PM] + + push ecx + call init_pdir + push edx + lno___task edx + chnge_proot eax,edx + pop edx + ; load page directory address of task + lea___pdir eax,edx + lno___prc ecx + dec ecx + shl ecx,log2_pagesize + add eax,ecx + + call flush_system_shared_page + pop ecx + + xret ,long + + + + +;############################################################################################### + + + +;---------------------------------------------------------------------------- +; +; init pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX phys addr of pdir, must be all 0 ! +; +;---------------------------------------------------------------------------- + + + +init_pdir: + + push ecx + push esi + push edi + + lno___prc esi + mov esi,ds:[empty_proot+8*esi-8] ; 1. shared tables taken from nil proot + lea esi,[esi+PM+(shared_table_base SHR 20)] ; 2. small ptab link reset + lea edi,[eax+PM+(shared_table_base SHR 20)] ; + mov ecx,(pagesize-(shared_table_base SHR 20))/4 ; ATTENTION: + cld ; chapters not marked !! + rep movsd ; (not necessary, better efficiency) + +;;sub ecx,ecx ; Remember: even nil proot may have +;;mov [eax+(com0_base SHR 20)+PM],ecx ; temporal com ptab links +;;mov [eax+(com1_base SHR 20)+PM],ecx ; + + ; Attention: pdir mapped as page into itself for fast access. + mov ecx,eax + mov cl,page_present+page_write_permit + mov dword ptr [eax+(offset ptab_space SHR 20)+PM],ecx + + pop edi + pop esi + pop ecx + ret + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PTAB Manager Thread ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + log2 <%physical_kernel_mem_size> + + +;---------------------------------------------------------------------------- +; +; ptabman int called before (!) booter is started +; +;---------------------------------------------------------------------------- + + +ptabman_init: + + ; store current segments (data, extra) + push ds + push es + + ; while s0 does not answer + DO + ; call sigma0 for pages for kernel use + sub ecx,ecx ; timeouts 0 + mov eax,ecx ; register send + mov ebp,ecx ; register receive + lea edx,[ecx+1] ; w0 = 00000001 + mov ebx,ecx ; w1 = 00000000 + mov esi,sigma0_task ; dest = sigma0 + + ke 'before ipc to s0' + + int ipc + ; repeat the loop if error occured in IPC or Sigma 0 answered with mapping (wrong answer to protocol) + test al,ipc_error_mask + CORNZ + test al,map_msg + IFNZ + sub esi,esi + + ; switch to any thread and repeat the loop next time + int thread_switch + REPEAT + FI + OD + + pop es + pop ds + + ; sigma 0 answered with available kernel pages = k in edx + ; for all available kernel pages k + DO + push edx + + ; send ipc to sigma0 + sub ecx,ecx ; timeout 0 + mov eax,ecx ; register IPC only + lea ebp,[ecx+(log2_)*4+map_msg] ; rcv mapping to 0 of size ??? + lea edx,[ecx-2] ; w0 = FFFFFFFE request a grant of any page + mov esi,sigma0_task ; dest = sigma0 + + push ds + push es + int ipc + pop es + pop ds + + ; if map message received and 1 page was granted + IFZ al,map_msg + CANDZ bl,(log2_pagesize*4+fpage_grant) + ; and fpage_base == send_fpage + xor ebx,edx + and ebx,-pagesize + CANDZ + ; insert fpage into fresh frame pool + mov eax,edx + call insert_into_fresh_frame_pool + ELSE_ + ; sigma0 message failed. + ke 'ill_s0_msg' + FI + + pop edx + dec edx + REPEATNZ + OD + + ret + + + + +;---------------------------------------------------------------------------- +; +; ptabman thread continued after (!) booter started +; +;---------------------------------------------------------------------------- + + + +ptabman_start: + + DO + ; wait, open receiving for any ipc, but do not reply + sub ecx,ecx ; timeout 0 + lea eax,[ecx-1] ; no send + mov ebp,ecx ; wait for register receive + sub esi,esi ; dest = nil thread + sub edi,edi ; receive from anyone + int ipc ; send ipc + REPEAT + OD + + + + +;################################################################################################ + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** map/flush special pages ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; flush system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NZ: was present +; +; EAX phys addr + access attributes +; +; Z: was not present +; +; EAX scratch +; +; +; flushed in all tasks +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; flushing in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +flush_system_shared_page: + + + push ebx + push ecx + + lno___prc ebx + mov ebx,ds:[kernel_proot+8*ebx-8] + xpdir ecx,eax + mov ebx,dword ptr [(ecx*4)+ebx+PM] + test bl,page_present + IFNZ + and ebx,-pagesize ; Note: Since ptab is shared + xptab ecx,eax ; between all pdirs (even empty), + ; page is flushed in the universe + invlpg [eax] + + sub eax,eax + xchg eax,dword ptr [(ecx*4)+ebx+PM] + + test eax,eax + FI + + pop ecx + pop ebx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; map system shared page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical addr (only bits 12...31 relevant) +; ESI virtual addr within system shared area ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: mapped (present, read/write, supervisor) in kernel space +; +; C: required ptab unavailable, not mapped +; +;---------------------------------------------------------------------------- +; Remark: Since the ptabs of all system shared areas are shared itself, +; mapping in kernel address space (reached by kernel_proot) is +; sufficient. +; +;---------------------------------------------------------------------------- + + + + +map_system_shared_page: + + push eax + push ecx + push edx + + mov edx,eax + + lno___prc ecx + mov ecx,ds:[kernel_proot+8*ecx-8] + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,kernel_task + call map_fresh_ptab ; Note: new ptab with system + pop edx + IFC ; shared area will be shared + ke 'syspt_unav' ; between *all* address spaces + + pop edx + pop ecx + pop eax + ret ; C ! + FI + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + mov dl,page_present+page_write_permit + mov [ecx],edx + + pop edx + pop ecx + pop eax + clc ; NC ! + ret + + +;---------------------------------------------------------------------------- +; +; gen kernel including new address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; begin of data+code area +; end of data+code area +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX physical address of new pdir +; +; new pdir is a copy (!) of empty pdir, complemented +; by a new ptab (0..4M), which is a copy (!) of the kernel's +; 0..4M ptab. +; +;---------------------------------------------------------------------------- + + icode + + +gen_kernel_including_address_space: + + push ecx + push edx + push esi + push edi + + call request_fresh_ptab + + mov edx,eax + + mov edi,PM + lno___prc esi + lea esi,ds:[kernel_proot+8*esi-8] + mov esi,[esi] + and esi,-pagesize + mov esi,[esi+edi] + and esi,-pagesize + add esi,edi + add edi,eax + + mov eax,[ebx].ktask_begin + shr eax,log2_pagesize + lea edi,[eax*4+edi] + lea esi,[eax*4+esi] + + mov ecx,[ebx].ktask_end + IFA ecx, + mov ecx,offset max_kernel_end + FI + add ecx,pagesize-1 + shr ecx,log2_pagesize + sub ecx,eax + + IFA + DO + mov eax,[esi] + mov [edi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + FI + + call request_fresh_ptab + + call init_pdir + + lea ecx,[edx+page_present+page_write_permit+page_user_permit] + lea edi,[eax+PM] + mov [edi],ecx + + shr ecx,log2_pagesize + mov [ecx*4+ptab_backlink],edi + + pop edi + pop esi + pop edx + pop ecx + ret + + + + + + + icod ends + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/SGMCTR.asm b/l4-x86/smp/lx/kern/SGMCTR.asm new file mode 100644 index 0000000..949f6b9 --- /dev/null +++ b/l4-x86/smp/lx/kern/SGMCTR.asm @@ -0,0 +1,287 @@ +include l4pre.inc + + Copyright IBM, L4.SGMCTR, 03,09,97, 19 + + +;********************************************************************* +;****** ****** +;****** Segment Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 03.09.97 ****** +;****** ****** +;********************************************************************* + + public init_sgmctr + public ltr_pnr + + public gdt_vec + public tss_vec + + extrn physical_kernel_info_page:dword + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include descript.inc +include kpage.inc +.list +include apstrtup.inc + + +ok_for x86 + +;**************************************************************************** +;****** ******* +;****** ******* +;****** Segment Controller Initialization ******* +;****** ******* +;****** ******* +;**************************************************************************** + + + +;----------------------------------------------------------------------- +; +; init segment controller +; +;----------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; paging enabled, adrspace established +; +; disable interrupt +; +; DS : R/W 0..4GB +; SS : R/W 0..4GB +; CS : X/R 0..4GB, USE32 +; +;----------------------------------------------------------------------- +; POSTCONDITION: +; +; GDT initialized +; GDTR initialized +; +; LDTR initialized +; +; CS phys_mem_exec +; DS linear_space +; ES linear_space +; FS linear_space +; GS linear_space +; SS linear_space +; +; EAX...EBP scratch +; +;---------------------------------------------------------------------- + + + assume ds:codseg + + icode + + + +init_sgmctr: + + mov eax,ds + mov es,eax + + ; delete space for gdt in linear adress space + mov edi,offset gdt + first_kernel_sgm + mov ecx,(sizeof gdt - first_kernel_sgm)/4 + sub eax,eax + cld + rep stosd + + ; copy initial GDT into GDT space + + mov edi,offset gdt + first_kernel_sgm + mov esi,offset initial_gdt+8 + mov ecx,(offset end_of_initial_gdt - (offset initial_gdt+8) +3) / 4 + rep movsd + + ; load GDT + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6,phys_mem_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + lea esp,[esp+PM] + + sub eax,eax + lldt ax + ret + + +;---------------------------------------------------------------------- +; Load Task Register with Processor Number +;---------------------------------------------------------------------- +; PRECONDITION: protected mode +; cs points to code segment +; ds points to data segment +; POSTCONDITION: segment registers reloaded +; tr loaded +; registers scratch +;---------------------------------------------------------------------- + + +ltr_pnr: + ; store current segment registers and gdt + + mov [tss_old_cs],cs + mov [tss_old_ds],ds + mov [tss_old_es],es + mov [tss_old_fs],fs + mov [tss_old_gs],gs + mov [tss_old_ss],ss + + sgdt fword ptr ds:[tss_old_gdt_vec] + + ; create temporary GDT for loading processor number into TR + + mov edi,offset tss_gdt + sub eax,eax + stosd + stosd + + ; use one task descriptor for each processor + + mov ecx, (1 SHL max_cpu) + tss_loop: + mov esi,offset desc_tss0 + movsd + movsd + loop tss_loop + + ; we need two additional descriptors for physical memory and linear kernel space + ; one is loaded into CS for execution, the other one is used to locate the final + ; descriptor table + ; use segments of cs and ds for code and data descriptors + + + mov eax,offset tss_old_gdt_ofs + + mov esi,cs + add esi,[tss_old_gdt_ofs] + movsd + movsd + mov esi,ds + add esi,[tss_old_gdt_ofs] + movsd + movsd + + aquire_new_processor_number ebx + + mov edx, offset tss_gdt + + lgdt fword ptr ds:[tss_vec] + jmpf32 $+6,((1 SHL max_cpu)+1)*8 + mov eax,((1 SHL max_cpu)+2)*8 + mov ds,eax + mov es,eax + shl ebx,3 + ltr bx + + ; reload old GDT + + lgdt fword ptr ds:[tss_old_gdt_vec] + + db 0EAh + dd $+6 + tss_old_cs dw 0 + + mov eax,linear_kernel_space + mov ds,[tss_old_ds] + mov es,[tss_old_es] + mov fs,[tss_old_fs] + mov gs,[tss_old_gs] + mov ss,[tss_old_ss] + +ret + +; temporary space for gdt and other segments +tss_old_gdt_vec dw 0 +tss_old_gdt_ofs dd 0 + +tss_old_ds dw 0 +tss_old_es dw 0 +tss_old_fs dw 0 +tss_old_gs dw 0 +tss_old_ss dw 0 + + +; special GDT with a list of task state segments +; used to load TR with processor number + + align 4 + +tss_vec dw 24+(1 SHL max_cpu)*8 + dd offset tss_gdt + + align 4 + +tss_gdt dd (((1 SHL max_cpu)+3)*2) dup (?) + +gdt_vec dw sizeof gdt-1 + dd offset gdt + + align 4 + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + +.errnz virtual_space_size AND (MB4-1) + +.xall + +initial_gdt dd 0,0 ; dummy seg + +desc_lksp: descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + +desc_phex: descriptor xr32, dpl0, PM, ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + +desc_tss0: descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + tss_ldt_base equ offset tss_ldt + tss_ldt_size equ 9*8 + +; descriptor ldtseg, dpl0, tss_ldt_base, tss_ldt_size ; 40 : tss_ldt + descriptor ldtseg, dpl0, 0, 24 + +end_of_initial_gdt equ $ + + icod ends + + + code ends + end + + + + diff --git a/l4-x86/smp/lx/kern/SIGMA0.asm b/l4-x86/smp/lx/kern/SIGMA0.asm new file mode 100644 index 0000000..7c1a0e0 --- /dev/null +++ b/l4-x86/smp/lx/kern/SIGMA0.asm @@ -0,0 +1,769 @@ +include l4pre.inc + + scode + + Copyright IBM, L4.sigma0 , 12,12,97, 12 + + +;********************************************************************* +;****** ****** +;****** Sigma 0 (Initial Address Space) ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 12.12.97 ****** +;****** ****** +;********************************************************************* + + + + public default_sigma0_start + public default_sigma0_stack + public default_sigma0_stack2 + public default_sigma0_begin + public default_sigma0_end + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include syscalls.inc +include pagconst.inc +include l4kd.inc +include kpage.inc +.list + + + + + + align 16 + + + + + + + + align 16 + +default_sigma0_begin equ $ + + + dd 31 dup (0) +default_sigma0_stack dd 0 + dd 31 dup (0) +default_sigma0_stack2 dd 0 + + +sigma0_data struc + + kernel_info_addr dd 0 + recommended_kernel_pages dd 0 + + device_mem_begin dd 0 + + memmap_descriptor dd 0,0 + memmap_size dd 0 + + requestors dw 6 dup (0) + +sigma0_data ends + + + +free_mem equ 0 +dedicated_mem equ 80h +reserved_mem equ 0FFh + + + +;---------------------------------------------------------------------------- +; +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +default_sigma0_start: + + pop ebx + + sub esp,sizeof sigma0_data + mov ebp,esp + + mov [ebp+kernel_info_addr],ebx + + mov ecx,[ebx+main_mem].mem_end + add ecx,MB4-1 + and ecx,-MB4 + mov [ebp+device_mem_begin],ecx + + mov eax,[ebx+reserved_mem1].mem_begin + IF kernel_x2 + imul eax,3 + shr eax,1 + ENDIF + shr eax,log2_pagesize + add eax,MB4/pagesize-1 + shr eax,22-log2_pagesize + movzx ecx,[ebx].ptabs_per_4M + test ecx,ecx + IFZ + mov ecx,128 + FI + imul eax,ecx + + ;; shr eax,7+log2_pagesize + ;; shr eax,3+log2_pagesize + ;; shr eax,2+log2_pagesize + mov [ebp+recommended_kernel_pages],eax + + + call init_mem_maps + + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; pushad +; +; extrn ide_start:near +; extrn ide_stack:dword +; +; mov eax,(sigma0_disk_driver AND mask lthread_no) SHR lthread_no +; mov ecx,offset ide_stack +; mov edx,offset ide_start +; sub ebx,ebx +; sub ebp,ebp +; sub esi,esi +; sub edi,edi +; int lthread_ex_regs +; +; popad +; +; +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + + sub eax,eax + dec eax + + + DO + push ebp + mov ecx,10h + mov ebp,open_receive + int ipc + pop ebp + + push ds + pop es + + test al,ipc_error_mask + mov eax,-1 + REPEATNZ + + sub eax,eax + + and dl,NOT 10b + test dl,01b + IFZ + IFNZ edx,0FFFFFFFCh + + call grab_specific_page + jnz short reply_nak + + add___eax map_msg + REPEAT + + ELSE_ + call grab_free_default_page + jnz short reply_nak + + add___eax map_msg + + lno___task ecx,esi + cmp ecx,kernel_task_no + REPEATNZ + + add ebx,fpage_grant - fpage_map_read_write + REPEAT + FI + FI + + IFZ bl,0 + mov edx,[ebp+recommended_kernel_pages] + REPEAT + FI + + IFZ bl,1 + mov ebx,[ebp+kernel_info_addr] + add ebx,log2_pagesize*4 + fpage_map_read_only + mov edx,ebx ;;;;;;;;;;;; + add___eax map_msg + REPEAT + FI + + IFZ bl,22*4 + + call grab_specific_4M_or_4K_page + jnz short reply_nak + + add___eax map_msg + REPEAT + FI + + + reply_nak: + + test ebx,ebx + IFNZ + ke <0E5h,'0_ill_rpc'> + FI + sub edx,edx + sub eax,eax + REPEAT + OD + + +;---------------------------------------------------------------------------- +; +; grab free default page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EDX grabbed page address +; EBX fpage (map_read_write) +; +; NZ: no more page available +; +;---------------------------------------------------------------------------- + + + +grab_free_default_page: + + push eax + push ecx + push edi + + call identify_requestor + + IFZ + mov edi,[ebp+memmap_descriptor].mem_begin + mov ecx,[ebp+memmap_size] + add edi,ecx + dec edi + + mov al,free_mem + test esp,esp + std + repne scasb + + IFZ + inc edi + mov edx,edi + or [edi],ah + sub edx,[ebp+memmap_descriptor].mem_begin + shl edx,log2_pagesize + + mov ebx,edx + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax + FI + FI + + pop edi + pop ecx + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; grab specific page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDX page address +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: EBX grabbed fpage (map_read_write) +; +; NZ: page not available +; +;---------------------------------------------------------------------------- + + +grab_specific_4M_or_4K_page: + + push eax + push ecx + push edi + + mov edi,edx + and edi,-MB4 + shr edi,log2_pagesize + + mov ecx,[ebp+memmap_size] + sub ecx,edi + + IFAE ecx,MB4/pagesize + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov ecx,MB4/pagesize + DO + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + inc edi + dec ecx + REPEATNZ + FI + OD + + CANDZ + + mov ecx,MB4/pagesize + sub edi,ecx + mov al,ah + cld + rep stosb + + mov ebx,edx + and ebx,-MB4 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop ecx + pop eax + ret + FI + + pop edi + pop ecx + pop eax + + + + + + +grab_specific_page: + + + IFAE edx,[ebp+device_mem_begin] ;;;;;; GB1 + CANDB edx,3*GB1 + + mov ebx,edx + and ebx,-1 SHL 22 + mov bl,22*4 + fpage_map_read_write + + cmp eax,eax + ret + FI + + + push eax + push edi + + mov edi,edx + shr edi,log2_pagesize + + IFB_ edi,[ebp+memmap_size] + + call identify_requestor + + CANDZ + + add edi,[ebp+memmap_descriptor].mem_begin + + add ah,free_mem + mov al,[edi] + CORZ al,dedicated_mem + CORZ al,ah + IFZ al,free_mem + mov [edi],ah + + mov ebx,edx + and ebx,-pagesize + mov bl,log2_pagesize*4 + fpage_map_read_write + + cmp eax,eax ; Z ! + pop edi + pop eax + ret + FI + FI + + test esp,esp ; NZ ! + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; identify_requestor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI requester id low +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: AH requestor no +; NZ: too many requestors +; +;---------------------------------------------------------------------------- + + + +identify_requestor: + + push ecx + push esi + push edi + + lno___task esi + + lea edi,[ebp+requestors] + mov ah,1 + DO + movzx ecx,word ptr [edi] + cmp ecx,esi + EXITZ + test ecx,ecx + EXITZ + + add edi,2 + inc ah + cmp ah,sizeof requestors/2 + REPEATBE + ; NZ ! + OD + IFZ + mov [edi],si + FI + + pop edi + pop esi + pop ecx + ret + +;---------------------------------------------------------------------------- +; +; init mem maps +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; memmap initialized +; +; REGs scratch +; +;---------------------------------------------------------------------------- + + + +init_mem_maps: + + mov edi,[ebp+kernel_info_addr] + + mov eax,[edi+reserved_mem1].mem_begin + mov [ebp+memmap_descriptor].mem_end,eax + + mov ecx,[edi+main_mem].mem_end + shr ecx,log2_pagesize + mov [ebp+memmap_size],ecx + + sub eax,ecx + and eax,-pagesize + mov [ebp+memmap_descriptor].mem_begin,eax + + lea esi,[edi+main_mem] + mov ebx,[esi].mem_begin + mov edx,[esi].mem_end + mov al,free_mem + mov ah,1 + call fill_mem_map + + lea esi,[ebp+memmap_descriptor] + mov al,reserved_mem + mov ah,1 + call fill_mem_map + + lea esi,[edi+reserved_mem0] + mov al,reserved_mem + mov ah,2 + call fill_mem_map + + lea esi,[edi+dedicated_mem0] + mov al,dedicated_mem + mov ah,5 + call fill_mem_map + + ret + + + + +fill_mem_map: + + push edi + DO + mov ecx,[esi].mem_end + IFA ecx,edx + mov ecx,edx + FI + mov edi,[esi].mem_begin + IFB_ edi,ebx + mov edi,ebx + FI + shr ecx,log2_pagesize + shr edi,log2_pagesize + sub ecx,edi + IFA + add edi,[ebp+memmap_descriptor].mem_begin + cld + rep stosb + FI + add esi,sizeof mem_descriptor + dec ah + REPEATNZ + OD + pop edi + ret + + + +;---------------------------------------------------------------------------- +; +; memory test +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX lower bound +; ECX upper bound +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z: no memory failure detected +; +; NZ: EAX address of detected failure +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + + +check_pass_string db sizeof check_pass_text +check_pass_text db 6,10,10,0E5h,'0 memory test ','0'-1,': pass X-X' + +check_no_offset equ (sizeof check_pass_text-11+1) +pass_type_offset equ (sizeof check_pass_text-3+1) +pass_no_offset equ (sizeof check_pass_text-1+1) + + + +memory_test: + + push ecx + push edx + push esi + push edi + + sub ecx,ebx + IFA ,,long + + inc ds:[check_pass_string+check_no_offset] + + mov eax,ecx + sub edx,edx + mov ecx,3*4*8 + div ecx + mov ecx,eax + mov dl,'1' + mov dh,dl + + DO + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+2*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+1*4] + call memtest_rd + EXITNZ + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_wr + + mov eax,055555555h + lea edi,[ebx+0*4] + call memtest_rd + EXITNZ + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_wr + + mov eax,0AAAAAAAAh + lea edi,[ebx+2*4] + call memtest_rd + OD + FI + + pop edi + pop esi + pop edx + pop ecx + ret + + +memtest_wr: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'W' + mov [eax++pass_no_offset],dl + kd____outstring + popad + inc dl + + mov esi,ecx + clign 16 + DO + mov [edi],eax + mov [edi+1*3*4],eax + mov [edi+2*3*4],eax + mov [edi+3*3*4],eax + mov [edi+4*3*4],eax + mov [edi+5*3*4],eax + mov [edi+6*3*4],eax + mov [edi+7*3*4],eax + + add edi,8*3*4 + dec esi + REPEATNZ + OD + ret + + + +memtest_rd: + + pushad + mov eax,offset check_pass_string + mov byte ptr [eax+pass_type_offset],'R' + mov [eax++pass_no_offset],dh + kd____outstring + popad + inc dh + + mov esi,ecx + clign 16 + DO + cmp [edi],eax + EXITNZ + cmp [edi+1*3*4],eax + EXITNZ + cmp [edi+2*3*4],eax + EXITNZ + cmp [edi+3*3*4],eax + EXITNZ + cmp [edi+4*3*4],eax + EXITNZ + cmp [edi+5*3*4],eax + EXITNZ + cmp [edi+6*3*4],eax + EXITNZ + cmp [edi+7*3*4],eax + EXITNZ + + add edi,8*3*4 + dec esi + REPEATNZ + + ret + OD + + mov eax,edi + ret + + +default_sigma0_end equ $ + + + scod ends + code ends + end diff --git a/l4-x86/smp/lx/kern/START.asm b/l4-x86/smp/lx/kern/START.asm new file mode 100644 index 0000000..4afe786 --- /dev/null +++ b/l4-x86/smp/lx/kern/START.asm @@ -0,0 +1,444 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.START, 8,12,99, 31 + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 8.12.99 ****** +;****** ****** +;********************************************************************* + + + public kernel_start + public kernel_start_x2 + + extrn init_default_kdebug:near,default_kdebug_exception:near + extrn default_kdebug_end:byte + extrn default_sigma0_stack:dword,default_sigma0_start:near + extrn default_sigma0_begin:byte,default_sigma0_end:byte + extrn ktest0_stack:dword,ktest0_start:near + extrn ktest1_stack:dword,ktest1_start:near + extrn ktest_begin:byte,ktest_end:byte + extrn labseg_start:byte + extrn kernelstring:byte + extrn kernelver:abs + extrn physical_kernel_info_page:dword + + + extrn determine_processor_type:near + extrn init_memctr:near + extrn ltr_pnr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_pagmap:near + extrn init_fresh_frame_pool:near + extrn init_pagfault:near + extrn init_schedcb:near + extrn init_cpuctr:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_ipcman:near + extrn init_adrsman:near + extrn init_emuctr:near + extrn init_basic_hw_interrupts:near + extrn init_rtc_timer:near + extrn init_sigma0_1:near + extrn start_dispatch:near + extrn ptabman_init:near + extrn ptabman_start:near + extrn create_kernel_including_task:near + extrn kcod_start:near + extrn init_apic:near + extrn init_small_address_spaces:near + extrn create_kernel_thread:near + + extrn determine_mp_system_type:near + extrn startup_ap:near + extrn synch_all:near + extrn release_all:near + +.nolist +include l4const.inc +include l4kd.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include syscalls.inc +include kpage.inc +include apic.inc +include descript.inc +.list + + +include apstrtup.inc + + + +ok_for x86 + + + + + + +;********************************************************************* +;****** ****** +;****** System Start ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + strtseg + + +;---------------------------------------------------------------------------- +; +; link table +; +;---------------------------------------------------------------------------- +; +; In the strt segment, *only* the start code of +; module start.pc is located before this table. +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 1008 so that the following table is placed +; exactly at location 1008h. +; +;---------------------------------------------------------------------------- + + db 0 + db current_kpage_version + db 0,0 + IF kernel_x2 + dd dual_link_table + ELSE + dd 0 + ENDIF + + dd init_default_kdebug,default_kdebug_exception ; 1010 ; kdebug + dd 0,default_kdebug_end + + dd default_sigma0_stack,default_sigma0_start ; 1020 ; sigma0 ESP, EIP + dd default_sigma0_begin,default_sigma0_end + + dd ktest1_stack,ktest1_start ; 1030 ; sigma1 ESP, EIP + dd ktest_begin,ktest_end + + dd ktest0_stack,ktest0_start ; 1040 ; booter ESP, EIP + dd ktest_begin,ktest_end + + dd 0 ; default pnodes and ptabs ; 1050 ; configuration ... + dd 0 + dd 00010108h ; no remote, 115 Kbd, start ke, 32 K trace buffer + dd 00003F00h ; all tasks, max permissions + + dd 0,0 ; main_mem ; 1060 + dd 0,0 ; reserved_mem0 + + IF kernel_x2 + dd MB16,MB64 ; reserved_mem1 ; 1070 + ELSE + dd 0,0 ; reserved_mem1 ; 1070 + ENDIF + + dd 0,0 ; dedicated_mem0 + + IF kernel_x2 + dd MB16,MB64 + ELSE + dd 0,0 ; dedicated_mem1 ; 1080 + ENDIF + + dd 0,0 ; dedicated_mem2 + + dd 0,0 ; dedicated_mem3 ; 1090 + dd 0,0 ; dedicated_mem4 +;; dd 32*MB1,GB1 ; speacial for broken PCS 320 !!!!!!!!!!!!!!! + + dd 0,0,0,0 ; 10A0 ; user clock + + dd 0,0,0,0 ; 10B0 ; clock freqencies + + dd 0,0,0,0 ; 10C0 ; boot mem, alias, ebx + + dd mpfloatstruc ; 10D0 + dd mpconftbl + dd 0 + dd proc_data + + db numb_proc ; 10E0 + db prc_sema + db prc_release + db 0 + dd 0,0,0 + + strt ends + + + + +;--------------------------------------------------------------------- +; +; system start +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; CS executable & readable segment, starting at 0, size 4G +; USE32 +; DS readable & writable segment, starting at 0, size 4G +; +; interrupts disabled +; +;--------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +kernel_start: + + mov eax,ds + mov es,eax + mov ss,eax + + sub eax,eax + mov fs,eax + mov gs,eax + + + IF kernel_x2 + call prepare_dual_processor_init + ENDIF + + + mov edi,offset physical_kernel_info_page + + mov [edi+LN_magic_word],4BE6344Ch ; 'L4',0E6h,'K' + mov [edi+LN_version_word],kernelver + + mov [edi+kpage_version],current_kpage_version + + mov eax,offset labseg_start + sub eax,edi + shr eax,4 + mov [edi+LN_label_link],al + + IF kernel_x2 + ELSE + sub eax,eax + mov [edi+next_kpage_link],eax + ENDIF + +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +; +; extrn ide_begin:byte,ide_end:byte +; +; IFA [edi+sigma0_ktask].ktask_begin, +; mov [edi+sigma0_ktask].ktask_begin,offset ide_begin +; FI +; IFB_ [edi+sigma0_ktask].ktask_end, +; mov [edi+sigma0_ktask].ktask_end,offset ide_end +; FI +; +;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + + + +kernel_start_x2: + + call determine_processor_type + + call init_memctr + call dword ptr cs:[physical_kernel_info_page+init_kdebug] + + call determine_mp_system_type + + sub eax,eax + mov [physical_kernel_info_page+numb_proc],eax + + call ltr_pnr + + call enable_paging_mode + + call init_sgmctr + call init_intctr ; mp modification + call init_emuctr ; mp modification + + kd____clear_page + mov al,0 + mov ah,22 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10> + + + ;; end of really documented code + + call init_cpuctr ; xxx to be checked xxx + call init_pagfault ;on bootstrap only (defines idt gate for pf handler) + + call init_pagmap + + ke 'before startup' + + ;; prepare semaphor + sub eax,eax + mov ds:[logical_info_page+prc_sema],al + mov ds:[logical_info_page+prc_release],al + + + call startup_ap + + ;; sync + call synch_all ; determine how much are really ok and seperate incorrect processors from system + ;; postcondition bootstrap is running only + call init_fresh_frame_pool ; grabs all remaining frames (on bootstrap only) + + call release_all + + call init_schedcb ; run on each proc + call init_tcbman ; starts kbooter and dispatcher thread on each processor + call init_dispatcher ; initialises dispatcher control block + + call init_ipcman ; on bootstrap only + + ;; point on dual + + call init_adrsman + call init_small_address_spaces + call init_basic_hw_interrupts ;docu + + ke 'bis hier bin ich' + + bt ds:[cpu_feature_flags],on_chip_apic_bit + IFC + call init_apic + ELSE_ + call init_rtc_timer + FI + + +;; **************************************** +;; Dual startup: Temporarly coded Stuff +;; +;; **************************************** + + ke 'start new thread' + mov ebp, offset ktest1_tcb + mov ecx, offset dual_thread_test2 + call create_kernel_thread + + ke 'test started' + + jmp $ + + + + + + test ds:[physical_kernel_info_page].kdebug_startflags,startup_kdebug + IFNZ + ke 'debug' + FI + + cli + + call init_sigma0_1 + + call ptabman_init + + mov eax,booter_task + mov ebx,offset booter_ktask+offset logical_info_page + call create_kernel_including_task + +; mov eax,(5 SHL task_no+1+5 SHL chief_no) +; mov ebx,offset cpu1task +; call create_kernel_including_task + + IFZ ds:[logical_info_page+booter_ktask].ktask_start, + mov eax,sigma1_task + mov ebx,offset sigma1_ktask+offset logical_info_page + CANDNZ <[ebx].ktask_stack>,0 + call create_kernel_including_task + FI + + + IF kernel_x2 + + extrn p6_workaround_init:near + call p6_workaround_init + + ENDIF + + jmp ptabman_start + +cpu1task dd cpu1task_stack,ktest0_start + dd ktest_begin,ktest_end + + align 16 + + dd 31 dup (0) +cpu1task_stack dd 0 + +dual_thread_test2: + + ke 'enter receive' + sub ecx,ecx ; timeout infinity + mov eax,-1 ; no send + mov ebp,1 ; receive registers only from anyone + int 30h + +jmp dual_thread_test2 + + + icod ends + + + + code ends + end + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/STARTPC.asm b/l4-x86/smp/lx/kern/STARTPC.asm new file mode 100644 index 0000000..0b69342 --- /dev/null +++ b/l4-x86/smp/lx/kern/STARTPC.asm @@ -0,0 +1,1402 @@ +include l4pre.inc + + + + + Copyright IBM, L4.START.PC, 26,06,98, 47 + +;********************************************************************* +;****** ****** +;****** LN START.PC ****** +;****** ****** +;****** ****** +;****** Jochen Liedtke ****** +;****** ****** +;****** modified: 26.06.98 ****** +;****** ****** +;********************************************************************* + + public init_basic_hw_interrupts + public init_rtc_timer + public wait_for_one_second_tick + public mask_hw_interrupt + public reset + public memory_failure + public irq0 + public irq15 + public irq0_intr + public irq8_intr + public physical_kernel_info_page + + extrn kernel_start:near + extrn kernelver:abs + extrn rtc_timer_int:near + extrn init_intr_control_block:near + extrn init_sgmctr:near + extrn max_kernel_end:near + + extrn exception:near + extrn define_idt_gate:near + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include intrifc.inc +include syscalls.inc +include kpage.inc +include cpucb.inc +.list + +include l4kd.inc + + +ok_for x86 + + + + +;---------------------------------------------------------------------------- +; +; start jump and jump at 100h +; +;---------------------------------------------------------------------------- +; +; Start.pc *MUST* ensure that it occupies position +; 0 ... 100X ( 0 < X < 10h ) so that the following +; table is placed at location 1010h (becaus 16-byte align). +; +;---------------------------------------------------------------------------- + + +start_offset equ 1000h ; preserves ROM BIOS area + + + +physical_kernel_info_page equ start_offset + + + + + strtseg + + + + + dd 0 ; kernel length (dwords) + dd 0 ; checksum + dd kernelver + + org 100h + + +start100: + + jmp start+2 + + + org start_offset-4 + + +bootstack dd 0 + + + + + + +start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2 + + jmp start_start+2 ; 32-bit jmp, as well executable as 16-bit jmp !! + + + nop + + ; start seg here ends at address 0x1008 . This is + ; inportant for proper link table begin in start.asm! + strt ends + + + + + align 4 + + + +;---------------------------------------------------------------------------- +; +; Port Addresses +; +;---------------------------------------------------------------------------- + + +sys_port_a equ 92h +sys_port_b equ 61h + +paritychk_signal_bit equ 7 +iochk_disable_bit equ 3 +iochk_signal_bit equ 6 + + + +kb_status equ 64h +kb_cntl equ 64h +kb_data equ 60h + +rtc_address equ 70h +rtc_data equ 71h +rtc_seconds equ 00h +rtc_minutes equ 02h +rtc_hour equ 04h +rtc_day equ 07h +rtc_month equ 08h +rtc_year equ 09h +rtc_reg_a equ 0Ah +rtc_reg_b equ 0Bh +rtc_reg_c equ 0Ch +rtc_century equ 32h +rtc_century_ps2 equ 37h + + +pic1_icw1 equ 20h +pic1_icw2 equ 21h +pic1_icw3 equ 21h +pic1_icw4 equ 21h +pic1_isr_irr equ 20h +pic1_imr equ 21h + +pic1_ocw1 equ 21h +pic1_ocw2 equ 20h +pic1_ocw3 equ 20h + +pic2_icw1 equ 0A0h +pic2_icw2 equ 0A1h +pic2_icw3 equ 0A1h +pic2_icw4 equ 0A1h + +pic2_ocw1 equ 0A1h +pic2_ocw2 equ 0A0h +pic2_ocw3 equ 0A0h +pic2_isr_irr equ 0A0h +pic2_imr equ 0A1h + + +seoi equ 60h + +read_irr equ 1010b +read_isr equ 1011b + + +drive_control equ 3F2h + + +irq0 equ 0h +irq15 equ 0Fh + +irq0_intr equ 20h +irq7_intr equ 27h +irq8_intr equ 28h +irq15_intr equ 2Fh + + + +seoi_master equ (seoi + 2) +seoi_rtc equ (seoi + 8 - 8) +seoi_co287 equ (seoi +13 - 8) + +;C01 ms rtc macros moved up, for use in nmi enabling/disabling +; from here to end here to this place moved + + +inrtc macro rtcport + +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +in al,rtc_data +endm + + +outrt macro rtcport + +push eax +mov al,rtcport +out rtc_address,al +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +jmp $+2 +pop eax +out rtc_data,al +endm + +; end here + + + + +;------------------------------------------------------------------------- +; +; memory +; +;------------------------------------------------------------------------- + + + + + + align 4 + + + + + + icode16 + +multiboot_info_area struc + + mbi_flags dd 0 + mbi_mem_low dd 0 + mbi_mem_high dd 0 + +multiboot_info_area ends + + + +emulated_info_area multiboot_info_area <1,0,0> + + + align 16 + +initial_gdt dd 0,0 + +initial_gdt_descr dw 47h ; gdt +initial_gdt_base_low dw initial_gdt +initial_gdt_base_high db 0 + db 92h + db 0 + db 0 + +initial_idt_descr dw 9*8-1 ; idt +initial_idt_base_low dw initial_idt +initial_idt_base_high db 0 + db 92h + db 0 + db 0 + +initial_ds_descr dw 0FFFFh ; ds + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; es + dw 0 + db 0 + db 092h + db 0CFh + db 0 + + dw 0FFFFh ; ss +initial_ss_base_low dw 0 +initial_ss_base_high db 0 + db 092h + db 0CFh + db 0 + +initial_cs_descr dw 0FFFFh ; cs +initial_cs_base_low dw 0 +initial_cs_base_high db 0 + db 09Ah + db 0CFh + db 0 + + dd 0,0 + +initial_tss_descr dw 67h + dw 0 + db 0 + db 89h + dw 0 + + +initial_ds equ (offset initial_ds_descr-offset initial_gdt) +initial_cs equ (offset initial_cs_descr-offset initial_gdt) +initial_tss equ (offset initial_tss_descr-offset initial_gdt) + + + +initial_idt dw lowword offset ke_,6*8,8E00h,0 ; DIV0 + dw lowword offset ke_,6*8,8E00h,0 ; DB + dw lowword offset ke_,6*8,8E00h,0 ; NMI + dw lowword offset ke_,6*8,8E00h,0 ; INT 3 + dw lowword offset ke_,6*8,8E00h,0 ; OV + dw lowword offset ke_,6*8,8E00h,0 ; BD + dw lowword offset ke_,6*8,8E00h,0 ; UD + dw lowword offset ke_,6*8,8E00h,0 ; NA + dw lowword offset ke_,6*8,8E00h,0 ; DF + + + ic16 ends + + + +;--------------------------------------------------------------------- +; +; LN-Start +; +; precondition: +; +; real mode or 32-bit protected mode +; +;--------------------------------------------------------------------- + + + + + + icode + + + + +start_start: + + nop ; to permit real mode and PM mode + nop ; (in PM, will jump to start_start+2) + + cli + + ; if started in real mode + mov ecx,cr0 + test cl,01 + IFZ + ; executes in 16-bit mode ! + ; jump to real mode start + osp + mov eax,offset real_mode_start + asp + jmp eax + + FI + ; else jump to protected mode start + jmp protected_mode_start + + + + + + icod ends + + + + icode16 + + + assume ds:c16seg + + +real_mode_start: + + ; load cs = ds = es = 0..10000h + mov ax,cs + mov ds,ax + mov ss,ax + mov esp,offset bootstack + + + +;---------------------------------------------------------------------------- +; +; initializations depending on hardware type +; +;---------------------------------------------------------------------------- + + ; switch of ps/2 watchdog + mov ax,0C300h ; switch off PS/2 watchdog + int 15h ; + + + + + +;---------------------------------------------------------------------------- +; +; determine memory configuration +; +;---------------------------------------------------------------------------- + + ; read lower memory configuration from bios + int 12h ; area 1 (0...640K) + movzx eax,ax + mov [emulated_info_area].mbi_mem_low,eax + + ; read upper memory configuration from bios + mov ah,88h ; area 2 (1MB...) + int 15h + movzx eax,ax + IFAE eax,63*MB1/KB1 + mov eax,63*MB1/KB1 + FI + mov [emulated_info_area].mbi_mem_high,eax + + + + +;---------------------------------------------------------------------------- +; +; switch to protected mode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS = SS = CS +; +;---------------------------------------------------------------------------- + + + sub eax,eax + mov ax,ss + shl eax,4 + mov ebx,eax + shr ebx,16 + + ; setup protected mode gdt + add [initial_gdt_base_low],ax + adc [initial_gdt_base_high],bl + + ; setup protected mode idt + add [initial_idt_base_low],ax + adc [initial_idt_base_high],bl + + ; setup protected mode ss + mov [initial_ss_base_low],ax + mov [initial_ss_base_high],bl + + ; setup protected mode cs + mov [initial_cs_base_low],ax + mov [initial_cs_base_high],bl + + ; load data semgment with 0 + sub ax,ax + mov ds,ax + ; load extra segment to code segment + mov ax,cs + mov es,ax + ; load offset of initial gdt + mov si,offset initial_gdt + ; load irq0, 8 handlers + mov bh,irq0_intr + mov bl,irq8_intr + mov ah,89h + ; push far jump address of protected mode from real mode on stack + push 0 + push cs + push lowword offset protected_mode_from_real_mode + ; jump to pushed address + jmp dword ptr ds:[15h*4] + + + + + + ic16 ends + + + + + icode + + assume ds:codseg + + + + +protected_mode_from_real_mode: + + ; disable interrupts + cli + + ; load stack pointer + mov esp,offset bootstack + + ; reset nested task flag + pushfd + btr dword ptr ss:[esp],nt_flag + popfd + + ; load initial code segment base + mov ecx,dword ptr ss:[initial_cs_base_low] + and ecx,00FFFFFFh + + ; align initial code segment base + sub eax,eax + mov ss:[initial_cs_base_low],ax + mov ss:[initial_cs_base_high],al + + ; push eflags + far return address for iretd on stack + pushfd + push cs + lea eax,[ecx+offset protected_mode_0_based_cs] + push eax + iretd + + +protected_mode_0_based_cs: + + ; load ss, es with ds + mov edx,ds + mov ss,edx + mov es,edx + + ; load multiboot magic word, address of emulated info area + mov eax,2BADB002h + lea ebx,[ecx+emulated_info_area] + + + + +;---------------------------------------------------------------------------- +; +; PROTECTED MODE START +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX 2BADB002h (multiboot magic word) +; EBX pointing to boot info area: +; +; flags (flags[0] = 1) +; mem_lower (in K) +; mem_upper (in K) +; +; CS 0...4GB, 32-bit exec, CPL=0 +; DS,SS,ES 0...4GB, read_write +; +; protected mode enabled +; paging disabled +; interrupts disabled +; +;---------------------------------------------------------------------------- + + +protected_mode_start: + + ; hang if bap multiboot magic word + DO + cmp eax,2BADB002h + REPEATNZ + OD + + ; hang if first flag of the mbi_flags is not set + mov ecx,[ebx].mbi_flags + DO + test cl,01 + REPEATZ + OD + + ; load stack pointer + lea esp,[ebx+4] + call current_eip + current_eip: ; physical load address -> ecx + pop edx ; + sub edx,offset current_eip ; + + ; load memory begin low, memory end into physical kernel info page + mov eax,[ebx].mbi_mem_low + shl eax,10 + and eax,-pagesize + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_begin,eax + mov [edx+dedicated_mem0+physical_kernel_info_page].mem_end,MB1 + + ; load memory begin high, memory end into physical kernel info page + mov eax,[ebx].mbi_mem_high + shl eax,10 + add eax,MB1 + and eax,-pagesize + mov [edx+main_mem+physical_kernel_info_page].mem_begin,0 + mov [edx+main_mem+physical_kernel_info_page].mem_end,eax + + ; load start ebx in physical kernel info page + mov [edx+start_ebx+physical_kernel_info_page],ebx + + ; load aliased boot memory area in physical kernel info page + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_begin,offset start_offset + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,offset max_kernel_end + mov [edx+alias_base+physical_kernel_info_page],edx + IFB_ edx, + mov [edx+aliased_boot_mem+physical_kernel_info_page].mem_end,edx + mov [edx+alias_base+physical_kernel_info_page],offset max_kernel_end + FI + + + +;---------------------------------------------------------------------------- +; +; relocate to abs 800h +; +;---------------------------------------------------------------------------- +; +; ensures CS=0, offset addr = real addr +; +; +; Remark: If LN kernel is loaded by DOS, INT 13h vector will be +; reassigned by DOS. So the relocation must not happen +; before real_mode_init_hard_disk and real_mode_init_floppy_ +; disk, because the relocation overwrites the DOS area. +; The BIOS area (400h...4FFh) however is not damaged. +; +;---------------------------------------------------------------------------- + + + ; wait for hd and floppy turn of because int 13 location will be overwritten + inrtc 80h ;C01 ms + + + + + ; copy relocation code to 800h + mov edi,start_offset-(continue_after_relocation-relocate) + lea esi,[edx+relocate] + mov ecx,offset continue_after_relocation-relocate + cld + rep movsb + + + mov edi,start_offset + lea esi,[edi+edx] + mov ecx,offset max_kernel_end-start_offset + shr ecx,2 + + ; jump to relocate + mov eax,start_offset-(continue_after_relocation-relocate) + jmp eax + + +relocate: + ; mov kernel to start_offset + DO + mov eax,[esi] + xchg [edi],eax + mov [esi],eax + add esi,4 + add edi,4 + dec ecx + REPEATNZ + OD + + mov eax,offset continue_after_relocation + jmp eax + + +; mov edi,start_offset +; lea esi,[edi+ecx] +; mov ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; mov eax,offset reloc2 +; jmp eax +; +;reloc2: +; +; mov ecx,offset max_kernel_end +; sub ecx,offset continue_after_relocation-start_offset +; shr ecx,2 +; +; DO +; mov eax,[esi] +; xchg [edi],eax +; mov [esi],eax +; add esi,4 +; add edi,4 +; dec ecx +; REPEATNZ +; OD +; +; jmp $+2 ; flush prefetch que, because next code parts just moved +; ; to position 'continue_after_relocation' +; align 4 + + +continue_after_relocation: + + ; load initial gate descriptor table + mov eax,offset initial_gdt + mov ds:[initial_gdt_base_low],ax + shr eax,16 + mov ds:[initial_gdt_base_high],al + osp + lgdt fword ptr ds:[initial_gdt_descr] + + ; load initial interrupt descriptor table + mov eax,offset initial_idt + mov ds:[initial_idt_base_low],ax + shr eax,16 + mov ds:[initial_idt_base_high],al + osp + lidt fword ptr ds:[initial_idt_descr] + + ; load all segments to initial values + mov eax,initial_ds + mov ds,eax + mov es,eax + mov fs,eax + mov gs,eax + mov ss,eax + ; load stack pointer + mov esp,offset bootstack + + ; load inital tss + mov eax,initial_tss + ltr ax + + ; jump far (reload code segment) + jmpf32 cs_loaded,initial_cs + + +cs_loaded: + + +;---------------------------------------------------------------------------- +; +; prepare for shutdown desaster +; +;---------------------------------------------------------------------------- + + ; define shutdown handler + call define_shutdown_handler + + +;---------------------------------------------------------------------------- +; +; inhibit hardware interrupts (even when STI) +; +;---------------------------------------------------------------------------- +; Remark: Inhibiting the hardware interrupts independent from the processors +; interrupt enable flag is necessary, because STI may happen before +; all hardware drivers are installed. +; +;---------------------------------------------------------------------------- + ; inhibit hardware interrupts by masking them + mov al,11111111b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + +;---------------------------------------------------------------------------- +; +; deselect diskette and turn off motor +; +;---------------------------------------------------------------------------- + ; turn of disk motor + mov al,0 + mov dx,drive_control + out dx,al + + + + +;---------------------------------------------------------------------------- +; +; start LN +; +;---------------------------------------------------------------------------- + + + ; start kernel + jmp kernel_start + + + + +;---------------------------------------------------------------------------- +; +; LN BIOS initialization +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; +; LN kernel initialized +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + +init_basic_hw_interrupts: + + pushad + ; enable NMIs + inrtc 0 ; enable NMI !!! + + ; define 8259 base + call define_8259_base + ; initialise interrupt catcher + lno___prc eax + IFZ eax, 1 + call init_interrupt_catcher ; bootstrap only + FI + + ; initialise NMI handler + call init_nmi + + ; reserver irq 0 and 8 for kernel + mov eax,(1 SHL 0)+(1 SHL 8) ; reserve irq 0 + 8 for kernel + ; initialise interrupt control block + call init_intr_control_block + + popad + ret + + + icod ends + + + ;...Ž + + +;---------------------------------------------------------------------------- +; +; NMI handling +; +;---------------------------------------------------------------------------- + + + icode + + +init_nmi: + + lno___prc eax + IFZ eax,1 + ; define IDT gate for memory failure + mov bl,nmi + mov bh,0 SHL 5 + mov eax,offset memory_failure + call define_idt_gate + FI + + ; enable NMIs + inrtc 0 + + ; jump to memory failure if parity check signal bit or io check signal bit is turned on + in al,sys_port_b + test al,(1 SHL paritychk_signal_bit)+(1 SHL iochk_signal_bit) + jnz memory_failure + + ; disable io checking + and al,NOT (1 SHL iochk_disable_bit) + out sys_port_b,al + + ret + + + icod ends + + + + +memory_failure: + + ipre 0 + ; enter kernel debugger if a memory failure happend + ke '-NMI' + + + + + + +;--------------------------------------------------------------------------- +; +; define interrupt base of 8259 interrupt controllers +; +;--------------------------------------------------------------------------- + + icode + + +define_8259_base: + + push eax + pushfd + cli + + ; setup interrupt controller 8259 + mov al,11h + out pic1_icw1,al ; + mov al,irq0_intr ; + out pic1_icw2,al ; + mov al,04h ; + out pic1_icw3,al ; + mov al,11h ; important difference to AT: + out pic1_icw4,al ; special fully nested mode !! + mov al,0C1h ; prio := 8..15,3..7,0,1 + out pic1_ocw2,al ; + ; KB must have low prio because + ; intr may arrive during paging + ; of KB driver process !! + mov al,11h + out pic2_icw1,al + mov al,irq8_intr + out pic2_icw2,al + mov al,02h + out pic2_icw3,al + mov al,11h + out pic2_icw4,al + mov al,0C7h + IF kernel_x2 + mov al,0C5h ; xxxxxxxxxxxxxxxx + ENDIF + out pic2_ocw2,al + + + mov al,11111011b ; set IMRs + out pic1_imr,al ; + mov al,11111111b ; + out pic2_imr,al ; + + mov al,60h + out pic1_ocw2,al + + popfd + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; mask interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX intr no +; +;---------------------------------------------------------------------------- + + +mask_hw_interrupt: + + pushfd + cli + push eax + + ; if interrupt is hardware interrupt + IFB_ ecx,16 + + ; mask hardware interrupt + in al,pic2_ocw1 + mov ah,al + in al,pic1_ocw1 + + bts eax,ecx + + out pic1_ocw1,al + mov al,ah + out pic2_ocw1,al + FI + + pop eax + popfd ; Rem: change of NT impossible + ret + + + +;---------------------------------------------------------------------------- +; +; lost interrupt catcher (IRQ 7 and ISR bit 7 = 0) +; +;---------------------------------------------------------------------------- + + icode + + +init_interrupt_catcher: + + lno___prc eax + IFZ eax,1 + ; define IDT gate for lost interrupt catcher + mov bl,irq7_intr + mov bh,0 SHL 5 + mov eax,offset lost_interrupt_catcher + call define_idt_gate + FI + ret + + + icod ends + + +lost_interrupt_catcher: ; in the moment hardware IRQ 7 + ; is disabled + iretd + + + + + + + + +;---------------------------------------------------------------------------- +; +; rtc timer +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + + icode + + +init_rtc_timer: + ; define idt gate for rtc timer interrupt + lno___prc eax + IFZ eax,1 + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset rtc_timer_int + call define_idt_gate + FI + + ; wait for rtc to tick + DO + inrtc rtc_reg_a + bt eax,7 + REPEATC + OD + ; set clock to 512 Hz + and al,0F0h + add al,7 ; set to 512 Hz + outrt rtc_reg_a + + ; set rtc_reg_b + inrtc rtc_reg_b + or al,01001000b + outrt rtc_reg_b + + ; reset timer intr line + inrtc rtc_reg_c ; reset timer intr line + + ; enable timer interrupt + in al,pic2_imr + and al,11111110b + out pic2_imr,al + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; End Of System Run +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 : reset , no reboot +; <>0 : reset and reboot +; +; DS phys mem +; +; PL0 ! +; +;---------------------------------------------------------------------------- + + assume ds:codseg + +;####################################################### + +reset: + + mov edx,ecx + + cli + ; disable NMIs + inrtc 80h ; disable NMI + + ; disable all breakpoints + sub eax,eax + mov dr7,eax ; disable all breakpoints + + ; if paging enabled + mov eax,cr0 ; IF paging already on + bt eax,31 ; + IFC ; + ; load data segment with kernel space + mov ebx,linear_kernel_space ; + mov ds,ebx ; + FI ; + + + ; hang if edx = 0 + test edx,edx ; no reboot if edx = 0 + jz $ ; + + + ; REBOOT: + ; load eax with 0 / PM + sub eax,eax ; + IFA esp, ; + mov eax,PM ; + FI ; + ; inhibit memory test at reboot + mov word ptr ds:[eax+472h],1234h ; inhibit memory test at reboot + DO ; + ; wait 2nd bit set in keyboard status + in al,kb_status ; + test al,10b ; + REPEATNZ ; + OD ; + ; + ; cmos shutdown with boot loader request + mov al,0 ; cmos: shutdown with boot loader req + outrt 8Fh ; NMI disabled + ; + ; reset pulse command + mov al,0FEh ; reset pulse command + out kb_cntl,al ; + ; + ; hang and wait for reboot + jmp $ ; + + align 4 + +end_of_reset_routine: + + + + +;---------------------------------------------------------------------------- +; +; wait for one second tick +; +;---------------------------------------------------------------------------- + + icode + + + +wait_for_one_second_tick: + + push eax + + ; Select status register A from RTC + ; set tc to one second ticks + mov al,rtc_reg_a + out rtc_address,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + + ; Wait for UIP (update in progress) flag to disappear + + ; wait for update in progress flag to be set (1 tick) + DO + in al,rtc_data + and al,80h + REPEATNZ + OD + + ; Wait for UIP flag to appear again. This indicates + ; that a second has passed + + ; wait for next update in progress flag to be set (1 tick) + DO + in al,rtc_data + and al,80h + REPEATZ + OD + + pop eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; shutdown desaster +; +; +; called if 386 CPU shutdown occurrs +; +;---------------------------------------------------------------------------- + + + icode + + +define_shutdown_handler: + + ret + + + +; push eax +; +; mov dword ptr ds:[467h],offset shutdown_desaster ; cs = 0 ! +; +; mov al,5 +; outrt 0Fh +; +; pop eax +; ret + + icod ends + + + +; code16 +; +; +;shutdown_desaster: +; +; DO +; sub ax,ax +; mov ds,ax +; mov ss,ax +; mov esp,offset bootstack +; +; mov di,0B000h +; mov es,di +; mov di,0 +; mov al,'S' +; mov ah,0Fh +; mov es:[di],ax +; mov es:[di+8000h],ax +; +; mov [initial_gdt_base_low],offset initial_gdt +; mov [initial_gdt_base_high],0 +; mov [initial_idt_base_low],offset initial_idt +; mov [initial_idt_base_high],0 +; sub ax,ax +; mov [initial_ss_base_low],ax +; mov [initial_ss_base_high],al +; mov [initial_cs_base_low],ax +; mov [initial_cs_base_high],al +; mov es,ax +; mov si,offset initial_gdt +; mov bh,irq0_intr +; mov bl,irq8_intr +; mov ah,89h +; push 0 +; push cs +; push offset protected_mode_desaster +; jmp dword ptr ds:[15h*4] +; +; c16 ends +; +; +; +;protected_mode_desaster: +; +; DO +; ke 'desaster' +; REPEAT +; OD +; +;; int 19h +;; mov di,0B000h +;; mov es,di +;; mov di,2 +;; mov al,'S' +;; mov ah,0Fh +;; mov es:[di],ax +;; mov es:[di+8000h],ax +;; REPEAT +; OD +; + + + + + + +;---------------------------------------------------------------------------- +; +; ke_ provisional INT 3 entry before intctr initialized +; +;---------------------------------------------------------------------------- + + icode + + +ke_: + + ipre trap1,no_ds_load + + mov al,3 + + jmp cs:[kdebug_exception+physical_kernel_info_page] + + + icod ends + + + + + + + code ends + end start100 + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/kern/TABLES.asm b/l4-x86/smp/lx/kern/TABLES.asm new file mode 100644 index 0000000..93896a3 --- /dev/null +++ b/l4-x86/smp/lx/kern/TABLES.asm @@ -0,0 +1,20 @@ + +include l4pre.inc +include l4const.inc + +include uid.inc +page +include adrspace.inc +page +include tcb.inc +page +include schedcb.inc +page +include cpucb.inc +page +include pagconst.inc +page +include syscalls.inc + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/TCBMAN.asm b/l4-x86/smp/lx/kern/TCBMAN.asm new file mode 100644 index 0000000..38e02ee --- /dev/null +++ b/l4-x86/smp/lx/kern/TCBMAN.asm @@ -0,0 +1,871 @@ +include l4pre.inc + + + Copyright IBM, L4.TCBMAN, 16,03,99, 9141 + +;********************************************************************* +;****** ****** +;****** Thread Control Block Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 16.03.99 ****** +;****** ****** +;********************************************************************* + + + + public init_tcbman + public tcb_fault + public flush_tcb + public create_thread + public delete_thread + public shutdown_thread + public create_kernel_thread + + extrn ipcman_open_tcb:near + extrn ipcman_close_tcb:near + extrn cancel_if_within_ipc:near + extrn dispatcher_open_tcb:near + extrn dispatcher_close_tcb:near + extrn insert_into_ready_list:near + extrn insert_into_fresh_frame_pool:near + extrn detach_coprocessor:near + extrn dispatch:near + extrn refresh_reallocate:near + extrn map_system_shared_page:near + extrn flush_system_shared_page:near + extrn exception:near + extrn init_sndq:near + extrn define_idt_gate:near + extrn request_fresh_frame:near + extrn sigma_1_installed:byte + + +.nolist +include l4const.inc +.list +include uid.inc +.nolist +include adrspace.inc +.list +include tcb.inc +.nolist +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +.list + + +ok_for x86 + + + assume ds:codseg + + + + +;---------------------------------------------------------------------------- +; +; init tcb manager +; +;---------------------------------------------------------------------------- + + icode + + +init_tcbman: + + ; Set Interruptgate for l_thread_ex_regs + lno___prc eax + IFZ eax,1 + mov bh,3 SHL 5 + mov bl,lthread_ex_regs + mov eax,offset lthread_ex_regs_sc + call define_idt_gate + FI + + ; create dispatcher thread dispatcher thread per cpu + mov ebp,offset dispatcher_tcb + call create_kernel_thread + + ; create and start kernel booter thread + mov ebp,kbooter_tcb + call create_kernel_thread + + pop ebx + mov esp,[ebp+thread_esp] + + jmp ebx + + + icod ends + + +;###################################################################################### + +;---------------------------------------------------------------------------- +; +; tcb page fault handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX faulting address +; EDX = EAX +; +;---------------------------------------------------------------------------- + + +tcb_fault: + + + call request_fresh_frame + + IFC + ke 'tcb_fail' + FI + + mov esi,edx + call map_system_shared_page + + + mov ebp,esi + and ebp,-sizeof tcb + + lno___prc ebx + dec ebx + shl ebx,task_no + + add ebx,ebp + + CORB ebx,dispatcher_table ; (ebx = ebp) + IFAE ebx,dispatcher_table+dispatcher_table_size + + mov ebx,dword ptr [ebp+tcb_id] + test ebx,ebx + IFNZ + xor ebx,'BCT' + ror ebx,24 + CORB ebx,40h + IFA ebx,new_tcb_version + ke 'inv_tcb' + FI + FI + + mov al,[ebp+coarse_state] + test al,restarting + IFNZ + test al,ndead + CANDNZ + and [ebp+coarse_state],NOT restarting + FI + + + call open_tcb + + FI + + ipost + +;##################################################################################### + +;---------------------------------------------------------------------------- +; +; open thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write address +; +; DS,ES linear space +; +; tcb must have valid structure +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread opened (known to prc list, all physical refs updated) +; +;---------------------------------------------------------------------------- + + + + +open_tcb: + + ; if thread is not dead and is present + test [ebp+coarse_state],ndead ; concurrent mapping must + IFNZ ; not lead to multiple open, + test [ebp+list_state],is_present ; + CANDZ ; else polling threads would + ; load task number ; + lno___task edx,ebp ; be mult inserted into sndq + + ; open dispatcher tcb + call dispatcher_open_tcb + ; open ipcmanager tcb + call ipcman_open_tcb + FI + + ret + + +;############################################################################### + +;---------------------------------------------------------------------------- +; +; flush thread control block +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX tcb addr (lower bits ignored) +; DS linear space +; +; spv locked +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread closed (removed from prc list, all physical refs invalid) +; (numeric coprocessor detached, if necessary) +; +;---------------------------------------------------------------------------- + + + +flush_tcb: + + pushad + pushfd + cli + + and eax,-sizeof tcb + test__page_writable eax + IFNC + IFNZ [eax+coarse_state],unused_tcb + mov edx,esp + xor edx,eax + and edx,-sizeof tcb + IFZ + ke 'tcb_flush_err' + FI + test [eax+list_state],is_present + IFNZ + mov ebp,eax + call detach_coprocessor + call ipcman_close_tcb + call dispatcher_close_tcb + and [eax+list_state],NOT is_present + FI + FI + + call flush_system_shared_page + + FI + + popfd + popad + ret + +;########################################################################## + + + + +;---------------------------------------------------------------------------- +; +; lthread exchange registers system call +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; +; EAX lthread no +; ECX ESP / FFFFFFFF +; EDX EIP / FFFFFFFF +; EBX preempter / FFFFFFFF +; ESI pager / FFFFFFFF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; +; EAX EFLAGS +; ECX ESP +; EDX EIP +; EBX preempter +; ESI pager +; +;---------------------------------------------------------------------------- + + +lthread_ex_regs_sc: + + tpre trap2,ds,es + + ; load tcb of current thread + mov ebp,esp + and ebp,-sizeof tcb + + push eax + mov edi,eax + + ; set dest thread to ebp + shl eax,lthread_no + and eax,mask lthread_no + set___lthread ebp,eax + + ; if (actual processor == 0 (thread to be created)) or (on current processor) + push eax + lno___prc eax + CORZ [ebp+proc_id],0 + IFZ [ebp+proc_id],eax,long + pop eax + + ; if thread is dead + test [ebp+coarse_state],ndead + IFZ + pushad + ; load tcb address + mov ebx,esp + and ebx,-sizeof tcb + + ; read creators thread mcp, prio and timeslice information + mov al,[ebx+max_controlled_prio] + shl eax,16 + mov ah,[ebx+prio] + mov al,[ebx+timeslice] + + ; create new thread with creators mcp, prio and timeslice + call create_thread + + popad + FI + + ; test if autopropagation information should be updated + bt edi,ex_regs_update_flag + IFC + ; if auto_propagation flag is set + bt edi,ex_regs_auto_propagating_flag + IFC + ; cand lthread not last in the task + CANDL eax,max_lthread_no + ; enable autopropagation + or [ebp+coarse_state],auto_propagating + ELSE_ + ; disable autopropagation + and [ebp+coarse_state],NOT auto_propagating + FI + FI + + ; set new stack pointer + IFNZ ecx,-1 + xchg ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + ELSE_ + ; load current stack pointer + mov ecx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_esp + FI + + ; set new eip + IFNZ edx,-1 + + xchg edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + + pushad + ; cancel ongoing ipc + call cancel_if_within_ipc + IFZ al,running + ; reset thread if running + call reset_running_thread + FI + popad + + ELSE_ + ; load instruction pointer + mov edx,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eip + FI + + ; set internal preempter + cmp ebx,-1 + IFNZ + xchg ebx,[ebp+int_preempter] + ELSE_ + ; load internal preempter + mov ebx,[ebp+int_preempter] + FI + + ; set pager + IFNZ esi,-1 + xchg esi,[ebp+pager] + ELSE_ + ; load current pager + mov esi,[ebp+pager] + FI + + pop eax + ; load eflags + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_eflags + ELSE_ + pop eax + pop eax + + ke 'lthread ex regs cross processor borders' + ; send ipc with information to proxy thread + ; lthread ex regs from proxy thread + + + + FI + tpost ,ds,es + + + + + + +;---------------------------------------------------------------------------- +; +; reset running thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; bottom state = running +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs unchanged +; +; kernel activities cancelled +; +;---------------------------------------------------------------------------- + + + +reset_running_thread: + + ; return if thread is not running + IFZ [ebp+fine_state],running + ret + FI + + + pop ecx + + ; load offset of interrupt stack on current thread's stack + lea esi,[ebp+sizeof tcb-sizeof int_pm_stack-4] + + ; store return address in ip_eip + mov dword ptr [esi],offset reset_running_thread_ret + + ; store linear user segment in ip_ds + mov dword ptr [esi+4],linear_space + + ; set thread state to running + mov [ebp+fine_state],running + ; mark thread ready + mov ebx,ebp + mark__ready ebx + + ; store threads new stack pointer + mov [ebp+thread_esp],esi +; xor esi,esp +; test esi,mask thread_no +; xc z,reset_own_thread + + push ecx + ; if resources allocated refresh allocate + cmp [ebp+ressources],0 + jnz refresh_reallocate + ret + + + + +;XHEAD reset_own_thread +; +; xor esp,esi +; xret + + + + + +reset_running_thread_ret: + + ipost + + + + + + +;---------------------------------------------------------------------------- +; +; create (and start) thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX mcp SHL 16 + prio SHL 8 + timeslice +; +; ECX initial ESP +; EDX initial EIP +; EBP tcb address +; ESI pager +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new thread id +; +; thread created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; +;---------------------------------------------------------------------------- + + + +create_thread: + + pushad + ; if thread is not on current processor + lno___prc edi + IFNZ [ebp+proc_id],edi + CANDNZ [ebp+proc_id],0 + ; return with kernel error message + ke 'killing a thread cross processor boundaries' + popad + ret + FI + + ; if tcb used and present + IFNZ [ebp+coarse_state],unused_tcb + test [ebp+list_state],is_present + CANDNZ + ; detach coprocessor + mov ebp,ebp + call detach_coprocessor + ; ipcman close tcb + call ipcman_close_tcb + ; dispatcher close tcb + call dispatcher_close_tcb + FI + + ; clear first quater of tcb + mov edi,ebp + mov ecx,sizeof tcb/4 + sub eax,eax + cld + rep stosd + + popad + + ; save tcb id + mov dword ptr [ebp+tcb_id],'BCT'+(new_tcb_version SHL 24) + + ; set thread state to not dead and not blocked + mov [ebp+coarse_state],ndead+nblocked + + ; initialise send Queue + call init_sndq ; must be done before (!) + ; myself initiated + + push eax + ; load creators tcb address + mov eax,esp + and eax,-sizeof tcb + +; test esi,esi +; IFZ +; mov esi,[eax+pager] +; FI + + ; set pager + mov [ebp+pager],esi + + ; set clan_depth and compute thread id + test ebp,mask lthread_no + IFNZ + CANDA ebp,max_kernel_tcb + mov bl,[eax+clan_depth] + mov [ebp+clan_depth],bl + mov esi,[eax+myself] + and esi,NOT mask thread_no + ELSE_ + mov esi,initial_version+root_chief_no SHL chief_no + FI + mov ebx,ebp + and ebx,mask thread_no + add esi,ebx + ; set thread id + mov [ebp+myself],esi + + pop eax + + ; set new threads stack pointer + lea ebx,[ebp+sizeof pl0_stack-sizeof int_pm_stack-4] + mov [ebp+thread_esp],ebx + + ; set eip, code segment and data segment of new thread + mov dword ptr [ebx],offset reset_running_thread_ret + mov [ebx+ip_error_code+4],fault + mov [ebx+ip_eip+4],edx + mov [ebx+ip_cs+4],linear_space_exec + mov dword ptr [ebx+ip_ds+4],linear_space + + ; set priority and timeslice of new thread + mov [ebp+prio],ah + mov [ebp+timeslice],al + IFDEF ready_llink + mov [ebp+rem_timeslice],al + ENDIF + + ; set maximum controlled priority + shr eax,16 + mov [ebp+max_controlled_prio],al + + ; set flags to pl0 and i_flag + mov [ebx+ip_eflags+4],(0 SHL iopl_field)+(1 SHL i_flag) + + ; if tcb address < -1 (max root tcb) (for all threads) + IFB_ ebp,-1 ;;; max_root_tcb + ; set minimal priviledge level for accessing the io address space to pl3 + or [ebp+coarse_state],iopl3_right + or byte ptr [ebx+ip_eflags+4+1],3 SHL (iopl_field-8) + FI + + ; set user level stack pointer and stack segment + mov [ebx+ip_esp+4],ecx + mov [ebx+ip_ss+4],linear_space + + ; set threads current processor id + push eax + lno___prc eax + mov [ebp+proc_id],eax + pop eax + + ; set thread to running + mov [ebp+fine_state],running + + ; open thread control block + call open_tcb + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; delete thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread deleted, frame inserted into free frame pool if no tcb left +; +;---------------------------------------------------------------------------- + + +delete_thread: + + pushfd + cli + + pushad + + ; enter kdebug if thread is on different processor + push eax + lno___prc eax + IFNZ [ebp+proc_id],eax + CANDNZ [ebp+proc_id],0 + ke 'killing a thread cross processor boundaries' + pop eax + popad + popfd + FI + pop eax + + ; cancel ongoing ipc + call cancel_if_within_ipc + popad + + ; detach coprocessor + call detach_coprocessor + + ; close tcb (dispatcher) + call dispatcher_close_tcb + + push eax + push ebp + push ecx + + ; set thread state to unused tcb + mov [ebp+coarse_state],unused_tcb + ; clear id + sub eax,eax + mov [ebp+myself],eax + + ; check if all tcb's of that page are unused + and ebp,-pagesize + mov al,pagesize/sizeof tcb + lno___prc ecx + DO + ; for all threads of that page check if tcb is unused + CORZ [ebp+proc_id],0 + IFZ [ebp+proc_id],ecx + cmp [ebp+coarse_state],unused_tcb + EXITNZ + ELSE_ + EXIT + FI + add ebp,sizeof tcb + dec al + REPEATNZ + OD + ; if no thread of that page is in use + IFZ + ; flush page + lea eax,[ebp-1] + call flush_system_shared_page + IFNZ + ; insert into fresh frame pool + call insert_into_fresh_frame_pool + FI + FI + + pop eax + pop ebp + popfd + ret + + + + + +;---------------------------------------------------------------------------- +; +; shutdown_thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESP kernel stack +; +;---------------------------------------------------------------------------- + + +shutdown_thread: + + ; load tcb address of current thread + mov ebp,esp + and ebp,-sizeof tcb + + ; set thread state to dead + and [ebp+coarse_state],NOT ndead + + ; repeat forever + DO + ; setup ipc + sub ecx,ecx ; timeout = 0 + mov esi,ecx ; send to nilthread + mov edi,ecx ; receive from anyone + lea eax,[ecx-1] ; no send phase + mov ebp,ecx ; open receive register messages only + ; send ipc + int ipc + REPEAT + OD + + + +;---------------------------------------------------------------------------- +; +; create kernel thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address lthread > 0 (!) +; ECX initial EIP +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI scratch +; +; thread (thread of kernel task) created and started at kernel_cs:EDI +; +;---------------------------------------------------------------------------- + + + + +create_kernel_thread: + + push ecx + mov eax,(255 SHL 16) + (16 SHL 8) + 10 ;mcp = 255, priority = 16, timeslice 10 + sub ecx,ecx + sub edx,edx + sub esi,esi + sub edi,edi + ; create Thread + call create_thread + pop ecx + + ; if current thread == dispatcher + IFZ ebp,dispatcher_tcb + ; set invalid thread id (so no one is able to send to this thread) + mov [ebp+myself],-1 + ELSE_ + ; else mark thread ready + mark__ready ebp + FI + ; set new thread's eip + mov ebx,[ebp+thread_esp] + mov [ebx],ecx + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/adrsman.asm b/l4-x86/smp/lx/kern/adrsman.asm new file mode 100644 index 0000000..7543f1e --- /dev/null +++ b/l4-x86/smp/lx/kern/adrsman.asm @@ -0,0 +1,1024 @@ +include l4pre.inc + + + Copyright IBM, L4.ADRSMAN.5, 08, 08, 99, 9025 + +;********************************************************************* +;****** ****** +;****** Address Space Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 08.08.99 ****** +;****** ****** +;********************************************************************* + + + + public init_adrsman + public init_sigma_1 + public sigma_1_installed + public create_kernel_including_task + public init_small_address_spaces + public attach_small_space + public get_small_space + public make_own_address_space_large + public set_small_pde_block_in_pdir + + + extrn create_thread:near + extrn delete_thread:near + extrn insert_into_fresh_frame_pool:near + extrn flush_address_space:near + extrn gen_kernel_including_address_space:near + extrn define_idt_gate:near + extrn ipc_update_small_space_size:near + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +include schedcb.inc +include syscalls.inc +include kpage.inc +include pagcb.inc +.list + + + +ok_for x86 + + + + assume ds:codseg + + + + + + +;---------------------------------------------------------------------------- +; +; init address space manager +; +;---------------------------------------------------------------------------- + + + icode + + + +init_adrsman: + lno___prc ecx + + ; make sure first ptab of kernel task is allocated + mov eax,kernel_task ; ensuring that first ptab for pdir space + lea___pdir eax,eax ; becomes allocated before task creation + + shl ecx,log2_pagesize + add eax,[ecx - pagesize] + + mov eax,[eax] + + lno___prc ecx + IFZ ecx,1 + ; define IDT gate for task new sc + mov bh,3 SHL 5 + + mov bl,task_new + mov eax,offset task_new_sc + call define_idt_gate + + ; clear redirection table + mov edi,offset redirection_table ;REDIR + mov ecx,tasks*tasks ; + movi eax,ipc_transparent ; + cld ; + rep stosd ; + FI + + ret + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; task new sc +; +; delete/create task (incl. creation of lthread 0 of new task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new chief / mcp +; ECX initial ESP of lthread 0 +; EDX initial EIP of lthread 0 +; EBX pager +; ESI task id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI new task id / 0 +; +; ECX,EDX,ESI,EDI,EBP scratch +; +; task created, +; lthread 0 created and started at PL3 with: +; +; EAX...EBP 0 +; ESP initial ESP +; EIP initial EIP +; DS...GS linear space +; CS linear space exec +; lthread 0's Processor will be the creators one +;---------------------------------------------------------------------------- + + +task_new_failed: + + ; task new failed + ke 'tfail' + + sub esi,esi + sub edi,edi + + add esp,3*4 + iretd + + + +;################################################################################### + +task_new_sc: + + tpre trap2,ds,es + + ; mask out thread number in task id + and esi,NOT mask lthread_no + + ; load current tcb + mov ebp,esp + and ebp,-sizeof tcb + + + IFZ ebx,1 ;REDIR begin -------------------------- + ; + mov ebx,[ebp+myself] ; + lno___task ebx ; + ; + mov eax,esi ; + call is_ruled_by ; + IFZ ; + mov eax,edx ; + call is_ruled_by_or_is_myself ; + CANDZ ; + CORZ ecx,ipc_transparent ; + CORZ ecx,ipc_inhibited ; + mov eax,ecx ; + call is_ruled_by_or_is_myself ; + IFZ ; + mov ebp,esi ; + and ebp,mask task_no ; + shr ebp,task_no-log2_tasks-2 ; + lno___task edx ; + mov [edx*4+ebp+redirection_table],ecx; + ; + tpost ,ds,es ; + FI ; + FI ; + sub esi,esi ; + tpost ,ds,es ; + ; + FI ;REDIR ends -------------------------- + + + push esi + push ebx + + mov ebx,[ebp+myself] + shl ebx,chief_no-task_no + xor ebx,esi + test ebx,mask chief_no + CORNZ + IFA [ebp+clan_depth],max_clan_depth + jmp task_new_failed + FI + + lea___tcb ebx,esi + test__page_present ebx + IFNC ,,long + CANDNZ [ebx+coarse_state],unused_tcb,long + + xor esi,[ebx+myself] + test esi,NOT mask ver + jnz task_new_failed + + + pushad ;------------------------- + ; + ; delete task + ; + mov edi,ebp ; ;REDIR begin --------------------------- + and edi,mask task_no ; ; + shr edi,task_no-log2_tasks-2 ; ; + add edi,offset redirection_table ; ; + movi eax,ipc_transparent ; ; + mov ecx,tasks ; ; + cld ; ; + rep stosd ; ;REDIR ends ---------------------------- + ; + ; + lno___task eax,ebp ; + load__proot eax,eax ; + mov ds:[cpu_cr3],eax ; If deleter has small address space, + mov dword ptr ds:[tlb_invalidated],eax; it might execute inside to be deleted + mov cr3,eax ; pdir. Avoided by explicitly switching + ; to deleter's pdir. + ; + lno___task edi,ebx ; + ; + call detach_associated_small_space ; + ; + load__proot edi,edi ; + ; + mov ecx,lthreads ; + DO ; + test__page_present ebx ; + IFNC ; + mov ebp,ebx ; + call delete_thread ; + FI ; + add ebx,sizeof tcb ; + dec ecx ; + REPEATNZ ; + OD ; + ; + call flush_address_space ; + + lno___prc ecx + IFNZ edi,ds:[empty_proot] ; + CANDNZ edi,ds:[kernel_proot+8*ecx-8] ; + ; + add edi,PM ; + mov ecx,virtual_space_size SHR 22; + DO ; + sub eax,eax ; + cld ; + repe scasd ; + EXITZ ; + ; + mov eax,[edi-4] ; + call insert_into_fresh_frame_pool; + REPEAT ; + OD ; + ; + lea eax,[edi-PM] ; + call insert_into_fresh_frame_pool; + ; + FI ; + popad ;-------------------------- + + + ELSE_ + + push eax + push ecx + push edi + lno___task ecx,ebx + lno___prc edi + shl ecx,max_cpu + add ecx,edi + mov ecx,[(ecx*8)+task_proot-8].switch_ptr + lno___task eax,ebp + add eax,ds:[empty_proot] + cmp eax,ecx + + pop edi + pop ecx + pop eax + jnz task_new_failed + FI + + + IFZ ,0 + + and eax,mask task_no + shl eax,chief_no-task_no + and esi,NOT mask chief_no + or esi,eax + + lno___task ebx + shr eax,chief_no + add eax,ds:[empty_proot] + store_inactive_proot eax,ebx + + add esp,3*4 + push linear_space + pop ds + push linear_space + pop es + iretd + FI + + + IFA al,[ebp+max_controlled_prio] + mov al,[ebp+max_controlled_prio] + FI + shl eax,16 + mov ah,[ebp+prio] + mov al,[ebp+timeslice] + + lno___task edi,ebx + mov esi,ds:[empty_proot] + store_proot esi,edi + + pop esi + + xchg ebp,ebx + push ebx + call create_thread + pop ebx + + pop esi + + mov eax,[ebx+myself] + and eax,mask task_no + shl eax,chief_no-task_no + or esi,eax + mov [ebp+myself],esi + + IFNZ eax,root_chief_no SHL chief_no + inc [ebp+clan_depth] + FI + + tpost eax,ds,es + + + + + + + +is_ruled_by_or_is_myself: ;REDIR begin -------------------------------- + ; + ; return if destination task_id is own task_id ; + lno___task edi,eax ; + IFZ edi,ebx ; + ret ; + FI ; + ; + ; + ; + ; +is_ruled_by: ; + ; EAX checked task ; + ; EBX mytask no ; + ; Z: yes ; + ; EAX,EDI,EBP scratch ; + ; mask out thread no in destination task id ; + and eax,NOT mask lthread_no ; always check lthread 0; + ; + ; load task and tcb address of that task ; + lno___task edi,eax ; + lea___tcb ebp,eax ; + ; + shl edi,max_cpu ; + push esi ; + lno___prc esi ; + add edi,esi ; + pop esi ; + IFZ [edi*8+task_proot-8].proot_ptr,0 ; + mov edi,[edi*8+task_proot-8].switch_ptr ; + sub edi,ds:[empty_proot] ; + ELSE_ ; + test__page_present ebp ; + IFNC ; + mov edi,[ebp+myself] ; + shr edi,chief_no ; + FI ; + FI ; + ; + cmp edi,ebx ; + ret ; + ;REDIR ends ------------------------------- + + + + +;################################################################################# + + + icode + + + + +create_kernel_including_task: + ; if kernel task stack pointer is valid (!= 0) + IFNZ [ebx].ktask_stack,0 + + ; load tcb address + lea___tcb ebp,eax + + ; generate kernel including address space + call gen_kernel_including_address_space + + push eax + + ; create first thread + mov ecx,[ebx].ktask_stack ; stack pointer + mov edx,[ebx].ktask_start ; instruction pointer + mov eax,(255 SHL 16) + (16 SHL 8) + 10; mcp = 255, priority 16, timeslice 10 + mov esi,sigma0_task ; pager + + ; create thread + call create_thread + + pop eax + ; load task number + lno___task ebp + ; store page root + store_proot eax,ebp + FI + + ret + + + + icod ends + + + + +;---------------------------------------------------------------------------- +; +; sigma_1 +; +;---------------------------------------------------------------------------- + + +sigma_1_installed db false + + + + + +init_sigma_1: + ; initialise sigma 1 + ; not present + ret + + + + +;********************************************************************* +;****** ****** +;****** ****** +;****** Small Address Space Handler ****** +;****** ****** +;****** ****** +;********************************************************************* + + + + + + + + +;---------------------------------------------------------------------------- +; +; init small address spaces +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + icode + + + +init_small_address_spaces: + + ; set small address space size (minimum is MB 4) + mov ds:[log2_small_space_size_DIV_MB4],-22 + mov ds:[small_space_size_DIV_MB4],1 + + ; clear proot fields of all small address spaces (No initially mapped small spaces) + sub ebx,ebx + DO + mov ds:[ebx*2+small_associated_task],0 + inc ebx + cmp ebx,max_small_spaces + REPEATB + OD + + ; change small space size + mov cl,3 ; 2 SHL cl * 4 MB = 32 MB + call change_small_space_size + + ret + + + + + + icod ends + +;############################################################################## + +;---------------------------------------------------------------------------- +; +; attach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH 0 < small as no < small spaces (attach small space) +; 0 = small as no (detach small space) +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDI scratch +; +; ES,FS,GS undefined +; +;---------------------------------------------------------------------------- + + + + +attach_small_space: + + CORZ ah,2 + IFZ ah,1 + shl ah,3+1 + add ah,32/4 + FI + + + mov cl,-1 + DO + inc cl + shr ah,1 + REPEATA ; NZ , NC + OD + IFNZ + shl ah,cl + IFNZ cl,ds:[log2_small_space_size_DIV_MB4] + call change_small_space_size + FI + FI + + + lno___task ebp,esi + shl ebp,max_cpu + lno___prc edi + add ebp,edi + lea edi,[ebp*8+task_proot-8] + + movzx eax,ah + movzx ecx,[edi].small_as + + IFNZ eax,ecx + + IFNZ cl,0 + call detach_small_space + FI + + test eax,eax + IFNZ + IFNZ [(eax*2)+small_associated_task],0 + mov ecx,eax + call detach_small_space + FI + mov [(eax*2)+small_associated_task],bp + FI + mov ecx,eax + mov [edi].small_as,al + FI + + shl ecx,22-16 + IFNZ + add ecx,(offset small_virtual_spaces SHR 16) + 0C0F30000h + xchg cl,ch + ror ecx,8 + mov [edi].switch_ptr,ecx + + mov eax,esp + xor eax,esi + test eax,mask task_no + jz short update_own_address_space_small + FI + ret + + + + + +;---------------------------------------------------------------------------- +; +; detach small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_small_space: + + push eax + push edi + + movzx edi,[(ecx*2)+small_associated_task] + test edi,edi + IFNZ + mov word ptr [(ecx*2)+small_associated_task],0 + + call flush_small_pde_block_in_all_pdirs + + mov ecx,edi + shl ecx,max_cpu + lno___prc eax + add ecx,eax + lea ecx,[(ecx*8)+task_proot-8] + + mov eax,cr3 + mov cr3,eax + + mov eax,[ecx].proot_ptr + mov al,0 + mov [ecx].switch_ptr,eax + mov [ecx].proot_ptr,eax + FI + + lno___task eax,esp + IFZ eax,edi + call make_own_address_space_large + FI + + pop edi + pop eax + ret + + + +;---------------------------------------------------------------------------- +; +; detach associated small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- + + + + +detach_associated_small_space: + + push ecx + + mov ecx,edi + shl ecx,max_cpu + push edi + lno___prc edi + add ecx,edi + pop edi + + movzx ecx,[ecx*8+task_proot-8].small_as + test ecx,ecx + IFNZ + call detach_small_space + FI + + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; change own address space large <--> small +; +;---------------------------------------------------------------------------- +; update..small PRECONDITION: +; +; EDI task_proot address of current task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; make..large PRECONDITION: +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; linar_space / exec segment descriptor updated +; ES,FS,GS reloaded +; DS unchanged +; +; TLB flushed +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- + + + +update_own_address_space_small: + + mov eax,[edi].switch_ptr + lno___prc edi + mov edi,ds:[kernel_proot+8*edi-8] + jmp short update_cr3_and_seg_register + + + + +make_own_address_space_large: + + lno___task edi,esp + shl edi,max_cpu + lno___prc eax + add edi,eax + lea edi,[(edi*8)+task_proot-8] + mov eax,[edi].proot_ptr + mov al,0 + mov [edi].switch_ptr,eax + + mov edi,eax + mov eax,00CCF300h + + + +update_cr3_and_seg_register: + + mov ds:[cpu_cr3],edi + mov cr3,edi + + mov ds:[gdt+linear_space/8*8+4],eax + add ah,0FBh-0F3h + mov ds:[gdt+linear_space_exec/8*8+4],eax + + mov eax,linear_space + mov es,eax + mov fs,eax + mov gs,eax + + ret + + + + +;---------------------------------------------------------------------------- +; +; flush small page directory block in ALL pdirs +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX 0 < small no < small spaces +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +flush_small_pde_block_in_all_pdirs: + + push ebx + push edx + push ebp + + mov edx,offset task_proot + DO + mov ebp,[edx].proot_ptr + add edx,8 + and ebp,0FFFFFF00h + REPEATZ + + EXITS + + push ecx + mov bl,ds:[small_space_size_DIV_MB4] + DO + sub eax,eax + xchg dword ptr [(ecx*4)+ebp+(offset small_virtual_spaces SHR 22)*4+PM],eax + inc ecx + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + and byte ptr [(eax*4)+ptab_backlink],NOT 01h + FI + dec bl + REPEATNZ + OD + pop ecx + REPEAT + OD + + pop ebp + pop edx + pop ebx + ret + + + + + + + + +;---------------------------------------------------------------------------- +; +; set small page directory entry in ONE pdir +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI source pde block addr +; EDI dest pde block addr +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + + +set_small_pde_block_in_pdir: + + mov cl,ds:[small_space_size_DIV_MB4] + DO + mov eax,[esi] + add esi,4 + mov dword ptr [edi],eax + add edi,4 + test al,superpage + IFZ + shr eax,log2_pagesize + CANDNZ + or byte ptr [(eax*4)+ptab_backlink],01h + FI + dec cl + REPEATNZ + OD + + ret + +;######################################################################################## + +;---------------------------------------------------------------------------- +; +; change small space size +; +; Precondition: Pagesize = (2^cl) * 4MB +; +;---------------------------------------------------------------------------- + + +change_small_space_size: + + pushad + + ; set small space size value div MB4 in pagcb + mov ch,1 + shl ch,cl + mov ds:[small_space_size_DIV_MB4],ch + + + ; modify segment limit field in linear space descriptor + ; modify segment limit field in linear space exec descriptor + + shl ch,2 + dec ch + mov byte ptr ds:[gdt+linear_space/8*8+1],ch ; recall: 256 MB is max small_space_size + mov byte ptr ds:[gdt+linear_space_exec/8*8+1],ch + + + ; I do really not know what this part does, ipc_update_small_spacec size requires log2 space size in ch not 25 + mov ch,cl ; ch = 3 + xchg cl,ds:[log2_small_space_size_DIV_MB4] ; cl = -22, l2small space size = 3 + add cl,22 ; cl = 0 + add ch,22 ; ch = 25 = 19h 32 MB = 8 * 4 MB = 2^3 * 4MB + call ipc_update_small_space_size + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get small space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI a tcb (!) address of dest task +; +; DS linear kernel space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL small space / 0 +; +;---------------------------------------------------------------------------- + + + + +get_small_space: + + ; load switch pointer at (task_no*2^max_cpu+(proc_nr-1))*8+task_proot + lno___task eax,esi + shl eax,max_cpu + push edi + lno___prc edi + add eax,edi + pop edi + mov eax,[eax*8+task_proot-8].switch_ptr + + ; if msb bit not set + test eax,eax + IFNS + ; return 0 + mov al,0 + ret + FI + + ; compute small space + rol eax,8 + xchg al,ah + shr eax,22-16 + sub al,(offset small_virtual_spaces SHR 22) AND 0FFh + add al,al + add al,ds:[small_space_size_DIV_MB4] + + ret + + + + + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/apstrtup.asm b/l4-x86/smp/lx/kern/apstrtup.asm new file mode 100644 index 0000000..83d0c97 --- /dev/null +++ b/l4-x86/smp/lx/kern/apstrtup.asm @@ -0,0 +1,369 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.APSTART, 17,01,00, 31 + +;********************************************************************* +;****** ****** +;****** Application Processor Startup ****** +;****** ****** +;****** Author: M.Voelp ****** +;****** ****** +;****** ****** +;****** modified: 17.01.00 ****** +;****** ****** +;********************************************************************* + + + public startup_ap + public synch_all + public release_all + + + extrn physical_kernel_info_page:dword + + extrn ltr_pnr:near + extrn enable_paging_mode:near + extrn init_sgmctr:near + extrn init_intctr:near + extrn init_emuctr:near + extrn init_cpuctr:near + extrn init_pagmap:near + extrn init_schedcb:near + extrn init_tcbman:near + extrn init_dispatcher:near + extrn init_adrsman:near + extrn init_small_address_spaces:near + extrn create_kernel_thread:near + + + extrn tss_vec:dword + extrn gdt_vec:dword + +.nolist + include l4const.inc + include uid.inc + include l4kd.inc +.list + +include adrspace.inc + +.nolist + include kpage.inc + include apic.inc + include descript.inc + include tcb.inc + include cpucb.inc +.list + include apstrtup.inc + +ok_for x86 + + assume ds:codseg + + icode + + +;------------------------------------------------------------------------------------------- +; handle not answering processors +;------------------------------------------------------------------------------------------- + +check_fatal_cpu_exception: + ; Get number of processors out of MPconfig Table + mov esi,ds:[logical_info_page+proc_data] + add esi,PM + + sub ebx,ebx + DO + ; processor data has entry type 0 located at first byte each 14h starting at proc_data + mov eax,ds:[esi] + inc ebx + add esi,14h + cmp al,0 + REPEATZ + OD + dec ebx + ; number of processors in the system in ebx + ; wait for time to elaps or all processors up and running (aquiring their procnumber) + + mov ecx,100000h + DO + dec ecx + IFZ + ke 'Fatal Error, some Processors does not respond' + FI + mov al,ds:[logical_info_page+numb_proc] + cmp al,bl + REPEATNZ + OD + ret + +;------------------------------------------------------------------------------------------- +; synch all +;------------------------------------------------------------------------------------------- +; Waits for all processors to enter the code. All processors loop waiting until all reached +; the loop. +;------------------------------------------------------------------------------------------- +synch_all: + mov eax,[logical_info_page+numb_proc] + mov eax,[eax] + lock inc ds:[logical_info_page+prc_sema] + DO + cmp al,ds:[logical_info_page+prc_sema] + REPEATNZ + + OD + ;; synched + lock inc ds:[logical_info_page+prc_release] + lno___prc eax + IFNZ eax,1 + sub eax,eax + DO + cmp al,ds:[logical_info_page+prc_sema] + REPEATNZ + OD + FI + ret + +release_all: + mov eax,[logical_info_page+numb_proc] + mov eax,[eax] + DO + cmp al,ds:[logical_info_page+prc_release] + REPEATNZ + OD + sub eax,eax + mov ds:[logical_info_page+prc_sema],al + mov ds:[logical_info_page+prc_release],al +ret + + +;------------------------------------------------------------------------------------------- +; startup application processors +;------------------------------------------------------------------------------------------- + +startup_ap: + call prepare_ap_startup ; store proc state (IDTR ,...) to memory + call initiate_startup ; initiate startup ipi + ret + + +;------------------------------------------------------------------------------------------- +; prepare application processor startup +;------------------------------------------------------------------------------------------- +; +; PRECONDITION: ds linear space +; temporarly implementation of startup code: +; store idt, tss, cr3 of BSP to share tables/data with all APs +; +;------------------------------------------------------------------------------------------- + +prepare_ap_startup: + + lea eax,[esp] + mov ds:[apinit_esp],eax + + sidt ds:[apinit_idt_vec] + ret + + apinit_esp dd 0 + apinit_idt_vec df 0 + + +;------------------------------------------------------------------------------------------- +; initiate startup +;------------------------------------------------------------------------------------------- +; initialises and starts up all APs. Startupcode at application_processor_start +; +; PRECONDITION +; ds linear space +; apic initialised +; POSTCONDITION +; +;------------------------------------------------------------------------------------------- + +initiate_startup: + + mov eax,(1 SHL max_cpu) + IFAE eax,2 + ; set entry point for the ap processor: jump to startup code + sub eax,eax + mov byte ptr ds:[eax],0E9h + mov ebx, offset application_processor_start-3 + mov word ptr ds:[eax+1],bx + + ; enable apic (set software apic enable bit) + ; bts ds:[local_apic+apic_icr], 7 ; apic sw enabled + + ; send Init message to all processors (level assert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; send Init message to all processors (level deassert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_deassert_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; now send startup IPI + mov ds:[local_apic+apic_icr], apic_startup_msg + 0 + ;; wait for apic to finish ?? + + mov ecx, 1000000 ; some time + DO + dec ecx + REPEATNZ + OD + + call check_fatal_cpu_exception + + FI + + ret + + + +;------------------------------------------------------------------------------------------- +; application processor start +;------------------------------------------------------------------------------------------- +; PRECONDITION +; real mode, interrupts disabled, apic disabled +; POSTCONDITION +; +; +;------------------------------------------------------------------------------------------- + +application_processor_start: + + ; enable protected mode + + ;load temporary gdt + asp + osp + lgdt fword ptr cs:[ap_gdt_vec] + + mov eax,cr0 + or ax,1 ; set protected mode bit + mov cr0,eax + + osp + db 0eah ; jmp far + dd offset ap_protected_mode + dw 10h ; cs register + + + ap_gdt_vec dw offset ap_temp_end_of_gdt - offset ap_temp_gdt -1 + dd offset ap_temp_gdt + + align 8 + + ap_temp_gdt dd 0,0 ; 0 descriptor + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor xr32, dpl0, 0, ; 10 : phys_exec + + ap_temp_end_of_gdt equ $ + +;------------------------------------------------------------------------------------- +; application processor protected mode start +;------------------------------------------------------------------------------------- +; PRECONDITION +; cs,ds phys memory, paging disabled, intr disabled +; protected mode +; +;------------------------------------------------------------------------------------- + + +ap_protected_mode: + sub eax,eax + mov eax,08h + mov ds, eax + mov es, eax + mov ss, eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,eax ; [apinit_esp] + add esp,1024 + + call ltr_pnr + + call enable_paging_mode + call init_sgmctr + call init_intctr + call init_emuctr + + ke 'dual' + + call init_cpuctr ; ?? + call init_pagmap ; ?? + + call synch_all + + call init_schedcb + call init_tcbman + call init_dispatcher + + call init_adrsman + call init_small_address_spaces + + +;; create thread (tcb = e0010500) thread 4 of kernel task + ;; send to thread 8 of kernel task + mov ebp, 0e0010400h ; thread 4 + mov ecx, offset dual_thread_test + call create_kernel_thread + + ke 'thread started' + jmp $ + + ke 'end dual' + + ; - test single processor behaviour on APs + ; - change Systemcall: thread switch + ; - extend IPC critical path + ; - extend thread schedule with dummy functionality: set processor number + ; - Implement Proxies and Mailboxes + ; - Implement send to Proxy + + + ke 'dual end2' + + jmp $ + + + +dual_thread_test: + + +dual_ipc_test: + sub ecx,ecx ; timeoutinfinity + mov ebp,-1 ; send only + mov esi,ds:[0e0010800h+myself]; + + rdtsc ; Measure START + mov ebx,eax ; 1/2 + mov edi,edx ; 1/2 + sub eax,eax ; send registers only 1 + + int 30h + + rdtsc ; Measure END + + ke 'ipc send' + + jmp dual_ipc_test + + icod ends + code ends +end + + diff --git a/l4-x86/smp/lx/kern/apstrtup1.asm b/l4-x86/smp/lx/kern/apstrtup1.asm new file mode 100644 index 0000000..5534ba7 --- /dev/null +++ b/l4-x86/smp/lx/kern/apstrtup1.asm @@ -0,0 +1,449 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.APSTART, 17,12,99, 31 + +;********************************************************************* +;****** ****** +;****** Application Processor Startup ****** +;****** ****** +;****** Author: M.Voelp ****** +;****** ****** +;****** ****** +;****** modified: 17.12.99 ****** +;****** ****** +;********************************************************************* + + + public startup_ap + + + extrn physical_kernel_info_page:dword + +.nolist + include l4const.inc + include uid.inc +.list + +include adrspace.inc + +.nolist + include kpage.inc + include apic.inc + include cpucb.inc +include tcb.inc + +.list + +ok_for x86 + + + + ;; load shared tables: gdt, idt, ldt + ;; enter protected mode, enable paging + + ; Do code next: + ; AP Datastructure setup: + ; - control blocks: cpu schedule + ; - establish scheduler lists on APs: ready list soon wakeup + ; + ; - test single processor behaviour on APs + ; - change Systemcall: thread switch + ; - extend IPC critical path + ; - extend thread schedule with dummy functionality: set processor number + ; - Implement Proxies and Mailboxes + ; - Implement send to Proxy + + + + + +;--------------------------------------------------------------------- +; +; AP Startup +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; protected mode +; paging enabled +; +; cs: physical mem executeable +; ds,es,fs,gs,ss linear space +; +; interrupts disabled +; all APIC's but BSP-APIC disabled +; waiting for INIT-IPI +; +;--------------------------------------------------------------------- + + assume ds:codseg + icode + + + +;---------------------------------------------------------------------------- +; +; Bootup and synchronization of AP's +; +;---------------------------------------------------------------------------- +; These methods insure to startup the kernel on a crashed / shutdown +; processor (i.e. after startup) +; +; PRECONDITION: At least one Processor (at startup the BSP) must have +; performed the startup of the nucleus including all structures +; needed to bring up the system (i.e. IDT / GDT /...) +;---------------------------------------------------------------------------- + +;---------------------------------------------------------------------------- +; Startup Application Processors +;---------------------------------------------------------------------------- +; This method is run by the BSP / the processor detecting an AP-crash +; +; PRECONDITION: EAX: mask of the destination processors to be started +; ******* ?? exact value for different addr types ?? +; POSTCONDITION: processor up waiting for task switch if +; proc id bit is set in proc_avail +; (2^APIC_ID = 2^CPU_ID = proc ID bit in proc_avail) +;---------------------------------------------------------------------------- + +startup_ap: + bt ds:[cpu_feature_flags],on_chip_apic_bit + IFS + FI + call prepare_ap_startup ; store proc state (IDTR ,...) to memory + call initiate_startup ; initiate startup ipi + ret + +prepare_ap_startup: + + lea eax,[esp] + mov ds:[apinit_esp],eax + + + ke 'wo bin ich' + sgdt ds:[apinit_gdt_vec] + + mov eax,cr3 + and eax,0FFFFFF00h + + lea edi,ds:[apinit_gdt_vec] + + mov ebx,[edi] + mov ecx,ebx + and ebx,0FFC00000h + shr ebx,22 + add eax,ebx + + ke 'pdir' + + mov eax,[eax] + mov ebx,ecx + and ebx,0003FF000h + shr ebx,12 + add eax,ebx + + ke 'ptab' + + mov ecx,ebx + and ebx,00000FFFh + mov eax,[eax] + add eax,ebx + + mov [edi],eax + + ke 'phys' + + sidt ds:[apinit_idt_vec] + + mov ds:[apinit_cs],cs + mov ds:[apinit_ds],ds + + str ds:[apinit_tss] + mov eax,cr3 + mov ds:[apinit_cr3],eax + + ret + +initiate_startup: + sub eax,eax + mov byte ptr ds:[eax],0E9h ; ??? + mov ebx, offset application_processor_start-3 + mov word ptr ds:[eax+1],bx + + ke 'before IPI' + ; send Init message to all processors (level assert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; send Init message to all processors (level deassert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_deassert_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; now send startup IPI + mov ds:[local_apic+apic_icr], apic_startup_msg + 0 + ke 'after IPI' + + ;; wait for apic to finish ?? + mov ecx, 1000000 ; some time + DO + dec ecx + REPEATNZ + OD + + ret + +;---------------------------------------------------------------------------- +; Application Processor Start +;---------------------------------------------------------------------------- +; This method is run by the AP at startup +; +; PRECONDITION STARTUP: real mode / disable intr / APIC not initialised +; POSTCONDITION: processor bit will be set in proc_avail (not immediately) +; +;---------------------------------------------------------------------------- + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + user_space_size equ linear_address_space_size + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm + + + + + +application_processor_start: + + sub eax,eax + mov ds,eax + sub ebx,ebx + mov [edi],eax + ;; jmp $ + + + ; Wrong code entry Point of AP Processor: + ; test with dec cs:[eax] + ; test without jump offset -3 + + ;; load cr3 register with page directory base address + asp + osp + mov eax,cs:[apinit_cr3] + mov cr3,eax + + + asp + osp + mov esp,cs:[apinit_esp] + + asp + osp + lgdt cs:[apinit_gdt_vec] + + asp + osp + lidt cs:[apinit_idt_vec] + + mov eax,cr0 ; Enable Protected Mode + + or al,1 ; protected mode + + osp + bts eax,31 ; paging + + osp + mov [edi],eax + + ;; jmp $ + + ;; put identity mapped code to 0 and jump to it + sub ebx,ebx + + osp + mov eax,0f22c0eah + osp + mov [edi],eax + + add ebx,4 + mov [edi],offset ap_protected_mode + + sub eax,eax + add ebx,2 + mov [edi],eax + + add ebx,4 + mov eax, 0008h + mov [edi],eax + + db 0eah + dd 00000000h + dw 0008h + + + ;; mov cr0, eax must be identity mapped + ;; jmp far cs:offset + mov cr0,eax + + + +ap_protected_mode: + + jmp $ + +;; Things to do for Startup AP's + ;; movzx eax, cs:[apinit_ds] + ;; mov ds,eax + ;; mov eax, cs:[apinit_cr3] + ;; mov cr3, eax + + ;; enable Paging + ;; mov eax, cr0 + ;; bts eax, 31 ; pg flag + ;; mov cr0, eax + + + ;; get Processor Number initially + sub eax,eax + inc eax + lock xadd [physical_kernel_info_page+numb_proc],eax + inc eax + ;; Processor Number in eax + + DO + sub eax,eax + REPEATNZ + OD + + + ;; Wait for thread schedule (own processor) + + + + align 8 + + apinit_ds dw 0 + apinit_esp dd 0 + apinit_gdt_vec df 0 + apinit_idt_vec df 0 + apinit_tss dw 0 + apinit_cr3 dd 0 + + +initial_gdt dd 0,0 ; dummy seg + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + + descriptor xr32, dpl0, PM, ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + +end_of_initial_gdt equ $ + + + + icod ends + code ends +end + + + + + + + + + + diff --git a/l4-x86/smp/lx/kern/apstrtup2.asm b/l4-x86/smp/lx/kern/apstrtup2.asm new file mode 100644 index 0000000..64c3463 --- /dev/null +++ b/l4-x86/smp/lx/kern/apstrtup2.asm @@ -0,0 +1,455 @@ +include l4pre.inc + + + + Copyright IBM+UKA, L4.APSTART, 17,01,00, 31 + +;********************************************************************* +;****** ****** +;****** Application Processor Startup ****** +;****** ****** +;****** Author: M.Voelp ****** +;****** ****** +;****** ****** +;****** modified: 17.01.00 ****** +;****** ****** +;********************************************************************* + + + public startup_ap + public synch_all + + + extrn physical_kernel_info_page:dword + extrn init_sgmctr:near + extrn tss_vec:dword + extrn gdt_vec:dword + +.nolist + include l4const.inc + include uid.inc + include l4kd.inc +.list + +include adrspace.inc + +.nolist + include kpage.inc + include apic.inc + include descript.inc + + include cpucb.inc +.list + include apstrtup.inc + +ok_for x86 + + assume ds:codseg + + icode + + +;------------------------------------------------------------------------------------------- +; handle not answering processors +;------------------------------------------------------------------------------------------- + +check_fatal_cpu_exception: + ; Get number of processors out of MPconfig Table + mov esi,ds:[logical_info_page+proc_data] + add esi,PM + + sub ebx,ebx + DO + ; processor data has entry type 0 located at first byte each 14h starting at proc_data + mov eax,ds:[esi] + inc ebx + add esi,14h + cmp al,0 + REPEATZ + OD + dec ebx + ; number of processors in the system in ebx + ; wait for time to elaps or all processors up and running (aquiring their procnumber) + + mov ecx,100000h + DO + dec ecx + IFZ + ke 'Fatal Error, some Processors does not respond' + FI + mov al,ds:[logical_info_page+numb_proc] + cmp al,bl + REPEATNZ + OD + ret + +;------------------------------------------------------------------------------------------- +; synch all +;------------------------------------------------------------------------------------------- +; Waits for all processors to enter the code. All processors loop waiting until all reached +; the loop. +;------------------------------------------------------------------------------------------- +synch_all: + mov eax,[logical_info_page+numb_proc] + lock inc ds:[logical_info_page+prc_sema] + DO + cmp al,ds:[logical_info_page+prc_sema] + REPEATNZ + OD + ret + + +;------------------------------------------------------------------------------------------- +; startup application processors +;------------------------------------------------------------------------------------------- + +startup_ap: + call prepare_ap_startup ; store proc state (IDTR ,...) to memory + call initiate_startup ; initiate startup ipi + ret + + +;------------------------------------------------------------------------------------------- +; prepare application processor startup +;------------------------------------------------------------------------------------------- +; +; PRECONDITION: ds linear space +; temporarly implementation of startup code: +; store idt, tss, cr3 of BSP to share tables/data with all APs +; +;------------------------------------------------------------------------------------------- + +prepare_ap_startup: + + lea eax,[esp] + mov ds:[apinit_esp],eax + + sidt ds:[apinit_idt_vec] + str ds:[apinit_tss] + mov eax,cr3 + mov ds:[apinit_cr3],eax + + mov ds:[apinit_cs],cs + mov ds:[apinit_ds],ds + + ret + + apinit_esp dd 0 + apinit_idt_vec df 0 + apinit_tss dw 0 + apinit_cr3 dd 0 + +;------------------------------------------------------------------------------------------- +; initiate startup +;------------------------------------------------------------------------------------------- +; initialises and starts up all APs. Startupcode at application_processor_start +; +; PRECONDITION +; ds linear space +; apic initialised +; POSTCONDITION +; +;------------------------------------------------------------------------------------------- + +initiate_startup: + ; set entry point for the ap processor: jump to startup code + sub eax,eax + mov byte ptr ds:[eax],0E9h + mov ebx, offset application_processor_start-3 + mov word ptr ds:[eax+1],bx + + ; enable apic (set software apic enable bit) +; bts ds:[local_apic+apic_icr], 7 ; apic sw enabled + + ; send Init message to all processors (level assert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; send Init message to all processors (level deassert) and delay for 2s + mov ds:[local_apic+apic_icr], apic_init_deassert_msg + 0 + mov ecx, 1000000 + DO + dec ecx + REPEATNZ + OD + + ; now send startup IPI + mov ds:[local_apic+apic_icr], apic_startup_msg + 0 + ;; wait for apic to finish ?? + + mov ecx, 1000000 ; some time + DO + dec ecx + REPEATNZ + OD + + call check_fatal_cpu_exception + + ret + + + +;------------------------------------------------------------------------------------------- +; application processor start +;------------------------------------------------------------------------------------------- +; PRECONDITION +; real mode, interrupts disabled, apic disabled +; POSTCONDITION +; +; +;------------------------------------------------------------------------------------------- + +application_processor_start: + + ; enable debug extension and page size extension for 4 MB pages + mov eax, cr4 + or eax, 16+8 ; bit 4:PSE 3:Debug Extension + mov cr4, eax ; BSP uses large Pages + + ; enable protected mode and paging + + ;; esp setzen + + + ; share page directory with BSP + asp + osp + mov eax,cs:[apinit_cr3] + + mov cr3,eax ; both arguments are always 32 bit + + + + ;load temporary gdt + asp + osp + lgdt fword ptr cs:[ap_gdt_vec] + + mov eax,cr0 + or ax,1 ; set protected mode bit + + osp + bts eax,31 ; set paging flag + + mov cr0,eax + + osp + db 0eah ; jmp far + dd offset ap_protected_mode +apinit_cs dw 0 + + + ap_gdt_vec dw offset ap_temp_end_of_gdt - offset ap_temp_gdt -1 + dd offset ap_temp_gdt + + + + IF kernel_type NE pentium + + user_space_size equ linear_address_space_size + ELSE + user_space_size equ (virtual_space_size + MB4) + + ENDIF + + + align 8 + + ap_temp_gdt dd 0,0 ; 0 descriptor + + descriptor rw32, dpl0, 0, ; 08 : linear_kernel_space + descriptor rw32, dpl3, 0, user_space_size ; 10 : linear space + descriptor xr32, dpl3, 0, user_space_size ; 18 : linear space + + descriptor xr32, dpl0, PM, ; 20 : phys_exec + descriptor rw32, dpl2, PM, ; 29 : phys_mem + + tss_base equ offset cpu_tss_area + tss_size equ offset (iopbm - offset cpu_tss_area + sizeof iopbm) + + descriptor tsseg, dpl0, tss_base, tss_size ; 30 : cpu0_tss + descriptor tsseg, dpl0, tss_base, tss_size ; 38 : cpu0_tss + + ap_temp_end_of_gdt equ $ + + + apinit_ds dw 0 + +;------------------------------------------------------------------------------------- +; application processor protected mode start +;------------------------------------------------------------------------------------- +; PRECONDITION +; cs,ds phys memory, paging disabled, intr disabled +; protected mode +; +; + + +ap_protected_mode: + + aquire_new_processor_number ebx + + lgdt fword ptr ds:[tss_vec] + jmpf32 $+6,(max_cpu+1)*8 + mov eax,(max_cpu+2)*8 + mov ds,eax + + mov es,eax + shl ebx,3 + ltr bx + + lgdt fword ptr ds:[gdt_vec] + + jmpf32 $+6,phys_mem_exec + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + + ;; load ds equal to bsp + + ;; status: PM, Paging, Code segment valid + + lidt ds:[apinit_idt_vec] + + mov esp,[apinit_esp] + add esp,1024 + + call synch_all + + ke 'synched' + +ap_striptease: + + kd____disp <'PROCESSOR STATE SUMMARY',13,10> + + kd____disp <13,10,'DS '> + mov eax,ds + kd____outhex32 + kd____disp <' ESP '> + mov eax,esp + kd____outhex32 + + kd____disp <13,10,'ES '> + mov eax,es + kd____outhex32 + kd____disp <' CR0 '> + mov eax,cr0 + kd____outhex32 + + kd____disp <13,10,'SS '> + mov eax,ss + kd____outhex32 + kd____disp <' CR1 '> + + kd____disp <13,10,'TR '> + str ax + kd____outhex32 + kd____disp <' CR2 '> + mov eax,cr2 + kd____outhex32 + + kd____disp <13,10,' '> + mov eax,0 + kd____outhex32 + kd____disp <' CR3 '> + mov eax,cr3 + kd____outhex32 + + kd____disp <13,10,' '> + mov eax,0 + kd____outhex32 + kd____disp <' CR4 '> + mov eax,cr4 + kd____outhex32 + +ke 'xx' + + jmp $ + + + + ;; precondition: + ;; cs,ds phys memory, paging disabled, intr disabled + ;; protected mode + ;; + ;; + ke 'before dual start' + + cli ; disable interrupts + + jmpf32 $+6,phys_mem_exec ; load cs with pm pl0 rx + mov eax,phys_mem + mov ds,eax ; load ds with pm pl0 rw + mov es,eax + sub eax,eax + mov fs,eax + mov gs,eax + + + ke 'before dual start1' + call ltr_pnr + + ke 'ltr reloaded' + + call enable_paging_mode + + call init_sgmctr + call init_intctr + call init_emuctr + + ke 'after emuctr2' + + call init_cpuctr ; ?? + call init_pagmap ; ?? + + + ke 'before synch' + ; synch + + call init_schedcb + call init_tcbman + call init_dispatcher + + ke 'end dual' + + + + ; load gate descriptor table + + ;; load address of gdt in edi, eax = size (gdt) + ;; lea___pno edi + ;; shl edi,6 ; log 2 gdt size (8*2*4 bytes = 64 bytes) = 6 + ;; mov eax,edi + ;; dec eax + ;; add edi, offset gdt + first_kernel_segment + + + + + ;; load shared tables: gdt, idt, ldt + ;; enter protected mode, enable paging + + ; Do code next: + ; AP Datastructure setup: + ; - control blocks: cpu schedule + ; - establish scheduler lists on APs: ready list soon wakeup + ; + ; - test single processor behaviour on APs + ; - change Systemcall: thread switch + ; - extend IPC critical path + ; - extend thread schedule with dummy functionality: set processor number + ; - Implement Proxies and Mailboxes + ; - Implement send to Proxy + + + + icod ends + code ends +end + diff --git a/l4-x86/smp/lx/kern/atrace.asm b/l4-x86/smp/lx/kern/atrace.asm new file mode 100644 index 0000000..394f6cd --- /dev/null +++ b/l4-x86/smp/lx/kern/atrace.asm @@ -0,0 +1,203 @@ +include l4pre.inc + + + Copyright xxx, L4.ATRACE, 17,01,98, 1 + + + dcode + +;********************************************************************* +;****** ****** +;****** Address Trace Handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 17.01.98 ****** +;****** modified: 17.01.98 ****** +;****** ****** +;********************************************************************* + + + public init_atrace + public trace_phys_addr + + +.nolist + include l4const.inc + include adrspace.inc +.list + + +ok_for x86 + + + +cachelinesize equ 32 + +min_icache_sets equ 32 +min_dcache_sets equ 64 +min_itlb_sets equ 16 +mib_dtlb_sets equ 32 +min_i4Mtlb_sets equ 1 +min_d4Mtlb_sets equ 1 + + + + +instr_access equ 001b +read_access equ 010b +write_access equ 100b + + +nil_precache_entry equ 0 + + + + log2 + +log2_cachelinesize equ log2_ + + + + align 16 + + +atrace_data_area equ $ + +atrace_counter dd 0,0 +btrace_counter dd 0,0 + +btrace_pointer dd 0 +btrace_begin dd 0 +btrace_end dd 0 + + + align 16 + + +i_precache dd min_icache_sets dup (0) + +d_precache dd min_dcache_sets dup (0) + + + + + + + assume ds:codseg + + + +init_atrace: + + mov [btrace_end],MB16 + ret + + + + + +;---------------------------------------------------------------------------- +; +; trace physical address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX physical EIP AND FFFFFFE0 + instr access / nil +; ECX physical data address AND FFFFFFE0 + data access / nil +; +;---------------------------------------------------------------------------- + + + +trace_phys_addr: + + push ebp + push esi + push edi + +X equ offset atrace_data_area + + mov ebp,offset atrace_data_area+PM + + mov esi,ebx + shr esi,log2_cachelinesize + + inc dword ptr ss:[ebp+atrace_counter-X] + xc z,inc_atrace_high + + mov edi,esi + and esi,sizeof d_precache/4-1 + and edi,sizeof i_precache/4-1 + add esi,offset d_precache-X + add edi,offset i_precache-X + test ebx,instr_access + IFNZ + mov eax,esi + mov edi,esi + mov esi,eax + FI + + mov eax,ss:[edi*4+ebp] + xor eax,ebx + cmp eax,cachelinesize + xc b,flush_alternate_precache_line + + mov eax,ss:[esi*4+ebp] + xor eax,ebx + CORAE eax,cachelinesize + mov edi,ebx + or ebx,eax + IFNZ ebx,edi + mov [esi*4+ebp],ebx + mov edi,ss:[ebp+btrace_pointer-X] + + inc dword ptr ss:[ebp+btrace_counter-X] + xc z,inc_btrace_high + + ;; mov ss:[edi],ebx + add edi,4 + IFAE edi,ss:[ebp+btrace_end-X] + mov edi,ss:[ebp+btrace_begin-X] + FI + mov ss:[ebp+btrace_pointer-X],edi + FI + + pop edi + pop esi + pop ebp + ret + + + + + +XHEAD flush_alternate_precache_line + + sub eax,eax + mov [edi*4+ebp],eax + xret + + + +XHEAD inc_atrace_high + + inc dword ptr ss:[ebp+atrace_counter+4-X] + xret + + +XHEAD inc_btrace_high + + inc dword ptr ss:[ebp+btrace_counter+4-X] + xret + + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/smp/lx/kern/boot.asm b/l4-x86/smp/lx/kern/boot.asm new file mode 100644 index 0000000..cb495b8 --- /dev/null +++ b/l4-x86/smp/lx/kern/boot.asm @@ -0,0 +1,323 @@ +include l4pre.inc + + + +;********************************************************************* +;****** ****** +;****** LN BOOTER ****** +;****** ****** +;****** Author: Jochen Liedtke ****** +;****** ****** +;****** created: 16.03.98 ****** +;****** modified: 14.04.98 ****** +;****** ****** +;********************************************************************* + + + +.nolist +include l4const.inc +include kpage.inc +.list + + + +strt16 segment para public use16 'code' + + + ; MS DOS function calls + +set_dta equ 1Ah +open_file equ 0Fh +read_seq equ 14h +display_str equ 09h +terminate equ 00h + + + ; ELF codes + +executable_file equ 2 +em_386 equ 3 + +e_header struc + e_magic dd 0,0,0,0 + e_type dw 0 + e_machine dw 0 + dd 0 + e_entry dd 0 + e_phoff dd 0 +e_header ends + +p_header struc + dd 0 + p_offset dd 0 + p_vaddr dd 0 + dd 0 + p_filesz dd 0 + p_memsz dd 0 +p_header ends + + + + + + + org 100h + + + assume ds:c16seg + + +start: + + mov ax,cs + mov ds,ax + mov ss,ax + mov sp,offset stack + + + mov dx,offset ln_buffer + mov ah,set_dta + int 21h + + mov dx,offset ln_fcb + mov ah,open_file + int 21h + + mov dx,offset ln_open_failed + test al,al + jnz boot_error + + mov ax,[ln_file_size] + mov [ln_buffer_len],ax + + mov dx,offset ln_fcb + mov ah,read_seq + int 21h + + mov dx,offset ln_read_error + test al,al + jnz boot_error + + + + push ds + mov ax,ds + add ax,KB64/16 + mov ds,ax + mov dx,offset root_buffer-KB64 + mov ah,set_dta + int 21h + pop ds + + mov dx,offset root_fcb + mov ah,open_file + int 21h + + mov dx,offset root_open_failed + test al,al + jnz boot_error + + mov ax,[root_file_size] + mov [root_buffer_len],ax + + mov dx,offset root_fcb + mov ah,read_seq + int 21h + + mov dx,offset root_read_error + test al,al + jnz boot_error + + + mov ax,ds + add ax,KB64/16 + mov es,ax + mov bp,root_buffer-KB64 + + CORNZ es:[bp+e_magic],464C457Fh ; 7Fh,ELF + CORNZ es:[bp+e_type],executable_file + IFNZ es:[bp+e_machine],em_386 + mov dx,offset no_elf + jmp boot_error + FI + mov ecx,es:[bp+e_entry] ; EBX begin addr + add bp,word ptr es:[bp+e_phoff] ; ECX start addr + mov edx,es:[bp+p_offset] ; EDX offset in elf file + mov esi,es:[bp+p_filesz] + mov edi,es:[bp+p_memsz] + mov ebx,es:[bp+p_vaddr] + + pushad + mov ecx,edi + sub ecx,esi + movzx edi,bp + add edi,esi + add edi,edx + mov ax,es + movzx eax,ax + shl eax,4 + add eax,edi + mov edi,eax + and edi,0Fh + shr eax,4 + mov es,ax + mov al,0 + cld + rep stosb + popad + + mov di,offset ln_buffer+200h+1000h ; kernel info page + lea eax,[ebx+edi] + mov [di+booter_ktask].ktask_stack,eax + mov [di+booter_ktask].ktask_start,ecx + mov [di+booter_ktask].ktask_begin,ebx + mov [di+booter_ktask].ktask_end,eax + mov [di+dedicated_mem1].mem_begin,ebx + mov [di+dedicated_mem1].mem_end,eax + + mov eax,ds + shl eax,4 + add eax,root_buffer + add eax,edx + mov [source_descr+2],ax + shr eax,16 + mov byte ptr [source_descr+4],al + mov byte ptr [source_descr+7],ah + + mov eax,ebx + mov [target_descr+2],ax + shr eax,16 + mov byte ptr [target_descr+4],al + mov byte ptr [target_descr+7],ah + + push ds + pop es + mov si,offset bios_gdt + mov cx,[root_file_size] + shr cx,1 + mov ah,87h + int 15h + + + mov dx,offset mov_failed + jc boot_error + + + + + + cli + push cs + pop ax + mov bx,offset ln_buffer+200h + shr bx,4 + add ax,bx + push ax + push 100h + retf + + +boot_error: + DO + push dx + mov bx,dx + mov dl,[bx] + cmp dl,'$' + EXITZ + mov ah,6 + int 21h + pop dx + inc dx + REPEAT + OD + pop dx + + mov ah,terminate + int 21h + + + +ln_open_failed db 'LN.EXE open failed$' +ln_read_error db 'LN.EXE read error$' +root_open_failed db 'ROOT.ELF open failed$' +root_read_error db 'ROOT.ELF read error$' +no_elf db 'no executable elf$' +mov_failed db 'mov failed$' + + align 4 + +ln_fcb db 0 + db 'LN ' + db 'EXE' + dw 0 +ln_buffer_len dw 80h +ln_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + align 4 + +root_fcb db 0 + db 'ROOT ' + db 'ELF' + dw 0 +root_buffer_len dw 80h +root_file_size dw 0,0 + db 0,0 + db 0,0 + dd 0,0 + db 0 + dd 0 + + + align 4 + +bios_gdt dd 0,0 + + dd 0,0 + +source_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + +target_descr dw 0FFFFh + dw 0 + db 0 + db 0F3h + db 0Fh + db 0 + + dd 0,0 + + dd 0,0 + + + + align 4 + + + dw 128 dup (0) +stack dw 0 + + + + align 16 + +ln_buffer: jmp $ + + +root_buffer equ (offset ln_buffer+KB64) + + + + + strt16 ends + code ends + end start diff --git a/l4-x86/smp/lx/kern/bugs b/l4-x86/smp/lx/kern/bugs new file mode 100644 index 0000000..bb5c3c8 --- /dev/null +++ b/l4-x86/smp/lx/kern/bugs @@ -0,0 +1,3 @@ +There is a bug in the MP case when switching an address space in IPC. + - Might be that the wrong page table is loaded => tripple fault. + diff --git a/l4-x86/smp/lx/kern/contents b/l4-x86/smp/lx/kern/contents new file mode 100644 index 0000000..61b8c4b --- /dev/null +++ b/l4-x86/smp/lx/kern/contents @@ -0,0 +1,31 @@ + +Contents of \kernel: + + +adrsman Address-Space Manager creates/deletes Adress Spaces, SC task +cpuctr CPU Controller thread switch, FPU, CPU init, Debug-Reg emulation +dispatch Dispatcher dispactching, timer intr, SC thread_switch, SC thread_schedule +emuctr Emulation Controller decodes instructions to be emulated (LLIDT, MOV DRn,...) +intctr Interrupt Controller IDT init, handles all non-kernel relevant exceptions +ipcman IPC Manager SC ipc, device interrupts, SC nearest +kernel Kernel Version contains only the kernel version +memctr Memory Controller initial rudimentory memory manager, before pagctr is up +pagctr Page Controller init paged mode, gen kernel regions, maintains free PTAB pool +pagfault Page Fault Handler page faults +pagmap Page Mapper map, grant, SC unmap +sgmctr Segment Controller init segments +start Start initializes all LN components, starts LN +start Start on PC PC-specific: ifc to booter, enter prot mode, clock,PIC,NMI +tcbman TCB Manager tcb create/delete, SC lthread_ex_regs +yoonseva BIOS interface special solution for calling BIOS-16 routines + +sigma0 Sigma 0 + +ktest Kernel Test Root Server for kernel test + +kdebug Kernel Debug +kdio Kernel-Debug IO + + + +Only the mentioned files and this file of \kernel are supported. \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/cpuctr.asm b/l4-x86/smp/lx/kern/cpuctr.asm new file mode 100644 index 0000000..8bc32c0 --- /dev/null +++ b/l4-x86/smp/lx/kern/cpuctr.asm @@ -0,0 +1,1323 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.CPUCTR, 24,08,99, 68, K + + +;********************************************************************* +;****** ****** +;****** CPU Controller ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 24.08.99 ****** +;****** ****** +;********************************************************************* + + + + public determine_processor_type + public init_cpuctr + public switch_context + public tunnel_to + public deallocate_ressources_int + public deallocate_ressources_ipc + public refresh_reallocate + public debug_exception_handler + public detach_coprocessor + public emu_load_dr + public emu_store_dr + public cpuctr_rerun_thread + public machine_check_exception + public init_apic + public apic_millis_per_pulse + public apic_micros_per_pulse + public pre_paging_cpu_feature_flags + + + extrn switch_thread_ipc_ret:near + extrn switch_thread_int_ret:near + extrn define_idt_gate:near + extrn exception:near + extrn apic_timer_int:near + extrn wait_for_one_second_tick:near + extrn irq8_intr:abs + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +.list +include cpucb.inc +.nolist +include apic.inc +include intrifc.inc +include schedcb.inc +include kpage.inc +.list + + +ok_for x86 + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + +pe_bit equ 0 +mp_bit equ 1 +em_bit equ 2 +ts_bit equ 3 + +ne_bit equ 5 +wp_bit equ 16 +am_bit equ 18 +nw_bit equ 29 +cd_bit equ 30 +pg_bit equ 31 + + + +;---------------------------------------------------------------------------- +; +; determine processor type +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +pre_paging_cpu_label db 8 dup (0) +pre_paging_cpu_type db 0 + db 0,0,0 +pre_paging_cpu_feature_flags dd 0 + + + + + + +determine_processor_type: + + mov dword ptr ds:[pre_paging_cpu_label],' 68 ' + mov dword ptr ds:[pre_paging_cpu_label+4],' ' + + mov ds:[pre_paging_cpu_feature_flags],0 + + ; xor alignment check flag and id flag in Eflags register + pushfd + pop eax + mov ebx,eax + xor eax,(1 SHL ac_flag) + (1 SHL id_flag) + push eax + popfd + pushfd + pop eax + xor eax,ebx + + ; if alignment check flag not set + test eax,1 SHL ac_flag + IFZ + ; set cpu label to 386 + mov ds:[pre_paging_cpu_label],'3' + mov ds:[pre_paging_cpu_type],i386 + + ; else if **** + ELIFZ eax,<(1 SHL ac_flag)> + + mov ds:[pre_paging_cpu_label],'4' + mov ds:[pre_paging_cpu_type],i486 + + ELSE_ + ; else + ; read model type with cpuid + mov eax,1 + cpuid + + ; set cpu type + mov cl,ah + shl cl,4 + mov ch,al + shr ch,4 + or cl,ch + + mov ds:[pre_paging_cpu_type],cl + + ; set cpu label + and ah,0Fh + add ah,'0' + mov ds:[pre_paging_cpu_label],ah + mov ah,al + and ah,0Fh + add ah,'0' + shr al,4 + add al,'A'-1 + mov word ptr ds:[pre_paging_cpu_label+6],ax + + ; set cpu feature flags + IFB_ cl,pentium + btr edx,enhanced_v86_bit + FI + mov ds:[pre_paging_cpu_feature_flags],edx + + FI + + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; init cpu controller +; +;---------------------------------------------------------------------------- + + assume ds:codseg + + icode + + +init_cpuctr: + + ; clear cpu control block + mov edi,offset cpu_cb + mov ecx,sizeof cpu_cb + mov al,0 + cld + rep stosb + + + +;---------------------------------------------------------------------------- +; +; get processor type +; +;---------------------------------------------------------------------------- + + + mov eax,dword ptr ds:[pre_paging_cpu_label+PM] + mov dword ptr ds:[cpu_label],eax + mov eax,dword ptr ds:[pre_paging_cpu_label+4+PM] + mov dword ptr ds:[cpu_label+4],eax + + mov al,ds:[pre_paging_cpu_type+PM] + mov ds:[cpu_type],al + + mov eax,ds:[pre_paging_cpu_feature_flags] + mov ds:[cpu_feature_flags],eax + + + + mov eax,cr0 + btr eax,am_bit + btr eax,nw_bit + btr eax,cd_bit + mov cr0,eax + + + mov cl,no87 + + fninit + push -1 + fnstsw word ptr ss:[esp] + pop eax + IFZ al,0 + push eax + fnstcw word ptr ss:[esp] + pop eax + and eax,103Fh + CANDZ eax,3Fh + + mov cl,i387 + + FI + mov ds:[co1_type],cl + + + lno___prc eax + + mov ds:[cpu_no],al + + mov ds:[cpu_iopbm],offset iopbm - offset cpu_tss_area + + mov ds:[cpu_ss0],linear_kernel_space + +; add eax,cpu0_tss +; ltr ax ;;; + + ; define debug exception handler + lno___prc eax + IFZ eax,1 + mov bl,debug_exception + mov bh,3 SHL 5 + mov eax,offset debug_exception_handler + call define_idt_gate + FI + + ; enable io breakpoint + bt ds:[cpu_feature_flags],io_breakpoints_bit + IFC + mov eax,cr4 + bts eax,cr4_enable_io_breakpoints_bit + mov cr4,eax + FI + + + bt ds:[cpu_feature_flags],machine_check_exception_bit + IFC + ; set idt gate for machine check exception + lno___prc eax + IFZ eax,1 + mov bl,machine_check + mov bh,0 SHL 5 + mov eax,offset machine_check_exception + + call define_idt_gate + FI + + DO + mov ecx,1 + rdmsr ; resets machine check type + test al,1 + REPEATNZ + OD + + mov eax,cr4 + bts eax,cr4_enable_MC_exception_bit + ;;;;;; Thinkpad (755?) bug: HW coninuously raises MC exception + ;;;;;; mov cr4,eax + FI + + + call init_numctr + + ; if cpu type is less than 486 enter kernel debugger with error message + mov al,ds:[cpu_type] + IFB_ al,i486 + ke '-at least 486 required' + FI + + ; set write protect bit (allow pl0 to write to pl3 pages) + mov eax,cr0 + bts eax,wp_bit + mov cr0,eax + + ; if bootstrap + lno___prc eax + IFZ eax,1 + ; wait for two second ticks and measure time in between + call wait_for_one_second_tick + rdtsc + mov ecx,eax + mov edi,edx + call wait_for_one_second_tick + rdtsc + + ; compute cpu frequency and store it in kernel info page + sub eax,ebx + mov ds:[logical_info_page+cpu_clock_freq],eax + FI + + + ret + + + + + +;---------------------------------------------------------------------------- +; +; APIC initialization +; +;---------------------------------------------------------------------------- + + +apic_millis_per_pulse equ 1 +apic_micros_per_pulse equ apic_millis_per_pulse * 1000 + + + +init_apic: + ; define idt gate for apic timer interrupt + lno___prc eax + IFZ eax,1 + mov bl,irq8_intr + mov bh,0 SHL 5 + mov eax,offset apic_timer_int + call define_idt_gate + FI + + ; reallocate apicbase on PPros + IFAE ds:[cpu_type],ppro + + mov ecx,27 ; apicbase for PentiumPro + rdmsr + and eax,KB4-1 + add eax,0FEE00000h + wrmsr + FI + + ; reset apic id to processor id + mov eax,ds:[local_apic+apic_id] + and eax,0F000000h + lno___prc ebx + shl ebx,24 + add eax,ebx + + ke 'eax apic id' + mov ds:[local_apic+apic_id],eax + + + ; set apic timer devide to by 1 + mov ds:[local_apic+apic_timer_divide],1011b ; divide by 1 + + ; initialise apic timer + mov edi,1000000 + mov ds:[local_apic+apic_timer_init],edi + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + lno___prc eax + IFZ eax,1 + + ; compute bus clock frequency and update logical kernel info page + rdtsc + mov ebx,eax + + mov ecx,10000 + DO + dec ecx + REPEATNZ + OD + + mov esi,ds:[local_apic+apic_timer_curr] + sub edi,esi + rdtsc + sub eax,ebx + + imul eax,10 + mov ebx,edi + shr ebx,5 + add eax,ebx + sub edx,edx + div edi + + mov ebx,eax + mov eax,ds:[logical_info_page+cpu_clock_freq] + imul eax,10 + sub edx,edx + div ebx + mov ds:[logical_info_page+bus_clock_freq],eax + + FI + + ; initialise apic timer interrupt + mov eax,ds:[logical_info_page+bus_clock_freq] + add eax,500 + mov ebx,1000 + sub edx,edx + div ebx + mov ds:[local_apic+apic_timer_init],eax + + ; define IDT gate for apic error handler + lno___prc eax + IFZ eax,1 + mov eax,offset apic_error_handler + mov bl,apic_error + mov bh,0 SHL 5 + call define_idt_gate + FI + + ; enable any epic errors + sub eax,eax + mov ds:[local_apic+apic_error_mask],eax + add eax,apic_error + mov ds:[local_apic+apic_error],eax + + ; enable apic + mov eax,ds:[local_apic+apic_svr] + or ah,1 + mov ds:[local_apic+apic_svr],eax + + ; enable timer interrupt + mov ds:[local_apic+apic_LINT_timer],(1 SHL 17) + irq8_intr + + ret + + + + icod ends + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + + +;---------------------------------------------------------------------------- +; +; switch context +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) +; EBX actual thread (tcb write addr) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,ESI values loaded by source thread +; EAX,EDX,EDI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- + + + + + klign 16 + + + +switch_context: + + ; switch thread context + switch_thread con,ebx + + ; load task number (tcb shr task_no) + shr ebp,task_no + + ; switch address space + switch_space + + ret + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + +;---------------------------------------------------------------------------- +; +; tunnel to +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination thread (tcb write addr) (must be locked_running!) +; EDI actual thread (tcb write addr) (must be locked_waiting!) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX values loaded by source thread +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + + +;############################################################################# + +tunnel_to: + + pop ecx + + switch_thread tunnel,edi + + push eax + + or [edi+fine_state],nready + and [ebp+fine_state],NOT nready + + pop eax + + mov esi,ebp + shr ebp,task_no + + push ds + switch_space ; switch space may load user_linear space into ds + pop ds + + mov ebp,esi + + jmp ecx + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;---------------------------------------------------------------------------- +; +; deallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; [EBX+ressources] ressources used by actual thread +; +; DS linear space +; SS linear space PL0 +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ressources switched and updated +; +;---------------------------------------------------------------------------- +; Semantics of ressources: +; +; Ressources are: comX_space extensions (next 4MB areas) +; numeric coprocessor +; debug register +; M4 lock +; M4 exec lock +; +;---------------------------------------------------------------------------- + + + + align 16 + +deallocate_ressources_tunnel: + ; push return address and jump to deallocate resources + push offset switch_thread_tunnel_ret + jmp short deallocate_ressources + + +deallocate_ressources_con: + ; edi = ebx + mov edi,ebx + ; push return address and jump to deallocate resources + push offset switch_thread_con_ret + jmp short deallocate_ressources + + +deallocate_ressources_int: + ; edi = ebx + mov edi,ebx + ; push return address and jump to deallocate resources + push offset switch_thread_int_ret + jmp short deallocate_ressources + + +deallocate_ressources_ipc: + ; push return address and jump to deallocate resources + push offset switch_thread_ipc_ret + + +deallocate_ressources: + + push eax + + ; edi = tcb address of thread + + ; if numeric coprocessor is used + test [edi+ressources],mask x87_used + IFNZ + ; set task switch bit to delay save of FPU state until next usage + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + ; set numeric coprocessor to unused + and [edi+ressources],NOT mask x87_used + IFZ + ; return if no other resources are currently in usage + pop eax + ret + FI + FI + + ; if com space used + test [edi+ressources],mask com_used + IFNZ + ; clear com_0 and com_1 base in page dir + sub eax,eax + mov ds:[pdir+(com0_base SHR 20)],eax + mov ds:[pdir+(com0_base SHR 20)+4],eax + mov ds:[pdir+(com1_base SHR 20)],eax + mov ds:[pdir+(com1_base SHR 20)+4],eax + + ; load task number (tcb shr task_no) + mov eax,ebp + shr eax,task_no + + ; mov eax,[(eax*8)+task_proot-(offset tcb_space SHR (task_no-3))] + ; load task_page root entry + and eax,0FFh ;taskno in lower bytes + shl eax, max_cpu + push edi + lno___prc edi + add eax, edi + pop edi + mov eax,[(eax*8)+task_proot-8] + + ; (if current page directory above physical kernel memory size) or equal to cpu_cr3 + CORA eax, + IFZ ds:[cpu_cr3],eax + ; flush tlb + mov eax,cr3 + mov cr3,eax + FI + + ; set resources to com unused + and [edi+ressources],NOT mask com_used + IFZ + ; return if no other resources are in use + pop eax + ret + FI + FI + + ; if debug registers are unused and no breakpoints enabled + test [edi+ressources],mask dr_used + CORZ + mov eax,dr7 + test al,10101010b + IFNZ + ; return + pop eax + ret + + FI + + ; reset and store dr6 + mov eax,dr6 + and ax,0F00Fh + or al,ah + mov [edi+thread_dr6],al + ; clear any user level breakpoints + sub eax,eax + mov dr7,eax + + pop eax + pop edi + + ; push return information + pushfd + push cs + push offset reallocate_ressources_by_popebp_iretd + push offset reallocate_ressources_by_ret + + push edi + ; load tcb address + mov edi,esp + and edi,-sizeof tcb + ret + + + + + + +;---------------------------------------------------------------------------- +; +; reallocate ressources +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; REGs scratch +; +; ressources reestablished +; +;---------------------------------------------------------------------------- + + + +reallocate_ressources_by_popebp_iretd: + + ; reallocate ressources + call reallocate_ressources + + ; return from interrupt + pop ebp + iretd + + + + + +reallocate_ressources_by_ret: + + add esp,3*4 + + + +reallocate_ressources: + + push eax + push ebx + + ; load current tcb + mov ebp,esp + and ebp,-sizeof tcb + + ; load resources mask + mov al,[ebp+ressources] + + ; if debg register are used + test al,mask dr_used + IFNZ + ; reload debug registers + call reload_debug_registers + ; reload dr6 + mov al,[ebp+thread_dr6] + mov ah,al + mov dr6,eax + + FI + + pop ebp + pop eax + ret + + + + + + kcod ends + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + +;---------------------------------------------------------------------------- +; +; refresh reallocate +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr (thread must be existent) +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +refresh_reallocate: + + push eax + + ; if thread is in kernel mode (esp points inside tcb) + mov eax,esp + sub eax,ebp + IFAE eax, + + ; cand debug reisters are used + test [ebp+ressources],mask dr_used + CANDNZ + ; cand user thread pointer != offset reallocate_ressouces_by_ret + mov eax,[ebp+thread_esp] + CANDNZ , + + ; push reallocate resources by ret on stack + sub eax,4*4 + mov dword ptr ds:[eax],offset reallocate_ressources_by_ret + mov dword ptr ds:[eax+4],offset reallocate_ressources_by_popebp_iretd + mov dword ptr ds:[eax+8],cs + mov dword ptr ds:[eax+12],0 + + ; reload stack pointer + mov [ebp+thread_esp],eax + FI + + + pop eax + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; cpuctr rerun thread (called when rerunning a thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb addr +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reallocate vec reestablished if necessary +; +;---------------------------------------------------------------------------- + + +cpuctr_rerun_thread: + + ret + + + + +;********************************************************************* +;****** ****** +;****** Debug Register Handling ****** +;****** ****** +;********************************************************************* + + +;---------------------------------------------------------------------------- +; +; debug exception handler +; +;---------------------------------------------------------------------------- + + +debug_exception_handler: + + ipre debug_ec,no_load_ds + + ; if bit 2 of dr7 is clear and comes from kernel code and vm flag is clear + mov eax,dr7 + test al,10b + IFZ + CANDZ [esp+ip_cs],phys_mem_exec + test byte ptr ss:[esp+ip_eflags+2],(1 SHL (vm_flag-16)) + CANDZ + ; ignore debug exception + bts [esp+ip_eflags],r_flag ; ignore DB exc if in kernel + ipost ; and no kernel (global) + FI ; breakpoint + ; else enter kernel debugger + mov al,debug_exception + jmp exception + + + + +;---------------------------------------------------------------------------- +; +; reload debug register from tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; DR0..3, DR7 reloaded +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + + +reload_debug_registers: + + push eax + + ; if debug register 7 is not used + mov eax,dr7 + test al,10101010b + IFZ + ; if any debug register were used previously by this thread + mov eax,ss:[ebp+thread_dr0+7*4] + and al,01010101b + IFNZ + ; mark ressource debug register used + mark__ressource ebp,dr_used + + ; load all debug registers + mov dr7,eax + mov eax,ss:[ebp+thread_dr0+0*4] + mov dr0,eax + mov eax,ss:[ebp+thread_dr0+1*4] + mov dr1,eax + mov eax,ss:[ebp+thread_dr0+2*4] + mov dr2,eax + mov eax,ss:[ebp+thread_dr0+3*4] + mov dr3,eax + ELSE_ + ; unmark ressource debug register used + unmrk_ressource ebp,dr_used + ; clear dr7 + sub eax,eax + mov dr7,eax + FI + FI + + + pop eax + ret + + + + + + +;---------------------------------------------------------------------------- +; +; emulate load/store debug register +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX instruction SHR 8 +; EBP tcb write addr +; EDI REG addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +emu_load_dr: + + push ecx + + ; compute register address in tcb + mov cl,ah + xor cl,7 + and ecx,7 + mov ecx,ss:[edi+(ecx*4)] + + shr eax,19-8 + and eax,7 + + ; load debug register + CORZ al,7 + IFBE al,3 + CANDB ecx, + mov ss:[(eax*4)+ebp+thread_dr0],ecx + call reload_debug_registers + + ELIFZ al,6 + mov dr6,ecx + FI + + mov al,3 + + pop ecx + ret + + + +emu_store_dr: + + push ecx + + ; store debug register + mov ecx,eax + shr ecx,19-8 + and ecx,7 + + IFZ cl,6 + mov ecx,dr6 + ELSE_ + mov ecx,ss:[ebp+(ecx*4)+thread_dr0] + + FI + + mov al,ah + xor al,7 + and eax,7 + mov ss:[edi+(eax*4)],ecx + + mov al,3 + + pop ecx + ret + + + + + + + +;********************************************************************* +;****** ****** +;****** Floating Point Unit Handling ****** +;****** ****** +;********************************************************************* + + + + +;---------------------------------------------------------------------------- +; +; init numeric devices and controller +; +;---------------------------------------------------------------------------- + + + icode + + + +init_numctr: + + ; set actual occupying tcb to 0 + mov ds:[actual_co1_tcb],0 + + ; if no coprocessor available + mov al,ds:[co1_type] + IFZ al,no87 + + ; set emulate coprosessor flag and reset monitor coprocessor flag and return + mov eax,cr0 + bts eax,em_bit + btr eax,mp_bit + mov cr0,eax + + ret + FI + + ; define idt gate for numeric coprocessor not available handler + lno___prc eax + IFZ eax,1 + mov bh,0 SHL 5 + mov bl,co_not_available + mov eax,offset co_not_available_handler + call define_idt_gate + FI + + ; reset emulate coprocessor and set monitor coprocessor and task switch flag + mov eax,cr0 + btr eax,em_bit ; 387 present + bts eax,mp_bit + bts eax,ts_bit + mov cr0,eax + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; coprocessor not available handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre +; +;---------------------------------------------------------------------------- +; +; PROC coprocessor not available +; +; IF emulator flag set +; THEN emulate coprocessor instruction +; ELSE schedule coprocessor +; FI . +; +; schedule coprocessor: +; IF actual coprocessor owner <> me +; THEN detach coprocessor ; +; IF first time to use coprocessor by this process +; THEN init coprocessor +; ELSE attach coprocessor +; FI +; FI ; +; clear task switch . +; +; ENDPROC coprocessor not available ; +; +;---------------------------------------------------------------------------- + + + +co_not_available_handler: + + ipre fault + + ; load current tcb + mov ebp,esp + and ebp,-sizeof tcb + + ; clear task switch flag (coprocessor will be available for next task) + clts + ; jump to exception if no coprocessor on board + cmp ds:[co1_type],no87 + mov al,co_not_available + jz exception + + ; if last user of coprocessor != current + mov eax,ds:[actual_co1_tcb] + IFNZ eax,ebp + ; if last user is valid thread + test eax,eax + IFNZ + ; save floating point registers to last user's tcb + fnsave [eax+reg_387] + ; wait for floating point unit to finish + fwait + FI + + ; if floating point unit was not in use before by this thread + IFZ [ebp+reg_387+8],0 ; word 8 (16 bit) or 16 (32 bit) contains + CANDZ [ebp+reg_387+16],0 ; either opcode (V86) or CS <> 0 ! + ; initialise floating point unit + finit + ELSE_ + ; else reload register contents from tcb + frstor [ebp+reg_387] + FI + ; set current tcb to be the actual user of the floating point unit + mov ds:[actual_co1_tcb],ebp + FI + ; mark the floating point unit to be a used ressource of this thread + mark__ressource ebp,x87_used + + ipost + + + + +;---------------------------------------------------------------------------- +; +; detach numeric devices if necessary +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no more atachement of numeric devices to this process +; +;---------------------------------------------------------------------------- + + +detach_coprocessor: + + ; if current tcb is last user of the FPU + IFZ ds:[actual_co1_tcb],ebp + + push eax + + ; clear task switch flag + clts ; clts prevents from INT 7 at fnsave + ; save FPU registers to tcb + fnsave [ebp+reg_387] + ; wait for FPU to complete + fwait + ; set actual FPU user tcb to nil + sub eax,eax + mov ds:[actual_co1_tcb],eax + + ; set task switch bit + mov eax,cr0 + or al,1 SHL ts_bit + mov cr0,eax + + pop eax + FI + + ret + + + +;********************************************************************* +;****** ****** +;****** APIC Error Handling ****** +;****** ****** +;********************************************************************* + + + +apic_error_handler: + + ;; ke 'apic_error' + + iretd + + + + + +;********************************************************************* +;****** ****** +;****** Machine Check Exception ****** +;****** ****** +;********************************************************************* + + + + +machine_check_exception: + + ; disable machine check + mov eax,cr4 + and al,NOT (1 SHL cr4_enable_MC_exception_bit) ; disable machine check + mov cr4,eax + ; load model specific register 0 and 1 and enter kernel debugger + sub ecx,ecx + rdmsr + mov esi,eax + mov edi,edx + inc ecx + rdmsr + + DO + ke '#MC' + REPEAT + OD + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/idecode.asm b/l4-x86/smp/lx/kern/idecode.asm new file mode 100644 index 0000000..6a3760f --- /dev/null +++ b/l4-x86/smp/lx/kern/idecode.asm @@ -0,0 +1,1142 @@ +include lnpre.inc + + + Copyright IBM, LN.IDECODE, 09,02,98, 1 + + dcode + +;********************************************************************* +;****** ****** +;****** Instruction Decoder ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** created: 18.01.98 ****** +;****** modified: 12.02.98 ****** +;****** ****** +;********************************************************************* + + + + public init_idecode + + + extrn trace_eip:near + extrn trace_data:near + extrn define_idt_gate:near + + +.nolist +include lnconst.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include syscalls.inc +.list + + +ok_for pentium,ppro + + +cachelinesize equ 32 + + + + + + +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +debug_exception equ 1 + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +intr_stack struc + + intr_edi dd 0 + intr_esi dd 0 + intr_ebp dd 0 + dd 0 + intr_ebx dd 0 + intr_edx dd 0 + intr_ecx dd 0 + intr_eax dd 0 + + intr_eip dd 0 + intr_cs dw 0,0 + intr_eflags dd 0 + intr_esp dd 0 + intr_ss dw 0,0 + +intr_stack ends + + + + +idt_descriptor df 0 + +idecode_idt_descriptor df 0 + + + + + +opcode_type record opc_type:4,data_width:2,access_type:2 + + +mod_rm equ 0 SHL opc_type +dir_mem equ 1 SHL opc_type +pushx equ 2 SHL opc_type +popx equ 3 SHL opc_type +esi_access equ 4 SHL opc_type +edi_access equ 5 SHL opc_type +esi_edi_acc equ 6 SHL opc_type + +group1_4 equ 8 SHL opc_type +group4_8 equ 9 SHL opc_type + +special equ 13 SHL opc_type +prefix equ 14 SHL opc_type +_0F equ 15 SHL opc_type + + +opc_handler dd mod_rm_handler + dd dir_mem_handler + dd pushx_handler + dd popx_handler + dd esi_handler + dd edi_handler + dd esi_edi_handler + dd 0 + dd group1_4_handler + dd group5_8_handler + dd 0 + dd 0 + dd 0 + dd special_opcode + dd prefix_opcode + dd _0F_handler + + + + + +byte_operand equ 0 SHL data_width +word_operand equ 1 SHL data_width +dword_operand equ 2 SHL data_width +qword_operand equ 3 SHL data_width + +read_access equ 01b +write_access equ 10b + + + +___ equ 0 + +r__ equ read_access +w__ equ write_access +x__ equ read_access+write_access + +rEb equ mod_rm+byte_operand+read_access +rEw equ mod_rm+word_operand+read_access +rEv equ mod_rm+dword_operand+read_access +rEq equ mod_rm+qword_operand+read_access +wEb equ mod_rm+byte_operand+write_access +wEw equ mod_rm+word_operand+write_access +wEv equ mod_rm+dword_operand+write_access +xEb equ mod_rm+byte_operand+read_access+write_access +xEv equ mod_rm+dword_operand+read_access+write_access + +rDb equ dir_mem+byte_operand+read_access +rDv equ dir_mem+dword_operand+read_access +wDb equ dir_mem+byte_operand+write_access +wDv equ dir_mem+dword_operand+write_access + +Uv equ pushx+dword_operand +Ov equ popx+dword_operand +UEv equ pushx+dword_operand+read_access +OEv equ popx+dword_operand+write_access +Uq equ pushx+qword_operand +Oq equ popx+qword_operand +UEq equ pushx+qword_operand+read_access +OEq equ popx+qword_operand+write_access + +rXb equ esi_access+byte_operand+read_access +rXv equ esi_access+dword_operand+read_access +rYb equ edi_access+byte_operand+read_access +rYv equ edi_access+dword_operand+read_access +wYb equ edi_access+byte_operand+write_access +wYv equ edi_access+dword_operand+write_access +rZb equ esi_edi_acc+byte_operand+read_access +rZv equ esi_edi_acc+dword_operand+read_access +xZb equ esi_edi_acc+byte_operand+write_access+read_access +xZv equ esi_edi_acc+dword_operand+write_access+read_access + +Eb1 equ group1+byte_operand +Ev1 equ group1+dword_operand +Eb2 equ group2+byte_operand +Ev2 equ group2+dword_operand +Eb3 equ group3+byte_operand +Ev3 equ group3+dword_operand +gr4 equ group4 +gr5 equ group5 +gr6 equ group6 +gr7 equ group7 +gr8 equ group8 + + + +group1 equ group1_4+00b +group2 equ group1_4+01b +group3 equ group1_4+10b +group4 equ group1_4+11b +group5 equ group4_8+00b +group6 equ group4_8+01b +group7 equ group4_8+10b +group8 equ group4_8+11b + + +_xx equ prefix+1 +_cs equ prefix+2 +_ss equ prefix+3 +_ds equ prefix+4 +_es equ prefix+5 +_fs equ prefix+6 +_gs equ prefix+7 + + +prefix_handler dd 0 + dd _xx_handler + dd _cs_handler + dd _ss_handler + dd _ds_handler + dd _es_handler + dd _fs_handler + dd _gs_handler + + + + + +Ua equ special+0 ; pusha +Oa equ special+1 ; popa +Of equ special+2 ; popf +it3 equ special+3 ; int 3 +itn equ special+4 ; int n +ito equ special+5 ; into +bnd equ special+6 ; bound +irt equ special+7 ; iret +xlt equ special+8 ; xlat +fD9 equ special+9 ; FP D9 +fDB equ special+10 ; FP DB +fDD equ special+11 ; FP DD +fDF equ special+12 ; FP DF +cx8 equ special+13 ; cmpxchg8 + + + + +special_handler dd pusha_handler + dd popa_handler + dd popf_handler + dd int_3_handler + dd int_n_handler + dd into_handler + dd bound_handler + dd iret_handler + dd xlat_handler + dd FP_D9_handler + dd FP_DB_handler + dd FP_DD_handler + dd FP_DF_handler + dd cmpxchg8_handler + + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc1 db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv,_0F ; 00 + db xEb,xEv,rEb,rEv,___,___, Uv, Ov, xEb,xEv,rEb,rEv,___,___, Uv, Ov ; 10 + db xEb,xEv,rEb,rEv,___,___,_es,___, xEb,xEv,rEb,rEv,___,___,_cs,___ ; 20 + db xEb,xEv,rEb,rEv,___,___,_ss,___, rEb,rEv,rEb,rEv,___,___,_ds,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db Uv, Uv, Uv, Uv, Uv, Uv, Uv, Uv, Ov, Ov, Ov, Ov, Ov, Ov, Ov, Ov ; 50 + db Ua, Oa,bnd,___,_fs,_gs,_xx,_xx, Uv,rEv, Uv,rEv,wYb,wYv,rXb,rXv ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db Eb1,Ev1,Ev1,Ev1,rEb,rEv,xEb,xEv, wEb,wEv,rEb,rEv,wEv,___,rEw,OEv ; 80 + db ___,___,___,___,___,___,___,___, ___,___, Uq,___, Uv, Of,___,___ ; 90 + db rDb,rDv,wDb,wDv,xZb,xZv,rZb,rZv, ___,___,wYb,wYv,rXb,rXv,rYb,rYv ; A0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; B0 + db Eb2,Ev2, Ov, Ov,rEq,rEq,wEb,wEv, Uv, Ov, Oq, Oq,it3,itn,ito,irt ; C0 + db Eb2,Ev2,Eb2,Ev2,___,___,___,xlt, rEv,fD9,rEv,fDB,rEq,fDD,rEw,fDF ; D0 + db ___,___,___,___,___,___,___,___, Uv,___,___,___,___,___,___,___ ; E0 + db _xx,___,_xx,_xx,___,___,Eb3,Ev3, ___,___,___,___,___,___,gr4,gr5 ; F0 + + + +; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + +opc2 db gr6,___,___,rEw,___,___,___,___, ___,___,___,___,___,___,___,___ ; 00 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 10 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 20 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 30 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 40 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 50 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 60 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 70 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; 80 + db ___,___,___,___,___,___,___,___, wEb,wEb,wEb,wEb,wEb,wEb,wEb,wEb ; 90 + db Uv, Ov,___,rEv,xEv,xEv,___,___, Uv, Ov,___,xEv,xEv,xEv,___,rEv ; A0 + db xEb,xEv,rEq,xEv,rEq,rEv,rEb,rEw, ___,___,gr8,xEv,rEv,rEv,rEb,rEw ; B0 + db xEb,xEv,___,___,___,___,___,cx8, ___,___,___,___,___,___,___,___ ; C0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; D0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; E0 + db ___,___,___,___,___,___,___,___, ___,___,___,___,___,___,___,___ ; F0 + + +; 000 001 010 011 100 101 110 111 + +grpx db x__,x__,x__,x__,x__,x__,x__,r__ ; 1 + db x__,x__,x__,x__,x__,x__,___,x__ ; 2 + db r__,___,x__,x__,r__,r__,r__,r__ ; 3 + db xEb,xEb,___,___,___,___,___,___ ; 4 + db xEv,xEv,UEv,UEq,rEv,rEq,UEv,___ ; 5 + db wEw,wEw,rEw,rEw,rEw,rEw,___,___ ; 6 + db ___,___,___,___,wEw,___,rEw,___ ; 7 + db ___,___,___,___,rEv,xEv,xEv,xEv ; 8 + + + + + + + +;---------------------------------------------------------------------------------- +; +; instruction decoder +; +;---------------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI instruction address +; EBP pointer to intr_... +; +; +; + + + + +idecode_handler: + + pushad + + mov eax,dr6 + test ah,40h + jnz non_single_step_debug_exception + + call trace_eip + + sub eax,eax + sub edx,edx + + +idecode1: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc1+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +XHEAD decode_sib_byte + + push ecx + + mov al,ds:[esi] + inc esi + + mov cl,al + mov ch,al + shr cl,6 + and al,111b SHL 3 + shr al,3 + and ch,7 + and al,7 + xor ch,7 + xor al,7 + + IFNZ al,100b XOR 7 + mov eax,ss:[eax*4+ebp+intr_edi] + shl eax,cl + add edi,eax + FI + + mov al,ch + + pop ecx + + cmp al,100b XOR 7 + xret nz + + call implicit_ss + xret + + + + + +mod_rm_handler: + + mov al,ds:[esi] + inc esi + + mov dh,al + and al,7 + shr dh,6 + xor al,7 + + IFZ dh,11b + ret + FI + + + sub edi,edi + + cmp al,100b XOR 7 + xc z,decode_sib_byte + + IFZ al,101b XOR 7 + IFZ dh,0 ; no base, 32-bit offset + add edi,ds:[esi] ; + add esi,4 ; + ELSE_ + call implicit_ss ; base: ss:ebp + add edi,ss:[eax*4+ebp+intr_edi] ; + FI ; + ELSE_ + add edi,ss:[eax*4+ebp+intr_edi] ; base: ds:reg + FI ; + + cmp cl,01b + IFZ + movsx edx,byte ptr ds:[esi] ; 8-bit offset + inc esi ; + add edi,edx ; + ELIFA + add edi,ds:[esi] ; 32-bit offset + add esi,4 ; + FI ; + + + + +access_data: + + and edx,-8 + IFZ + mov edx,ds + and edx,-8 + FI + + mov ah,byte ptr ss:[edx+gdt+7] + mov al,byte ptr ss:[edx+gdt+4] + shl eax,16 + mov ax,word ptr ss:[edx+gdt+2] + add edi,eax + + mov cl,ch + and ch,mask access_type + and cl,mask data_width + shr cl,data_width + mov edx,1 + shl edx,cl + add edx,edi + + xor edx,edi + test edx,-cachelinesize + jz trace_data + + call trace_data + add edi,cachelinesize + jmp trace_data + + + + + + + +implicit_ss: + + test dl,dl + jnz short explicit_ss + ret + + + +explicit_ss: + + mov dl,byte ptr ss:[ebp+intr_ss] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + ret + FI + + push eax + mov eax,ss + mov dl,al + pop eax + ret + + + + + + + + + + + + +dir_mem_handler: + + add edi,ds:[esi] + add esi,4 + jmp access_data + + + + + +pushx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + sub edi,4 + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + +popx_handler: + + push ecx + push edx + push edi + + and ch,NOT mask access_type + or ch,read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + call access_data + + pop edi + pop edx + pop ecx + + test ch,mask access_type + jnz mod_rm_handler + + ret + + + + + +esi_handler: + + mov edi,ss:[ebp+intr_esi] + jmp access_data + + + +esi_edi_handler: + + push ecx + push edx + + and ch,NOT mask access_type + or ch,read_access + mov edi,ss:[ebp+intr_esi] + call access_data + + pop edx + pop ecx + + test ch,write_access + IFNZ + and ch,NOT read_access + FI + + +edi_handler: + + mov edx,es + mov edi,ss:[ebp+intr_edi] + jmp access_data + + + + + + + + + + +_0F_handler: + + mov al,ds:[esi] + inc esi + + mov al,ss:[eax+opc2+PM] + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + + +group1_4_handler: + + and ch,11b + jmp short group_n_handler + + + +group5_8_handler: + + and ch,11b + add ch,4 + +group_n_handler: + + shl ch,3 + mov al,ds:[esi] + shr al,3 + and al,7 + add al,ch + mov al,ss:[eax+grpx+PM] + + mov ch,al + shr eax,opc_type + IFNZ ch,___ + jmp ss:[eax*4+opc_handler+PM] + FI + ret + + + + + +prefix_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+prefix_handler+PM] + + + + +_xx_handler: + + ret + + +_ss_handler: + call explicit_ss + jmp idecode1 + + +_ds_handler: + mov edx,ds + jmp idecode1 + +_cs_handler: + mov edx,cs + jmp idecode1 + +_es_handler: + mov edx,es + jmp idecode1 + +_fs_handler: + mov edx,fs + jmp idecode1 + +_gs_handler: + mov edx,gs + jmp idecode1 + + + + + + + + + +special_opcode: + + mov al,ch + and al,0Fh + jmp ss:[eax*4+special_handler+PM] + + + + + + + + +pusha_handler: + + mov ch,qword_operand+write_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + sub edi,2*4 + call access_data + pop edi + pop edx + pop ecx + dec cl + REPEATNZ + OD + ret + + + + +popa_handler: + + mov ch,qword_operand+read_access + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + mov edi,ss:[ebp+intr_esp] + FI + + call explicit_ss + + mov cl,4 + DO + push ecx + push edx + push edi + call access_data + pop edi + pop edx + pop ecx + add edi,2*4 + dec cl + REPEATNZ + OD + ret + + + + +popf_handler: + + CORNZ esi,offset idecode_off_popfd + test byte ptr ss:[ebp+intr_cs],11b + IFNZ + sub eax,eax + call ensure_single_step_on + FI + mov ch,dword_operand + jmp popx_handler + + + + +int_3_handler: + + ke 'int 3' + ret + + +int_n_handler: + + ke 'int n' + ret + +into_handler: + + ke 'into' + ret + + +bound_handler: + + ke 'bound' + ret + + +iret_handler: + + mov eax,2*4 + call ensure_single_step_on + + mov ch,qword_operand + jmp popx_handler + + + +xlat_handler: + + ke 'xlat' + ret + + +FP_D9_handler: +FP_DB_handler: +FP_DD_handler: +FP_DF_handler: + + ke 'FP instr' + ret + + +cmpxchg8_handler: + + ke 'cmpx8' + ret + + + + + + + +ensure_single_step_on: + + lea edi,[ebp+intr_esp] + test byte ptr ss:[ebp+intr_cs],11b + IFZ + or byte ptr ss:[eax+ebp+intr_esp+1],1 SHL (t_flag-8) + ret + FI + + mov edi,ss:[ebp+intr_esp] + or byte ptr ds:[eax+edi+1],1 SHL (t_flag-8) + ret + + + +;-------------------------------------------------------------------------- +; +; init idecoder +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + +init_idecode: + + pushad + + mov edi,offset idecode_idt_descriptor+PM + mov word ptr [edi],idt_entries*8-1 + mov dword ptr [edi+2],offset idecode_idt+PM + + mov edi,offset idecode_idt+PM+(debug_exception*8) + mov dword ptr [edi],offset idecode_handler + mov dword ptr [edi+4],offset idecode_handler+PM + + mov edi,offset idecode_idt+PM + mov ecx,idt_entries + DO + mov word ptr ds:[edi+2],phys_mem_exec + mov word ptr ds:[edi+4],8E00h + add edi,8 + dec ecx + REPEATNZ + OD + + popad + ret + + + +;-------------------------------------------------------------------------- +; +; instruction decode on/off +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +idecode_on: + + sidt ss:[idt_descriptor+PM] + lidt ss:[idecode_idt_descriptor+PM] + + pushfd + or byte ptr ss:[esp+1],1 SHL (t_flag-8) + popfd + + ret + + + +idecode_off: + + pushfd + and byte ptr ss:[esp+1],NOT (1 SHL (t_flag-8)) + idecode_off_popfd: + popfd + + lidt ss:[idt_descriptor+PM] + + ret + + + +non_single_step_debug_exception: + + and ah,NOT 40h + mov dr6,eax + popad + + pushfd + push eax + push ebx + + mov ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx+debug_exception*8] + mov ebx,ss:[ebx+debug_exception*8+4] + + mov bx,ax + shr eax,16 + + xchg ss:[esp+1*4],eax + xchg ss:[esp],ebx + + iretd + + + + + + +.listmacro + + FOR nnn,<0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17> + + idt_call_&nnn: + push nnn + jmp idt_call + endm + +.list + +.nolistmacro + + +idt_call: + + sub esp,2*4 + pushad + + mov ebx,ss:[esp+intr_eflags] + + +idt_call_ebx: + + pushfd + pop eax + or ah,1 SHL (t_flag-8) + mov ss:[esp+intr_eflags],eax + + shl ebx,3 + add ebx,dword ptr ss:[idt_descriptor+2+PM] + + mov eax,ss:[ebx] + mov ebx,ss:[ebx+4] + + test bh,bh +;;; IFS + + mov bx,ax + shr eax,16 + + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + + + + +gp_handler: + + sub esp,2*4 + pushad + + mov eax,dword ptr ss:[esp+8*4] + +;; test al,mask error_code_idt_bit + IFNZ + CANDA ax, + CANDB ax, + +;;; and eax,mask error_code_selector_index + add eax,dword ptr ss:[idt_descriptor+2+PM] + + mov ebx,ss:[eax+4] + mov eax,ss:[eax] + + test bh,bh + IFS + and bh,11b + mov bl,byte ptr ss:[esp+intr_cs+3*4] + shr bh,5 + and bl,11b + IFBE bl,bh + + pushfd + pop ecx + mov ss:[esp+intr_eflags],ecx + mov bx,ax + shr eax,16 + mov dword ptr ss:[esp+intr_cs],eax + mov ss:[esp+intr_eip],ebx + + popad + iretd + FI + ELSE_ + popad + add esp,2*4 + push seg_not_present + jmp idt_call + FI + FI + + popad + add esp,2*4 + push general_protection + jmp idt_call + + + + + + + + + + + + + + + align 16 + +.listmacro + + +idecode_idt dd idt_call_0,idt_call_0+PM + dd idecode_handler,idecode_handler+PM + FOR nnn,<2,3,4,5,6,7,8,9,10,12> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + dd gp_handler,gp_handler+PM + FOR nnn,<14,15,15,16,17> + dd idt_call_&nnn,idt_call_&nnn+PM + endm + +idt_entries equ (($-idecode_idt)/8) + + +.nolistmacro + + + + + + + dcod ends + code ends + end diff --git a/l4-x86/smp/lx/kern/ipcman.asm b/l4-x86/smp/lx/kern/ipcman.asm new file mode 100644 index 0000000..075178d --- /dev/null +++ b/l4-x86/smp/lx/kern/ipcman.asm @@ -0,0 +1,3678 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.IPCMAN, 18,08,99, 9174, K + + +;********************************************************************* +;****** ****** +;****** IPC Manager ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 18.08.99 ****** +;****** ****** +;********************************************************************* + + + public init_ipcman + public init_sndq + public init_intr_control_block + public ipcman_open_tcb + public ipcman_close_tcb + public ipcman_wakeup_tcb + public ipcman_rerun_thread + public restart_poll_all_senders + public detach_intr + public push_ipc_state + public pop_ipc_state + public cancel_if_within_ipc + public get_bottom_state + public ipc_update_small_space_size + public ipc_critical_region_begin + public ipc_critical_region_end + + public ipc_sc + public id_nearest_sc + + + + extrn deallocate_ressources_ipc:near + extrn deallocate_ressources_int:near + extrn switch_context:near + extrn dispatch:near + extrn insert_into_ready_list:near + extrn define_idt_gate:near + extrn mask_hw_interrupt:near + extrn map_fpage:near + extrn grant_fpage:near + extrn translate_address:near + extrn irq0_intr:abs + extrn irq15:abs + extrn rdtsc_clocks:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +.list +include tcb.inc +.nolist +include schedcb.inc +include cpucb.inc +include intrifc.inc +include pagconst.inc +include pagmac.inc +.list +include msg.inc +.nolist +include small-as.inc +include syscalls.inc +include apic.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +;20.02.95 jl: flexpage messages (temp mapping) introduced +; +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; interrupt associated threads +; +;---------------------------------------------------------------------------- + + +intr1_intr0 equ 8 + + + + +intr_control_block struc + + db offset intr_cb dup (?) + + intr_associated_tcb dd intr_sources dup (?) + +intr_control_block ends + + + + +;---------------------------------------------------------------------------- +; +; init intr control block +; +;---------------------------------------------------------------------------- +; +; EAX bit n = 0 : intr usable +; = 1 : intr reserved for kernel +; +;---------------------------------------------------------------------------- + + + icode + + +init_intr_control_block: + + pushad + + sub ecx,ecx + DO + shr eax,1 + sbb ebx,ebx + mov [(ecx*4)+intr_associated_tcb],ebx + + inc ecx + cmp ecx,intr_sources + REPEATB + OD + + popad + ret + + + icod ends + + + +;---------------------------------------------------------------------------- +; +; send ques +; +;---------------------------------------------------------------------------- +; send que INVARIANT: +; +; All tcbs in send ques are present in RAM !!! +; +; (So insert/delete will never induce paging!) +; (Swapping out such a tcb must delete it from the que.) +; +;---------------------------------------------------------------------------- + + + + +;---------------------------------------------------------------------------- +; +; init send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; send que of tcb initialized empty +; +;---------------------------------------------------------------------------- + + +init_sndq: + + push ebp + and [ebp+list_state],NOT is_polled + add ebp,offset sndq_root + mov [ebp].tail,ebp + mov [ebp].head,ebp + pop ebp + ret + + + +;---------------------------------------------------------------------------- +; +; insert last into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EBX tcb of thread to be entered +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EDX,EDI scratch +; +; EBX thread entered into EBP send que +; +;---------------------------------------------------------------------------- + + +insert_last_into_sndq macro + + or [ebp+list_state],is_polled + + lea edi,[ebp+sndq_root] + lea edx,[ebx+sndq_llink] + mov eax,[edi].tail + + mov [edi].tail,edx + mov [edx].pred,eax + mov [eax].succ,edx + mov [edx].succ,edi + + endm + + +;---------------------------------------------------------------------------- +; +; insert intr first into send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP send que, (write addr of tcb) +; EDX intr id +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX,EDX scratch +; +; intr id entered into EDX send que +; +;---------------------------------------------------------------------------- + + +insert_intr_first_into_sndq macro + + or [ebp+list_state],is_polled + + lea edx,[(edx*8)+intrq_llink-8*1] + lea ecx,[ebp+sndq_root] + + mov [edx].pred,ecx + mov eax,[ecx].head + mov [ecx].head,edx + mov [edx].succ,eax + mov [eax].pred,edx + + endm + + +.erre offset intrq_llink GE (offset tcb_space+tcb_space_size) + + + +;---------------------------------------------------------------------------- +; +; get first from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX send que, (write addr of tcb) must not be empty !! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: EDX deleted first thread (tcb write addr), BL undefined ! +; +; NC: EDX deleted first intr (intr_tab_addr) +; +; ECX,ESI scratch +; +;---------------------------------------------------------------------------- + + +get_first_from_sndq macro + + lea esi,[ebx+sndq_root] + mov edx,[esi].head + mov ecx,[edx].succ + + mov [esi].head,ecx + mov [ecx].pred,esi + + IFZ ecx,esi + and [ebx+list_state],NOT is_polled + FI + + cmp edx,offset intrq_llink + + endm + + + + +;---------------------------------------------------------------------------- +; +; test intr in send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg send que, (write addr of tcb) must not be empty !! +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; C: no intr waiting +; +; NC: intr waiting in send que (first position) +; +;---------------------------------------------------------------------------- + + +test_intr_in_sndq macro reg + + cmp [reg+sndq_root],offset intrq_llink + + endm + + + + + +;---------------------------------------------------------------------------- +; +; delete from send que +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr), must be within a snd que! +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,ECX scratch +; +; EBP thread deleted from send que +; +;---------------------------------------------------------------------------- + + +delete_from_sndq macro + + mov eax,[ebp+sndq_llink].succ + mov ecx,[ebp+sndq_llink].pred + + mov [eax].pred,ecx + mov [ecx].succ,eax + + IFZ eax,ecx + and [eax+list_state-offset sndq_root],NOT is_polled + FI + + endm + + + +;---------------------------------------------------------------------------- +; +; join send ques +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb of source sndq (not empty) +; EDI tcb of dest sndq (may be empty) +; +; DS linear space +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI scratch +; +; source sndq empty, old joined to des sndq +; +;---------------------------------------------------------------------------- + + +join_sndqs macro + + and [ebp+list_state],NOT is_polled + or [edi+list_state],is_polled + + lea eax,[edi+sndq_root] + mov ebx,[edi+sndq_root].tail + + lea esi,[ebp+sndq_root] + mov ecx,[esi].head + mov ebp,[esi].tail + + mov [esi].head,esi + mov [esi].tail,esi + + mov [eax].tail,ebp + mov [ebp].succ,eax + mov [ebx].succ,ecx + mov [ecx].pred,ebx + + endm + + + + + + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + kcode + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** Interrupt Handling ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq: + push fault + pushad + mov al,irq + jmp short send_intr + + endm + + +.list + + + + +.erre offset intr_1 - offset intr_0 EQ intr1_intr0 +.erre offset intr_2 - offset intr_1 EQ intr1_intr0 +.erre offset intr_3 - offset intr_2 EQ intr1_intr0 +.erre offset intr_4 - offset intr_3 EQ intr1_intr0 +.erre offset intr_5 - offset intr_4 EQ intr1_intr0 +.erre offset intr_6 - offset intr_5 EQ intr1_intr0 +.erre offset intr_7 - offset intr_6 EQ intr1_intr0 +.erre offset intr_8 - offset intr_7 EQ intr1_intr0 +.erre offset intr_9 - offset intr_8 EQ intr1_intr0 +.erre offset intr_10 - offset intr_9 EQ intr1_intr0 +.erre offset intr_11 - offset intr_10 EQ intr1_intr0 +.erre offset intr_12 - offset intr_11 EQ intr1_intr0 +.erre offset intr_13 - offset intr_12 EQ intr1_intr0 +.erre offset intr_14 - offset intr_13 EQ intr1_intr0 +.erre offset intr_15 - offset intr_14 EQ intr1_intr0 + + + + align 16 + + + +send_intr: + + push ds + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + + movzx edx,al + inc edx + + mov ebp,[(edx*4)+intr_associated_tcb-4*1] + + mov al,[ebp+fine_state] + + and al,nwait+nclos + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + IFZ + cmp [ebp+waiting_for],edx + FI + jnz intr_pending + FI + + mov [ebp+fine_state],running + + cmp ebx,dispatcher_tcb + jz intr_while_dispatching + + mark__interrupted ebx + push offset switch_from_intr + + + +transfer_intr: + + switch_thread int,ebx + + mov [ebp+rem_timeslice],100 ;;;;;;;;;;;;;;;;;; -------------- + + shr ebp,task_no + + switch_space + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + +intr_while_dispatching: + + mov ebx,ds:[cpu_esp0] + sub ebx,sizeof tcb + mov esp,[ebx+thread_esp] + cmp ebp,ebx + jnz transfer_intr + + pop eax + + sub eax,eax + mov ebx,eax + mov esi,edx + mov edi,ebx + + iretd + + + + + + +intr_pending: + + test_intr_in_sndq ebp ; prevents multiple entry + IFC ; of intr into sendq + insert_intr_first_into_sndq + + test [ebp+fine_state],nready + IFZ + CANDNZ ebp,ebx + CANDNZ ebx,dispatcher_tcb + + mark__interrupted ebx + + push offset switch_from_intr + jmp switch_context + FI + FI + +; jmp switch_from_intr + + + + klign 16 + + + + +switch_from_intr: + + ipost + + + + +;---------------------------------------------------------------------------- +; +; special P2 intr handling +; +;---------------------------------------------------------------------------- + + IF kernel_x2 + + + + align 16 + + + irp irq,<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15> + + align 8 + +intr_&irq&_P2: + push fault + pushad + mov al,irq + jmp short send_intr_P2 + + endm + + +.list + + + +send_intr_P2: + + mov ss:[local_apic+apic_eoi],0 + jmp send_intr + + + + ENDIF + + + +;**************************************************************************** +;***** ****** +;***** ****** +;***** IPC System Calls ****** +;***** ****** +;***** ****** +;**************************************************************************** + + + + + + +;---------------------------------------------------------------------------- +; +; IPC +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX snd descriptor +; ECX timeouts +; EDX snd.w0 +; EBX snd.w1 +; EBP rcv descriptor +; ESI dest +; EDI msg.w2 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX msg.dope / completion code +; ECX -ud- +; EDX msg.w1 +; EBX msg.w0 +; EBP -ud- +; ESI source +; EDI msg.w2 +; +;---------------------------------------------------------------------------- + +.erre (PM SHR 24) LE hardware_ec + + + + + + +ipc_critical_region_begin: ; PF in critical region push ipc state + ; even if fine_state is still 'running' + + + +ipc_sc: + + push eax + push ebx + + ; receive only if user specifies send buffer beyond his address space + cmp eax,virtual_space_size-MB4 + jae receive_only + + ; load sender tcb (ebx) + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + ; load linear kernel space into data segment + mov ds,edx + + ; store receive descriptor in tcb + mov [ebx+rcv_descriptor],ebp + mov ebp,esi + + ; store destination threadID (ebp=esi) in tcb (wait for this thread to enter receive state) + mov [ebx+waiting_for],esi + + ; IPC redirection + and al,(NOT ipc_control_mask)+deceit+map_msg ;REDIR begin ---------------------------- + + ; mask task no of source and destination ; + and ebp,mask task_no ; + mov edx,ebx ; + + shr ebp,task_no-2 ; + and edx,mask task_no ; + ; + shr edx,task_no-log2_tasks-2 ; + ; + ; lookup ipc redirection table at index: (dest_task_no*4){column}+(src_task_no*tasks*4){row} + mov edx,[edx+ebp+redirection_table] ; + + ; redirect or lock if ipc not transparent ; + cmp edx,ipc_transparent ; + xc nz,redirect_or_lock_ipc,long ; + ; + mov ebp,esi ;REDIR ends ---------------------------- + + ; load destination tcb address + and ebp,mask thread_no + + ; store second message word + mov [ebx+mword2],edi + add ebp,offset tcb_space + + ; load src threadID + mov edi,[ebx+myself] + ;REDIR: and al,(NOT ipc_control_mask)+deceit+map_msg + ; load dest threadID + mov edx,[ebp+myself] + xor edi,esi + + ; send to chief + test edi,mask chief_no + xc nz,to_chief,long + + ; load processor number [MP] + lno___prc edi + + ; test if destination exists + cmp esi,edx + jnz ipc_dest_not_existent + + ; if destination thread is not on current processor [MP] + cmp edi,[ebp+proc_id] + jnz ipc_cross_processor + + + + ; ipc on local processor + + ; if deceit bit is set ipc is propagated (propagate pre) + test al,deceit + ; if propagatee in src task or in dest task receiver gets propagatee id and waits for receive from this thread + ; else check for direction preceiving IPC + xc nz,propagate_pre,long + + ; get fine state of destination thread + mov dl,[ebp+fine_state] + + and dl,nwait+nclos + ; IF dest thread is ??? + IFLE ; Greater : nwait=SF=OV=0 and ZF=0 + ; IF dest thread is ??? + IFZ + ; IF dest thread is in closed wait + ; does dest thread wait for src thread + mov esi,[ebp+waiting_for] + mov edi,[ebx+myself] + cmp edi,esi + FI + ; IF (dest thread is in closed wait but not for src thread) OR (???) THEN check for pending or autopropagation + xc nz,pending_or_auto_propagating,long + FI + +;;<----------- hier bin ich + + test eax,0FFFFFFF2h + xc nz,ipc_long,long + + + mov ch,running + + mov [ebp+fine_state],ch + + +receive_message: + + mov edx,[ebx+rcv_descriptor] + cmp edx,virtual_space_size + + mov dh,[ebx+list_state] + IF____xc ae,send_only,long + + ELSE__ + + and edx,(is_polled SHL 8) + nclos + + cmp edx,(is_polled SHL 8) + nclos + jz fetch_next + + and cl,0Fh + xc nz,enter_wakeup_for_receive_timeout,long + + add dl,closed_wait+nwake + mov edi,ebx + + mov [ebx+fine_state],dl + pop edx + + pop ebx + FI____ + + + ;;;;; switch_thread ipc,edi + mov cl,[edi+ressources] + + test cl,cl + jnz deallocate_ressources_ipc + + public switch_thread_ipc_ret + switch_thread_ipc_ret: + + lea esi,[ebp+sizeof tcb] + mov [edi+thread_esp],esp + + mov ds:[cpu_esp0],esi + mov esp,[ebp+thread_esp] + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + shr ebp,task_no + mov esi,[edi+myself] + + test al,deceit+redirected + xc nz,propagate_or_redirected_post + + mov edi,[edi+mword2] + + ; mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + and ebp,0FFh ;taskno in lower bytes + shl ebp, max_cpu + lno___prc ecx + add ebp, ecx + mov ebp,[(ebp*8)+task_proot-8] + + + + + ;;;;;;;;;;;; switch_space + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + cmp byte ptr ds:[gdt+linear_space/8*8+7],0 + mov cr3,ebp + mov ebp,linear_space + IFZ + mov ds,ebp + pop ebp + iretd + FI + FI + mov ebp,00CCF300h + FI + + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + + mov ds:[gdt+linear_space_exec/8*8+4],ebp + mov ebp,linear_space + + mov es,ebp + + mov fs,ebp + + mov gs,ebp + + mov ds,ebp + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pop ebp + iretd + + + +.errnz open_wait - (closed_wait + nclos) +.errnz nwait - 80h + + + + + +XHEAD propagate_or_redirected_post + + mov ecx,[edi+waiting_for] + test al,deceit + + mov esi,[edi+myself] + xret z + + mov esi,[edi+virtual_sender] + xret + + + + + +XHEAD send_only + + mov [ebx+fine_state],running + mov edi,ebx + pop edx + pop ebx + push offset send_ok_ret + + test [edi+list_state],is_ready + xret nz,long + + IFDEF ready_llink + push eax + push ebx + mov ebx,edi + call insert_into_ready_list + mov edi,ebx + pop ebx + pop eax + ELSE + lins edi,esi,ready + ENDIF + xret ,long + + + + + + +XHEAD propagate_pre + + ; get address propagatee ID parameter on user level stack + mov edi,[esp+iret_esp+(3+1)*4] ; must be read from user space, + sub edx,edx + + ; clear propagatee_tcb field + mov [ebx+propagatee_tcb],edx + ; load propagatee thread id + mov edi,es:[edi] ; potentially small space + + ; set task no of sender and receiver to 0 if equal to the task no of propagatee + mov edx,ebx + mov esi,ebp + xor edx,edi + xor esi,edi + + ; store propagatee ID in virtual sender field in the tcb + mov [ebx+virtual_sender],edi + + ; IF src task equals propagatee's task + test edx,mask task_no ; propagation if deceited in dest or src task + CORZ + ; COR dest task equals propagatee's task + test esi,mask task_no + IFZ + ; load propagatee's tcb address + lea___tcb esi,edi + + ; IF tcb writeable + test__page_writable esi + IFNC + ; CAND propagatee tcb valid + CANDZ [esi+myself],edi + mov dl,[esi+fine_state] + mov edi,[esi+waiting_for] + and dl,NOT nwake + ; CAND propagatee is closed waiting + CANDZ dl,closed_wait + ; CAND waiting for src thread + CANDZ [ebx+myself],edi + + ; store propagatee's tcb address in src thread + mov [ebx+propagatee_tcb],esi + ; set propagatee to wait for src thread + mov edi,[ebp+myself] + mov [esi+waiting_for],edi + FI + ; return + xret ,long + FI + + ; ELSE src and dest task differ from propagatee's task + ; check for direction preceiving deceit + + mov edx,[ebx+myself] ;REDIR begin -------------------------------- + mov esi,[ebp+myself] ; + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + ; + test edx,mask chief_no ; ; redirection only if within same clan + IFZ ; ; and redir path + push ecx ; ; + push ebp ; ; note that this implies that I am + ; ; NOT the chief/redirector + and ebp,mask task_no ; ; + mov esi,edi ; ; see below for that case + shr ebp,task_no-2 ; + mov ecx,16 ; + DO ; + and esi,mask task_no ; + shr esi,task_no-log2_tasks-2 ; + ; + mov edx,[esi+ebp+redirection_table] ; + cmp edx,ipc_transparent ; + EXITZ ; + cmp edx,ipc_inhibited ; + EXITZ ; ; + cmp edx,ipc_locked ; + EXITZ ; + dec ecx ; + EXITZ ; + ; + mov esi,edx ; + xor edx,ebx ; + test edx,mask task_no ; + REPEATNZ ; + ; + xret ,long ; + OD ; + and al,NOT deceit ; + xret ,long ; + FI ; + ; + mov edx,[ebx+myself] ; ; always redirection if + mov esi,[ebp+myself] ; ; myself = chief (dest) AND + shl edx,chief_no-task_no ; ; myself = chief (virtual sender) + xor esi,edx ; + xor edx,edi ; + or edx,esi ; + xret z,long ;REDIR ends ----------------------------------- + + + push eax + push edi + + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + setz ah ; AH=1 <==> I am chief of nchief(dest) + call nchief + shr esi,chief_no-task_no + xor esi,ebx + test esi,mask task_no + setz al ; AL=1 <==> I am chief of nchief(source) + xor al,ah + + pop edi + pop eax + + IFZ + and al,NOT deceit + FI + xret ,long + + + + + + + +XHEAD enter_wakeup_for_receive_timeout + + mov dword ptr [esp+4+4],offset receive_timeout_ret + + mov edi,ecx + and edi,0FF000000h + add cl,2 + shr edi,cl + shr edi,cl + IFNZ + + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + + sub dl,nwake + + cmp cl,5+2 + xret le,long + + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + + test [ebx+list_state],cl + xret nz,long + + linsr ebx,ecx,edi,cl + xret ,long + FI + + + mov dl,running-(closed_wait+nwake) + push eax + mark__ready ebx + pop eax + xret ,long + + + align 4 + + + +send_ok_ret: + + pop eax + sub eax,eax + iretd + + + + + ; PF in critical region push ipc state +ipc_critical_region_end: ; even if fine_state is still 'running' + + + + align 16 + + +XHEAD ipc_long + + mov [ebx+timeouts],ecx + mov edx,(locked_running SHL 8) + (locked_waiting AND 0FFh) + + mov [ebx+fine_state],dh + mov [ebp+fine_state],dl + + and al,ipc_control_mask + mov esi,[esp+4+4] + + mov edi,[ebp+rcv_descriptor] + and esi,NOT (deceit+map_msg) + + mov [ebx+com_partner],ebp + IFNZ + mov bl,al + mov eax,es:[esi+msg_dope] + + mov al,bl + mov bl,0 + FI + + + test edi,map_msg ;;; test al,map_msg ---- Volkmar + IFZ ,,long + + test eax,mask md_mwords-(3 SHL md_mwords)+mask md_strings + map_msg + xret z,long + + add al,ipc_cut + and edi,NOT (deceit+map_msg) + + nop + CANDNZ ,,long + + + sub al,ipc_cut + push ebx + + push eax + mov ecx,eax + + shr ecx,md_mwords + ;; mov [ebx+com_partner],ebp + + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_source,long + + mov [ebp+com_partner],ebx + mov eax,ebp + + shr eax,task_no + lea edx,[ecx*4+edi] + + sass__32 cmp,edx,MB4-offset msg_w3 + nop + + ; mov eax,[eax*8+task_proot-(offset tcb_space SHR (task_no-3))].proot_ptr + and eax,0FFh ;taskno in lower bytes + shl eax, max_cpu + push edi + lno___prc edi + add eax, edi + pop edi + mov eax,[(eax*8)+task_proot-8].proot_ptr + + IFBE + + test al,al + CANDNZ + mov ah,0 + add edi,offset small_virtual_spaces + + shl eax,22 + nop + + add edi,eax + ELSE_ + + mov al,0 + mov edx,ds:[cpu_cr3] + + cmp eax,edx + IFNZ + + mark__ressource ebx,com_used + + mov [ebx+waddr],edi + mov ebx,edi + + and ebx,-MB4 + and edi,MB4-1 + + shr ebx,20 + add eax,PM + + add ebx,eax + mov al,ds:[tlb_invalidated] + + add edi,com0_base + test al,al + + mov eax,[ebx] + mov ebx,[ebx+4] + + lea edx,[edx+(com0_base SHR 20)+PM] + IFNZ + + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + cmp [edx],eax + CORNZ + + cmp [edx+4],ebx + IFNZ + push eax + mov eax,cr3 + mov cr3,eax + pop eax + FI + FI + or al,page_accessed+page_dirty + or bl,page_accessed+page_dirty + + mov [edx],eax + mov [edx+4],ebx + FI + FI + + sti + + mov edx,edi + mov edi,[edi+msg_size_dope] + + shr edi,md_mwords + nop + + cmp ecx,edi + xc a,shorten_mwords,long + + sub ecx,2 + IFA + lea esi,[esi+msg_w3] + + mov edi,[edx+32] + lea edi,[edx+msg_w3] + + cmp ecx,8 + ccall a,copy_long + + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + + sub edi,edx + sub esi,edi + FI + + + pop eax + pop ebx + + test ah,mask md_strings SHR 8 + xc nz,ipc_strings,long + + mov edi,[edx+msg_rcv_fpage] + + unmrk_ressource ebx,com_used + + test edi,edi + IFNZ + or edi,map_msg + FI + + cli + + mov ecx,[ebx+timeouts] + nop + + FI + + test al,map_msg + xret z,long + + + + ;------------------------------------------------------------- + ; + ; IPC MAP + ; + ;------------------------------------------------------------- + ; + ; + ; EAX msg dope + cc + ; ECX scratch + ; EDX w0 + ; EBX snd tcb + ; EBP rcv tcb + ; ESI snd msg pointer / 0 + ; EDI rcv fpage + ; + ;-------------------------------------------------------------- + + or al,ipc_cut + + mov ecx,ebx ; + xor ecx,ebp ; + test ecx,mask task_no ; ignore intra-task mapping + xret z,long ; + + test edi,map_msg + xret z,long + + and al,NOT ipc_cut + + pop edx + + push eax + push ebx + push edx + + + mov ecx,eax + + mov eax,[esp+3*4] ; w1, first snd fpage + mov ebx,edi ; rcv fpage -> ebx + + ;-------------- provisional translate impl ----------- + + test al,al + IFZ + call translate_address + mov [esp+3*4],eax + + pop edx + pop ebx + pop eax + + push edx + mov ecx,[ebx+timeouts] + + xret ,long + FI + + ;----------------------------------------------------- + + DO + push ecx + push ebx + push esi + + mov ch,al ; ch: opn + + mov esi,-1 SHL log2_pagesize + mov edi,esi + + mov cl,bl + shr cl,2 + sub cl,log2_pagesize + IFNC + shl edi,cl + + mov cl,al + shr cl,2 + sub cl,log2_pagesize + CANDNC + shl esi,cl + + and eax,esi + + xor esi,edi + and edx,esi + + test esi,edi + xc nz,shrink_snd_fpage ; snd fpage > rcv fpage + and edi,ebx + add edi,edx + + push ebp + + mov edx,ebp + + push offset fpage_opn_ret + test ch,fpage_grant + jz map_fpage + jmp grant_fpage + + klign 16 + + fpage_opn_ret: + + pop ebp + FI + + pop esi + pop ebx + pop ecx + + EXITC + + sub ecx,2 SHL md_mwords + IFBE + pop edx + pop ebx + pop eax + + push edx + + mov ecx,[ebx+timeouts] + + xret ,long + FI + + add esi,sizeof fpage_vector + + mov edx,[esi+msg_w3].snd_base + mov eax,[esi+msg_w3].snd_fpage + + REPEAT + OD + + pop edx + pop ebx + pop eax + + push edx + + mov al,ipc_cut + + mov ecx,[ebx+timeouts] + xret ,long + + + + + +XHEAD shrink_snd_fpage + + add eax,edx + sub edx,edx + mov cl,bl + xret + + + +XHEAD shorten_mwords + + mov ecx,edi + shl eax,width md_mwords + shrd eax,ecx,width md_mwords + or al,ipc_cut + xret ,long + + + + + + +XHEAD prepare_small_source + + shl eax,16 + lea edx,[ecx*4+esi] + + sass__32 cmp,edx,MB4-offset msg_w3 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + shl eax,max_cpu + push edi + lno___prc edi + add eax,edi + pop edi + mov eax,[eax*8+task_proot-8].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + + + + copy_long: + + + DO + mov eax,[esi] + mov ebx,[edi+32] + mov ebx,[esi+4] + mov [edi],eax + mov [edi+4],ebx + mov eax,[esi+8] + mov ebx,[esi+12] + mov [edi+8],eax + mov [edi+12],ebx + mov eax,[esi+16] + mov ebx,[esi+20] + mov [edi+16],eax + mov [edi+20],ebx + mov eax,[esi+24] + mov ebx,[esi+28] + mov [edi+24],eax + mov [edi+28],ebx + add esi,32 + add edi,32 + sub ecx,8 + cmp ecx,8 + REPEATA + OD + ret + + + + +;----------------------------------------------------------------------------------- +; +; ipc strings +; +;----------------------------------------------------------------------------------- +; +; ipc strings : +; +; to first source string ; +; to first dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; open dest string ; +; +; DO +; copy segment := source segment RESTRICTED BY (dest segment.length, 4MB) ; +; IF addresses are valid +; THEN copy data +; FI ; +; set dest string length ; +; source segment PROCEED BY copy segment.length ; +; dest segment PROCEED BY copy segment.length ; +; +; IF source segment exhausted +; THEN to next source string ; +; IF no source string THEN LEAVE WITH done FI ; +; IF is master source string +; THEN to next master dest string ; +; IF no dest string +; THEN LEAVE WITH cut error +; ELSE open dest string +; FI +; FI +; ELIF dest segment exhausted +; THEN to next dest string ; +; IF no dest string THEN LEAVE WITH cut error FI ; +; IF dest slave string +; THEN open dest string +; ELSE LEAVE WITH cut error +; FI +; FI +; OD . +; +;--------------------------------------------------------------------------------- + + + + align 16 + + + +XHEAD ipc_strings + + or al,ipc_cut + + mov ch,ah + and ah,NOT (mask md_strings SHR 8) + and ch,mask md_strings SHR 8 + + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + xret z,long + or ah,cl + + + push eax + push edx + + + mov ebx,[esi+msg_size_dope] + shr ebx,md_mwords + lea ebp,[(ebx*4)+esi+msg_w3-2*4] + + mov eax,[edx+msg_size_dope] + shr eax,md_mwords + lea edx,[(eax*4)+edx+msg_w3-2*4] + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + mov [edx+str_addr],edi + + + DO + push ecx + + mov ecx,MB4 + IFB_ eax,ecx + mov ecx,eax + FI + IFB_ ebx,ecx + mov ecx,ebx + FI + + + pushad + mov eax,edi + mov ebx,esi + add eax,ecx + IFNC ,,long + add ebx,ecx + CANDNC ,,long + CANDB eax,virtual_space_size,long + CANDB ebx,virtual_space_size,long + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space,long + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + FI + popad + + + sub eax,ecx + sub ebx,ecx + add edi,ecx + add ecx,esi + IFNC + mov esi,ecx + FI + + mov ecx,[edx+buf_addr] + sub edi,ecx + mov [edx+str_len],edi + add edi,ecx + + pop ecx + + + test ebx,ebx + IFZ + add ebp,sizeof string_vector + dec ch + EXITZ + + mov ebx,[ebp+str_len] + mov esi,[ebp+str_addr] + test ebx,ebx + REPEATNS + + and ebx,7FFFFFFFh + DO + add edx,sizeof string_vector + dec cl + OUTER_LOOP EXITZ + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + test eax,eax + REPEATS + OD + mov [edx+str_addr],edi + REPEAT + FI + + test eax,eax + REPEATNZ + + add edx,sizeof string_vector + dec cl + EXITZ + + mov eax,[edx+buf_size] + mov edi,[edx+buf_addr] + + test eax,eax + REPEATS + mov cl,0 + + OD + + + mov ebx,esp + and ebx,-sizeof tcb + + pop edx + pop eax + + mov ebp,[ebx+com_partner] + + test cl,cl + IFNZ + and al,NOT ipc_cut + sub ah,cl + inc ah + FI + + xret ,long + + + + + + + if 0 ;----------------------------------------- + + + + + align 16 + + + +XHEAD ipc_strings + + mov ch,ah + and ch,mask md_strings SHR 8 + mov cl,[edx+msg_size_dope].msg_strings + and cl,mask md_strings SHR 8 + IFA ch,cl + mov ch,cl + or al,ipc_cut + and ah,NOT (mask md_strings SHR 8) + add ah,cl + test cl,cl + xret z,long + FI + + push edx + + mov edi,[edx+msg_size_dope] + shr edi,md_mwords + lea edi,[(edi*4)+edx+msg_w3-2*4] + + mov edx,[esi+msg_size_dope] + shr edx,md_mwords + lea esi,[(edx*4)+esi+msg_w3-2*4] + + DO + push ecx + push esi + push edi + + mov ecx,[esi+str_len] + cmp ecx,[edi+buf_size] + IFA + mov ecx,[edi+buf_size] + or al,ipc_cut + FI + + push eax + push ebx + + mov eax,[edi+buf_addr] + mov [edi+str_len],ecx + mov [edi+str_addr],eax + + mov esi,[esi+str_addr] + mov edi,eax + + mov al,byte ptr ds:[gdt+linear_space/8*8+4] + mov ah,byte ptr ds:[gdt+linear_space/8*8+7] + + test ah,ah + xc nz,prepare_small_string_source,long + + mov edx,ebx + xor edx,ebp + test edx,mask task_no + IFNZ + mov edx,edi + and edx,-MB4 + sub edi,edx + add edi,com0_base + mov eax,[ebx+waddr] + xor eax,edx + test eax,-MB4 + xc nz,string_to_com1_space + FI + + mov dl,cl + and dl,4-1 + shr ecx,2 + + cmp ecx,8 + ccall a,copy_long + + test ecx,ecx + IFNZ + DO + mov eax,[esi] + mov [edi],eax + + add esi,4 + add edi,4 + + dec ecx + REPEATNZ + OD + FI + DO + test dl,dl + EXITZ + mov al,[esi] + mov [edi],al + cmp dl,2 + EXITB + mov al,[esi+1] + mov [edi+1],al + EXITZ + mov al,[esi+2] + mov [edi+2],al + OD + + pop ebx + pop eax + + pop edi + pop esi + pop ecx + + add esi,sizeof string_vector + add edi,sizeof string_vector + dec ch + REPEATNZ + OD + + pop edx + sub edi,edx + sub esi,edi + xret ,long + + + + + endif ;-------------------------------------- + + + + + + +XHEAD string_to_com1_space + + push ecx + + mark__ressource ebx,com_used + + shr edx,16 + mov word ptr [ebx+waddr],dx + add edi,com1_base-com0_base + ; load page directory of task: tcb (ebp) + lea___pdir ecx,ebp + + push eax + mov eax,ds:[ebp+proc_id] + dec eax + shl eax,log2_pagesize + add ecx,eax + pop eax + + mov ecx,[ecx+edx] + mov edx,ecx + and dl,NOT page_user_permit + xchg ds:[pdir+(com1_base SHR 20)],edx + cmp edx,ecx + mov dword ptr ds:[pdir+(com1_base SHR 20)+4],0 + + pop ecx + xret z,long + test edx,edx + xret z,long + + mov edx,cr3 + mov cr3,edx + xret ,long + + + + +XHEAD prepare_small_string_source + + shl eax,16 + + lea edx,[esi+ecx] + sass__32 cmp,edx,MB4 + IFB_ + add esi,eax + xret ,long + FI + + lno___task eax,ebx + shl eax,max_cpu + push edi + lno___prc edi + add eax,edi + pop edi + mov eax,[eax*8+task_proot-8].proot_ptr + mov al,0 + mov ds:[cpu_cr3],eax + mov ds:[tlb_invalidated],al + mov cr3,eax + xret ,long + + + + +ipc_cross_processor: + + ke 'cross processor ipc' + + ; ebp = dest tcb, edi = proc_id, edx = dest_id_tcb, eax = snd descriptor, ebx = src_tcb, ecx = timeouts, esi = dest_id + ;; setup mailbox + + push eax + imul edi,(mailbox_size+4) + imul edx,[ebp+proc_id],((1 SHL max_cpu)*(mailbox_size+4)) + add edx, offset mailbox + add edx, edi + + ; ebp = dest tcb, ebx = src tcb, ecx = timeout, esi = dest_id edi scratch, edx = offset mailbox begin + + sub eax,eax + sub edi,edi + inc edi + lock cmpxchg ds:[edx],edi ; set bit 0 and read old value (should be 00 for free + unlocked) + ; 01 free but locked, 10 not free but unlocked 11 locked and not free + IFZ ; mailbox was free +mailbox_locked: + ; write to mailbox + pop eax + mov ds:[edx+4],eax ; snd descriptor + pop eax + pop edi + mov ds:[edx+8],ebp ; dest_tcb + mov ds:[edx+16],ecx ; timeouts + mov ds:[edx+24],edi ; mword 1 + mov edi,ds:[ebx+mword2] + mov ds:[edx+12],ebx ; src_tcb + mov ds:[edx+20],eax ; mword 0 + mov ds:[edx+28],edi ; mword 2 + ; mailbox_IPC: snd desriptor / dest_tcb / src_tcb / timeouts / mw0 / mw1 / mw2 + + ;set sender wait for proxy thread + ; include sender in wait list to be checked within the timer interrupt + + ; set sender locked running // only needed for active polling, else locked_waiting + mov [ebx+fine_state],locked_running + + ; unlock mailbox + mov edi,2 + mov ds:[edx],edi ; 10 not free but unlocked + + ; send ipi + + + ; poll for proxy thread completion + mov [ebx+proxy_completion],0 + DO + mov edx,[ebx+proxy_completion] + REPEATZ + ; switch to anyone + OD + ; setup ipc pre: setup receive?, ipc fail, ipc complete + IFZ dh,0 ; send completed correctly + ; setup old stack + + jmp receive_message + FI + ; setup completion message of send part + mov eax,edx + mov [ebx+fine_state],running + ke 'end of message' + iretd + ELSE_ + DO + sub eax,eax + DO + mov edi,ds:[edx] + REPEATNZ + OD + sub edi,edi + inc edi + lock cmpxchg ds:[edx],edi + jz mailbox_locked + REPEATNZ + OD + FI + iretd + + + + + + + align 16 + + + +fetch_next: + + add dl,locked_closed_waiting + mov [ebx+fine_state],dl + + pop edx + + mov esi,[ebx+myself] + test al,deceit + IFNZ + mov esi,[ebx+virtual_sender] + FI + mov edi,[ebx+mword2] + + mov ecx,esp + mov esp,[ebp+thread_esp] + + push eax ; eax ; + mov eax,[ebx+waiting_for] ; + push eax ; ecx ; + push edx ; edx ; + mov eax,[ecx] ; + push eax ; ebx ; pushad + push eax ; temp (esp) ; + push eax ; ebp ; + push esi ; esi ; + push edi ; edi ; + push offset received_ok_ret + + mark__ready ebp + + mov [ebp+thread_esp],esp + lea esp,[ecx+4] + + + get_first_from_sndq + + IFC + mov dl,0 + mov ebp,edx + + + mov [edx+fine_state],locked_running + + jmp switch_context + + FI + + mov [ebx+fine_state],running + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + + pop eax + sub eax,eax + iretd + + + + + + + + +ipc_dest_not_existent: + + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + pop ebp + pop ebp + iretd + + + +nil_dest_not_existent_or_interrupt_attach_operation: + + sub eax,eax + pop edx ; msg w0 + pop ebx ; msg w1 + pop ebp + + test byte ptr ss:[esp+iret_eflags+1],11b SHL (iopl_field-8) + CORZ + test esi,esi + IFZ + mov al,ipc_not_existent_or_illegal + iretd + FI + + lea ecx,[esi-1] + + mov edi,ebx + mov esi,edx + sub ebx,ebx + test edx,edx + IFNZ + lea___tcb edx,edx + CANDZ [edx+myself],esi + mov ebx,edx + FI + + call attach_intr + + iretd + + + + + + + + + align 16 ;REDIR begins -------------------------- + ; + ; + ; +XHEAD redirect_or_lock_ipc ; + ; + IFNZ edx,ipc_locked ; + ; + mov esi,edx ; + or al,redirected ; + ; + xret ,long ; + FI ; + ; + ; + ; ipc locked: wait and restart ipc + pushad ; + sub esi,esi ; + int thread_switch ; + popad ; + ; + mov ebp,[ebx+rcv_descriptor] ; + pop edx ; + pop ebx ; + pop eax ; + ; + iretd ;REDIR ends -------------------------- + + + + + + + + + align 16 + + +XHEAD to_chief + + cmp esi,intr_sources + jbe nil_dest_not_existent_or_interrupt_attach_operation + + cmp esi,ipc_inhibited ;REDIR ------------------------- + jz ipc_dest_not_existent ;REDIR ------------------------- + + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + or al,redirected + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + EXITZ + FI + + or al,redirected+from_inner_clan + mov esi,[ebx+myself] + shr esi,chief_no-task_no + OD + + lea___tcb ebp,esi + mov edx,esi ; ensures that dest-id check succeeds + xret ,long + + + + + + + + +XHEAD pending_or_auto_propagating + + cmp ebx,ebp + jz sw_err3 + + mov edi,[ebp+myself] + DO + test [ebp+coarse_state],auto_propagating + EXITZ + + add ebp,sizeof tcb + test__page_writable ebp + EXITC + + mov dl,[ebp+fine_state] + test dl,nwait + REPEATNZ + + test dl,nclos + IFNZ + cmp [ebp+waiting_for],edi + REPEATNZ + FI + + mov edi,[ebp+myself] + test al,deceit + IFNZ + mov esi,[ebx+propagatee_tcb] + CANDNZ esi,0 + mov [esi+waiting_for],edi + ELSE_ + mov [ebx+waiting_for],edi + FI + + xret ,long + OD + + pop edx + pop edi + ; eax ; already pushed + + push ecx ; ecx ; + push edx ; edx ; + push edi ; ebx ; + push edi ; temp (esp) ; + mov edi,[ebx+rcv_descriptor]; ; pushad + push edi ; ebp ; + mov esi,[ebx+waiting_for] ; ; + mov edi,[ebx+mword2] ; ; + push esi ; esi ; + push edi ; edi ; + + + test cl,0F0h + IFNZ + test ecx,000FF0000h + jz send_timeout_ret + FI + + mov [ebx+com_partner],ebp + + insert_last_into_sndq + + shl ecx,8 + mov cl,ch + shr cl,4 + + push offset ret_from_poll + mov ch,polling+nwake + + jmp wait_for_ipc_or_timeout + + + + +sw_err3: + pop edx + pop edi + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + + + + + + + + +ret_from_poll: + + push linear_kernel_space + pop ds + + mov ebx,esp + and ebx,-sizeof tcb + mov ebp,[ebx+com_partner] + + IFZ [ebx+fine_state],locked_running + + mov [ebx+fine_state],running + and [ebp+fine_state],nclos + or [ebp+fine_state],closed_wait+nwake + + popad + jmp ipc_sc + + FI + + test [ebx+fine_state],npoll + IFZ + mov ebp,ebx + delete_from_sndq + mov [ebx+fine_state],running + FI + + +send_timeout_ret: + + popad + sub eax,eax + mov al,ipc_timeout+ipc_s + iretd + + + + + + +;---------------------------------------------------------------------------- + + + +w_err: + pop eax + sub eax,eax + mov al,ipc_not_existent_or_illegal + iretd + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE +; +;---------------------------------------------------------------------------- + + + align 16 + + + + + + + +receive_only: + + mov ebx,esp + push edx + + and ebx,-sizeof tcb + mov edx,linear_kernel_space + + mov ds,edx + + pop edx + pop eax + + cmp ebp,virtual_space_size + jae w_err + + mov [ebx+timeouts],ecx + mov [ebx+rcv_descriptor],ebp + + test ebp,nclos + jz receive_from + + test [ebx+list_state],is_polled + IFNZ + + get_first_from_sndq + + IFNC + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + mov dl,0 + mark__ready edx + mov [ebx+fine_state],locked_waiting + mov [ebx+com_partner],edx + mov [edx+fine_state],locked_running + mov [edx+com_partner],ebx + mov ebp,edx + jmp switch_context + + FI + + + mov ch,open_wait+nwake + + + +wait_for_receive_or_timeout: + + mov ebp,ebx + + + +wait_for_receive_from_or_timeout: + + mov dword ptr [esp],offset receive_timeout_ret + + + + +wait_for_ipc_or_timeout: + + and cl,0Fh + IFNZ + + mov edi,ecx + and edi,0FF000000h + IFZ + ret + FI + sub ch,nwake + add cl,2 + shr edi,cl + shr edi,cl + add edi,ds:[system_clock_low] + mov [ebx+wakeup_low],edi + cmp cl,5+2 + IFG + movi edi, + cmp cl,7+2 + mov cl,is_soon_wakeup + IFLE + add edi,offset late_wakeup_link-soon_wakeup_link + mov cl,is_late_wakeup + FI + test [ebx+list_state],cl + CANDZ + linsr ebx,eax,edi,cl + FI + FI + + mov al,[ebp+timeslice] + mov [ebp+rem_timeslice],al + + mov [ebx+fine_state],ch + + test [ebp+fine_state],nready + + jz switch_context + jmp dispatch + + + + + +receive_timeout_ret: + + mov ebp,esp + and ebp,-sizeof tcb + + mov [ebp+fine_state],running + + sub eax,eax + mov al,ipc_timeout + + iretd + + + + align 16 + + +received_ok_ret: + + popad + add esp,4 + iretd + + + + + + +;---------------------------------------------------------------------------- +; +; RECEIVE FROM +; +;---------------------------------------------------------------------------- + + + align 16 + + +receive_from: + + mov [ebx+waiting_for],esi + + IFB_ esi,intr_sources+1 + + test_intr_in_sndq ebx + + IFC + mov ch,closed_wait+nwake + mov edi,ecx + and edi,0FF00000Fh + IFNZ + cmp edi,15 + FI + jae wait_for_receive_or_timeout + + call detach_intr + mov ecx,esi + dec ecx + IFNS + CANDZ [(ecx*4)+intr_associated_tcb],0 + call attach_intr + pop eax + jmp receive_timeout_ret + FI + jmp w_err + FI + + + get_first_from_sndq + + pop eax + + sub edx,offset intrq_llink-1*8 + shr edx,3 + sub ebx,ebx + mov esi,edx + mov edi,ebx + sub eax,eax + + iretd + FI + + lea___tcb ebp,esi + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFNZ + call nchief + FI + + cmp [ebp+myself],esi + jnz short r_source_not_existent + + test [ebp+fine_state],npoll + IFZ + CANDZ [ebp+com_partner],ebx + + delete_from_sndq + + mov [ebp+fine_state],locked_running + mark__ready ebp + mov [ebx+fine_state],locked_closed_waiting + mov [ebx+com_partner],ebp + + jmp switch_context + FI + + + mov ch,closed_wait+nwake + jmp wait_for_receive_from_or_timeout + + + + + +r_source_not_existent: + sub eax,eax + mov al,ipc_not_existent_or_illegal + pop ebp + iretd + + + + +;---------------------------------------------------------------------------- +; +; nchief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI thread / 0 +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ESI=0 on input: +; +; ESI myself +; +; +; ESI>0 on input: +; outside clan within clan +; +; AL redirected / redirected+from_inner_clan 0 +; ESI chief thread +; +; EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + + align 16 + + + + +id_nearest_sc: + + mov ebp,esp + and ebp,-sizeof tcb + + sub eax,eax + + test esi,esi + IFZ + mov esi,[ebp+myself] + iretd + FI + + + mov ebx,ebp + lea___tcb ebp,esi + + push linear_kernel_space + pop ds + + sub eax,eax + call nchief + + push linear_space + pop ds + + iretd + + + + + + + +nchief: ; esi: dest, ebx: my tcb, ebp: dest tcb + + mov al,0 + DO + mov edi,[ebx+myself] + shr edi,chief_no-task_no + xor edi,esi + test edi,mask task_no ; esi = chief(me) + EXITZ + + mov edi,esi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no ; me = chief(esi) + EXITZ + + test__page_present ebp + IFNC + CANDNZ [ebp+coarse_state],unused_tcb + mov dl,[ebp+clan_depth] + sub dl,[ebx+clan_depth] + CANDA + mov al,redirected+from_inner_clan + DO + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov edi,[esi+myself] + mov esi,edi + shr edi,chief_no-task_no + xor edi,ebx + test edi,mask task_no + OUTER_LOOP EXITZ + + dec dl + REPEATNZ + OD + + mov edi,[ebx+myself] + xor edi,esi + test edi,mask chief_no + IFZ + mov al,redirected + ret + FI + FI + + mov esi,[ebx+myself] + shr esi,chief_no-task_no + and esi,NOT mask lthread_no + lea___tcb esi,esi + mov esi,[esi+myself] + mov al,redirected + OD + + ret + + + + + + + + kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + + +;---------------------------------------------------------------------------- +; +; push / pop complete ipc state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; push PRECONDITION: +; +; is 'locked_running' or 'locked_waiting' or 'running' +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pushed / popped +; +; EAX,EDI scratch +; +;---------------------------------------------------------------------------- +; push POSTCONDITION: +; +; NZ: ECX timeouts for page fault RPC +; +; Z: PF timeout is 0, ECX scratch +; +; +; is 'running' +; +;---------------------------------------------------------------------------- + + align 16 + + + +push_ipc_state: + + pop edi + + mov eax,[ebp+com_partner] + push eax + mov eax,[ebp+waiting_for] + push eax + mov eax,[ebp+mword2] + push eax + mov eax,[ebp+rcv_descriptor] + push eax + mov eax,[ebp+virtual_sender] + push eax + mov eax,[ebp+timeouts] + shl eax,8 + mov ah,[ebp+fine_state] + mov [ebp+fine_state],running + mov al,[ebp+state_sp] + push eax + + mov ecx,esp + shr ecx,2 + mov [ebp+state_sp],cl + + IFNZ ah,running + mov ecx,[ebp+com_partner] + test [ebp+fine_state],nrcv + mov ecx,[ecx+timeouts] + IFNZ + rol ch,4 + FI + mov cl,ch + and cl,0F0h + shr ch,4 + or cl,ch + mov ch,cl + rol ecx,16 + mov cl,1 + mov ch,1 + ror ecx,16 + cmp cl,15*16+15 + + jmp edi + FI + + sub ecx,ecx + test esp,esp ; NZ! + + jmp edi + + + + + + +pop_ipc_state: + + pop edi + + pop eax + mov [ebp+state_sp],al + mov [ebp+fine_state],ah + shr eax,8 + mov byte ptr [ebp+timeouts+1],ah + + pop eax + mov [ebp+virtual_sender],eax + pop eax + mov [ebp+rcv_descriptor],eax + pop eax + mov [ebp+mword2],eax + pop eax + mov [ebp+waiting_for],eax + pop eax + mov [ebp+com_partner],eax + + IFNZ [ebp+fine_state],running + test [eax+fine_state],nlock + CORNZ + IFNZ [eax+com_partner],ebp + + ke '-pi_err' + FI + FI + jmp edi + + + + + + +;---------------------------------------------------------------------------- +; +; get bottom state +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX fine state (bottom) +; EBX com partner (bottom) iff state is 'locked' +; +;---------------------------------------------------------------------------- + + + +get_bottom_state: + + movzx eax,[ebp+state_sp] + test eax,eax + IFZ + mov eax,[ebp+sizeof tcb-sizeof int_pm_stack].ip_error_code + IFAE eax,min_icode + CANDBE eax,max_icode + + mov eax,running + ret + FI + + movzx eax,[ebp+fine_state] + ret + FI + + DO + lea ebx,[(eax*4)+ebp] + mov al,[ebx] + test al,al + REPEATNZ + OD + mov al,[ebx+1] + mov ebx,[ebx+4*4] + ret + + + + + +;---------------------------------------------------------------------------- +; +; cancel if within ipc +; +;---------------------------------------------------------------------------- +; cancel if within ipc PRECONDITION: +; +; EBP tcb write addr +; +; interrupts disabled ! +; +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL bottom state +; +; {REGs - AL} scratch +; +; base waiting : ipc cancelled +; base pending : ipc cancelled +; base locked : ipc aborted, also of partner +; +; ELSE : status unchanged +; +;---------------------------------------------------------------------------- + + + +cancel_if_within_ipc: + + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + delete_from_sndq + pop ecx + pop eax + FI + + + call get_bottom_state + + push eax + + test al,nlock + IFNZ + test al,nready + IFNZ + mov al,ipc_cancelled + call reset_ipc + FI + pop eax + ret + FI + + mov al,ipc_aborted + call reset_ipc + mov ebp,ebx + mov al,ipc_aborted + call reset_ipc + + pop eax + ret + + + + + +reset_ipc: + + pop ecx + + lea esi,[ebp+sizeof tcb-sizeof iret_vec-2*4] + test [ebp+fine_state],nrcv + IFNZ + add al,ipc_s + FI + movzx eax,al + mov [esi+4],eax + mov dword ptr [esi],offset reset_ipc_ret + + mov [ebp+fine_state],running + mov ebx,ebp + mark__ready ebx + + mov [ebp+thread_esp],esi + xor esi,esp + test esi,mask thread_no + IFZ + xor esp,esi + FI + + jmp ecx + + + + + +reset_ipc_ret: + + pop eax + iretd + + + + +;---------------------------------------------------------------------------- +; +; ipcman wakeup tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr +; +; DS linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; if locked no change, else +; state of thread set to 'running', deleted from sendq if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_wakeup_tcb: + + test [ebp+fine_state],nlock + IFNZ + test [ebp+fine_state],npoll + IFZ + push eax + push ecx + + delete_from_sndq + + pop ecx + pop eax + FI + mov [ebp+fine_state],running + push eax + push edi + mark__ready ebp + pop edi + pop eax + FI + + ret + + +;---------------------------------------------------------------------------- +; +; ipcman open tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb write addr, must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDP reentered into snd que if necessary +; +;---------------------------------------------------------------------------- + + + + +ipcman_open_tcb: + + pushfd + cli + + test [ebp+fine_state],npoll + IFZ + call enforce_restart_poll + FI + + popfd + ret + + +;---------------------------------------------------------------------------- +; +; ipcman close tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP to be deleted, (tcb write addr) +; must be mapped !! +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP thread deleted from send que if contained +; +;---------------------------------------------------------------------------- + + + +ipcman_close_tcb: + + pushad + pushfd + + cli + + mov al,[ebp+fine_state] + + test al,npoll + IFZ + delete_from_sndq + ;;;;; lno___thread ebx,eBp + ;;;;; call signal_scheduler_reactivation + FI + + mov eax,[ebp+sndq_root].head + and eax,-sizeof tcb + IFNZ eax,ebp + +;;;; mov edi,scheduler_tcb +;;;; join_sndqs + FI + + popfd + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; restart poll all senders (special routine for schedule) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb address +; +;---------------------------------------------------------------------------- + + +restart_poll_all_senders: + + ke '-n' + +; pushad +; pushfd +; +; DO +; cli +; test [ebx+list_state],is_polled +; EXITZ +; +; get_first_from_sndq +; IFNC +; ke 'flushed_intr' +; FI +; mov dl,0 +; +; test [edx+fine_state],npoll +; IFZ +; mov ebp,edx +; call enforce_restart_poll +; FI +; +; sti +; REPEAT +; OD +; +; popfd +; popad +; ret + + + +;---------------------------------------------------------------------------- +; +; enforce restart poll +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP tcb address, mapped +; +; tcb not open AND fine state = polling +; +;---------------------------------------------------------------------------- + + +enforce_restart_poll: + + pushad + + lea___esp eax,ebp +;;mov dword ptr [eax],offset restart_poll + + mov ebx,ebp + mark__ready ebx + + mov al,running + xchg [ebp+fine_state],al + + test al,nwake + IFZ + mov esi,[ebp+wakeup_low] + movzx edi,[ebp+wakeup_high] + pushfd + cli + mov eax,ds:[system_clock_low] + movzx ebx,ds:[system_clock_high] + popfd ; Rem: change of NT impossible + + sub esi,eax + sbb edi,ebx + IFC + sub esi,esi + FI + mov [ebp+timeouts],esi + FI + + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; attach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; ECX intr no (0...intr_sources-1) +; +;---------------------------------------------------------------------------- + + +attach_intr: + + + mov [(ecx*4)+intr_associated_tcb],ebx + + IF kernel_x2 + push eax + lno___prc eax + test eax,eax + pop eax + IFNZ + push eax + push ebx + + lea eax,[ecx*2+io_apic_redir_table] + mov byte ptr ds:[io_apic+io_apic_select_reg],al + lea ebx,[ecx+irq0_intr] + mov ebx,10000h + mov ds:[io_apic+io_apic_window],ebx + inc al + mov byte ptr ds:[io_apic+io_apic_select_reg],al + mov eax,ds:[local_apic+apic_id] + mov ds:[io_apic+io_apic_window],eax + + lea eax,[(ecx*intr1_intr0)+intr_0_P2] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + + extrn p6_workaround_open_irq:near + call p6_workaround_open_irq + + pop ebx + pop eax + ret + FI + ENDIF + + + call mask_hw_interrupt + + push eax + push ebx + lea eax,[(ecx*intr1_intr0)+intr_0] + lea ebx,[ecx+irq0_intr] + mov bh,0 SHL 5 + call define_idt_gate + pop ebx + pop eax + + ret + + + +;---------------------------------------------------------------------------- +; +; detach interrupt +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX tcb write addr +; +;---------------------------------------------------------------------------- + + +detach_intr: + + push ecx + + sub ecx,ecx + DO + IFZ [ecx+intr_associated_tcb],ebx + mov [ecx+intr_associated_tcb],0 + shr ecx,2 + call mask_hw_interrupt + EXIT + FI + add ecx,4 + cmp ecx,sizeof intr_associated_tcb + REPEATB + OD + + pop ecx + ret + + + +;---------------------------------------------------------------------------- +; +; ipcman rerun tcb +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ECX rerun esp real +; EDX tcb addr virtual (not mapped !) +; EBP tcb addr real +; +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; ECX rerun esp real (may have changed !) +; EBP tcb addr real (may have changed !) +; +; tcb restarted as far as ipcman is concerned +; +;---------------------------------------------------------------------------- +; Algorithm: +; +; IF special kernel ipc active +; THEN pop original tcb status +; FI ; +; IF locked running {message transfer running} +; THEN restart transfer long message {edx,ebp are ok on stack !! } +; ELIF locked waiting OR waiting +; THEN restart waiting +; ELIF locked waiting for non persisting {sender disappeared} +; THEN restart receive timeout +; FI +; +;---------------------------------------------------------------------------- + + align 4 + + +ipcman_rerun_thread: + + pushad + + mov al,[ebp+fine_state] + and al,NOT nwake + + CORZ al, + IFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + IFAE [ebp+waiting_for],intr_sources + mov [ebp+fine_state],running + FI + + ELIFZ al, + mov dword ptr [ecx],offset receive_timeout_ret + + ELIFZ al, + ELIFZ al, + sub ecx,4 + mov dword ptr [ecx],offset ret_from_poll + + ELIFZ al, + mov dword ptr [ecx],offset send_ok_ret + + ELIFZ al, + mov al,[ebp+coarse_state] + and al,nblocked+ndead + CANDZ al,ndead + mov dword ptr [ecx],offset send_ok_ret + + ELSE_ + ke 'ill_mess_rerun' + FI + + mov [esp+6*4],ecx + mov [esp+2*4],ebp + popad + ret + + + + +;---------------------------------------------------------------------------- +; +; update small_space_size +; +;---------------------------------------------------------------------------- + +.listmacro + + +ipc_update_small_space_size: + + update_small_space_size_immediates + + ret + + + +.nolistmacro + +;---------------------------------------------------------------------------- +; +; init ipcman +; +;---------------------------------------------------------------------------- + + + icode + + + +init_ipcman: + + ; define IDT gate for ipc sc and id nearest sc + mov bh,3 SHL 5 + + mov bl,ipc + mov eax,offset ipc_sc + call define_idt_gate + + mov bl,id_nearest + mov eax,offset id_nearest_sc + call define_idt_gate + + ret + + + + icod ends + + + + + code ends + end diff --git a/l4-x86/smp/lx/kern/kdebug.asm b/l4-x86/smp/lx/kern/kdebug.asm new file mode 100644 index 0000000..b81dd32 --- /dev/null +++ b/l4-x86/smp/lx/kern/kdebug.asm @@ -0,0 +1,5808 @@ +include l4pre.inc + + + dcode + + Copyright IBM+UKA, L4.KDEBUG, 24,08,99, 75 + + +;********************************************************************* +;****** ****** +;****** LN Kernel Debug ****** +;****** ****** +;****** ****** +;****** ****** +;****** ****** +;****** modified: 27.08.99 ****** +;****** ****** +;********************************************************************* + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include schedcb.inc +include intrifc.inc +include pagconst.inc +include syscalls.inc +IFDEF task_proot +include pagmac.inc +include pnodes.inc +ENDIF +include kpage.inc +include l4kd.inc +.list + + +ok_for x86 + + + + + + + public init_default_kdebug + public default_kdebug_exception + public default_kdebug_end + + + extrn grab_frame:near + extrn init_kdio:near + extrn open_debug_keyboard:near + extrn close_debug_keyboard:near + extrn set_remote_info_mode:near + extrn open_debug_screen:near + extrn kd_outchar:near + extrn kd_incharety:near + extrn kd_inchar:near + extrn kd_kout:near + extrn old_pic1_imr:byte + extrn irq0_intr:abs + extrn physical_kernel_info_page:dword + + extrn first_lab:byte + extrn kcod_start:byte + extrn cod_start:byte + extrn dcod_start:byte + extrn scod_start:byte + extrn kernelstring:byte + extrn reset:near + + IF kernel_x2 + extrn enter_single_processor_mode:near + extrn exit_single_processor_mode:near + ENDIF + + + + + assume ds:codseg + + + +;---------------------------------------------------------------------------- +; +; screen +; +;---------------------------------------------------------------------------- + + +lines equ 25 +columns equ 80 + + +;---------------------------------------------------------------------------- +; +; kd intr area +; +;---------------------------------------------------------------------------- + + + + + +kd_xsave_area struc + + kd_es dw 0 + kd_dr7 db 0,0 + kd_ds dw 0,0 + +kd_xsave_area ends + +kd_save_area struc + + dw 0 ; kd_es + db 0,0 ; kd_dr7 + +kd_save_area ends + + + + + + +kdpre macro + + push es + + push eax + mov eax,dr7 + mov ss:[esp+kd_dr7+4],al + mov al,0 + mov dr7,eax + pop eax + + endm + + + +kdpost macro + + push eax + mov eax,dr7 + mov al,ss:[esp+kd_dr7+4] + mov dr7,eax + pop eax + + pop es + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_sema dd 0 + +kdebug_esp dd 0 +kdebug_text dd 0 + + +kdebug_segs_struc struc + + ds_sreg dw 0 + es_sreg dw 0 + +kdebug_segs_struc ends + + + align 4 + +breakpoint_base dd 0 + +breakpoint_thread dd 0 +no_breakpoint_thread dd 0 + +debug_breakpoint_counter_value dd 0 +debug_breakpoint_counter dd 0 + +bx_low dd 0 +bx_high dd 0 +bx_addr dd 0 +bx_size db 0 + +debug_exception_active_flag db false + + align 4 + +debug_exception_handler dd 0 + + + +page_fault_prot_state db 0 + +ipc_prot_state db 0 +ipc_prot_mask db 0FFh + align 4 +ipc_prot_thread dd 0 +ipc_prot_non_thread dd 0 + + + +niltext db 0 + + align 4 + +page_fault_low dd 0 +page_fault_high dd 0FFFFFFFFh + + +page_fault_handler dd 0 + +ipc_handler dd 0 + + +timer_intr_handler dd 0 + +kdebug_timer_intr_counter db 0,0,0,0 + +monitored_exception_handler dd 0 +monitored_ec_min dw 0 +monitored_ec_max dw 0 +monitored_exception db 0 +exception_monitoring_flag db false + db 0,0 + + +kdebug_buffer db 32 dup (0) + + + +;---------------------------------------------------------------------------- +; +; kdebug trace buffer +; +;---------------------------------------------------------------------------- + + align 4 + + +debug_trace_buffer_size equ KB64 + + +trace_buffer_entry struc + + trace_entry_type dd 0 + trace_entry_string dd 0,0,0,0,0 + trace_entry_timestamp dd 0,0 + trace_entry_perf_count0 dd 0 + trace_entry_perf_count1 dd 0 + dd 0,0,0,0,0,0 + +trace_buffer_entry ends + + + +get___timestamp macro + + IFA esp,virtual_space_size + rdtsc + FI + + endm + + + + + + +trace_buffer_begin dd 0 +trace_buffer_end dd 0 +trace_buffer_in_pointer dd 0 + +trace_buffer_active_stamp dd 0,0 + +trace_display_mask dd 0,0 + + +no_references equ 0 +forward_references equ 1 +backward_references equ 2 +performance_counters equ 3 + +display_trace_index_mode equ 0 +display_trace_delta_time_mode equ 1 +display_trace_offset_time_mode equ 2 + +no_perf_mon equ 0 +kernel_perf_mon equ 1 +user_perf_mon equ 2 +kernel_user_perf_mon equ 3 + +trace_link_presentation db display_trace_index_mode +trace_reference_mode db no_references +trace_perf_monitoring_mode db no_perf_mon + + db 0 +kd_proc_dest dd 0 +kd_proc_mask dd 0 +kd_proc_eax dd 0 + + +;---------------------------------------------------------------------------- +; +; init kdebug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +; SS linear kernel space +; +;---------------------------------------------------------------------------- + + + icode + + +init_default_kdebug: + + mov al,'a' + call init_kdio + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + call init_trace_buffer + ret + + + icod ends + + +;---------------------------------------------------------------------------- +; +; prep ds / prep ds & eax +; +;---------------------------------------------------------------------------- + + +prep_ds_es: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug IO call +; +;---------------------------------------------------------------------------- + + align 4 + +kdebug_io_call_tab dd kd_outchar ; 0 + dd outstring ; 1 + dd outcstring ; 2 + dd clear_page ; 3 + dd cursor ; 4 + + dd outhex32 ; 5 + dd outhex20 ; 6 + dd outhex16 ; 7 + dd outhex12 ; 8 + dd outhex8 ; 9 + dd outhex4 ; 10 + dd outdec ; 11 + + dd kd_incharety; 12 + dd kd_inchar ; 13 + dd inhex32 ; 14 + dd inhex16 ; 15 + dd inhex8 ; 16 + dd inhex32 ; 17 + +kdebug_io_calls equ 18 + + + + +kdebug_io_call: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + movzx ebx,ah + IFB_ ebx,kdebug_io_calls + + mov eax,[ebp+ip_eax] + call [ebx*4+kdebug_io_call_tab] + mov [ebp+ip_eax],eax + ELSE_ + mov al,ah + call kd_kout + FI + + jmp ret_from_kdebug + + + + +void: + + ret + + + +;---------------------------------------------------------------------------- +; +; kdebug display +; +;---------------------------------------------------------------------------- + + +kdebug_display: + + IFAE esp, + push phys_mem + pop ds + push phys_mem + pop es + FI + + lea eax,[ebx+2] + call outstring + + jmp ret_from_kdebug + + + +;---------------------------------------------------------------------------- +; +; outstring +; +;---------------------------------------------------------------------------- +; outstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: len_byte,text +; +;---------------------------------------------------------------------------- +; outcstring PRECONDITION: +; +; EAX string addr (phys addr or linear addr (+PM)) +; string format: text,00 +; +;---------------------------------------------------------------------------- + + +outstring: + + and eax,NOT PM + + mov cl,cs:[eax] + inc eax + + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +outcstring: + + and eax,NOT PM + + mov cl,255 + mov ebx,eax + IFNZ cl,0 + DO + mov al,[ebx] + test al,al + EXITZ + call kd_outchar + inc ebx + sub cl,1 + REPEATNZ + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; cursor +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL x +; AH y +; +;---------------------------------------------------------------------------- + + +cursor: + + push eax + mov al,6 + call kd_outchar + mov al,byte ptr ss:[esp+1] + call kd_outchar + pop eax + jmp kd_outchar + + + +;---------------------------------------------------------------------------- +; +; clear page +; +;---------------------------------------------------------------------------- + + +clear_page: + + push eax + push ebx + + mov bl,lines-1 + mov al,1 + call kd_outchar + DO + mov al,5 + call kd_outchar + mov al,10 + call kd_outchar + dec bl + REPEATNZ + OD + mov al,5 + call kd_outchar + + pop ebx + pop ecx + ret + + + + + +;---------------------------------------------------------------------------- +; +; outhex +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +outhex32: + + rol eax,16 + call outhex16 + rol eax,16 + + +outhex16: + + xchg al,ah + call outhex8 + xchg al,ah + + +outhex8: + + ror eax,4 + call outhex4 + rol eax,4 + + + +outhex4: + + push eax + and al,0Fh + add al,'0' + IFA al,'9' + add al,'a'-'0'-10 + FI + call kd_outchar + pop eax + ret + + + +outhex20: + + ror eax,16 + call outhex4 + rol eax,16 + call outhex16 + ret + + + +outhex12: + + xchg al,ah + call outhex4 + xchg ah,al + call outhex8 + ret + + + + + +;---------------------------------------------------------------------------- +; +; outdec +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX value +; +;---------------------------------------------------------------------------- + + +outdec: + + sub ecx,ecx + +outdec_: + + push eax + push edx + + sub edx,edx + push ebx + mov ebx,10 + div ebx + pop ebx + test eax,eax + IFNZ + inc ecx + + call outdec_ + + CORZ ecx,9 + CORZ ecx,6 + IFZ ecx,3 + ; mov al,',' + ; call kd_outchar + FI + dec ecx + FI + mov al,'0' + add al,dl + call kd_outchar + + pop edx + pop eax + ret + + +;---------------------------------------------------------------------------- +; +; inhex +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL / AX / EAX value +; +;---------------------------------------------------------------------------- + + +inhex32: + + push ecx + mov cl,8 + jmp short inhex + + +inhex16: + + push ecx + mov cl,4 + jmp short inhex + + +inhex8: + + push ecx + mov cl,2 + + +inhex: + + push edx + + sub edx,edx + DO + kd____inchar + + IFZ al,'.' + CANDZ ebx,17 + CANDA cl,2 + + call kd_outchar + call inhex8 + and eax,lthreads-1 + shl edx,width lthread_no + add edx,eax + EXIT + FI + + mov ch,al + sub ch,'0' + EXITC + IFA ch,9 + sub ch,'a'-'0'-10 + EXITC + cmp ch,15 + EXITA + FI + call kd_outchar + shl edx,4 + add dl,ch + dec cl + REPEATNZ + OD + mov eax,edx + + pop edx + pop ecx + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; show +; +;---------------------------------------------------------------------------- + + +show macro string,field,aoff + +xoff=0 +IFNB +xoff=aoff +ENDIF + + kd____disp + IF sizeof field eq 1 + mov al,[esi+field+xoff] + kd____outhex8 + ENDIF + IF sizeof field eq 2 + mov ax,[esi+field+xoff] + kd____outhex16 + ENDIF + IF sizeof field eq 4 + mov eax,[esi+field+xoff] + kd____outhex32 + ENDIF + IF sizeof field eq 8 + mov eax,[esi+field+xoff] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[esi+field+xoff+4] + kd____outhex32 + ENDIF + endm + + +;---------------------------------------------------------------------------- +; +; kdebug exception (kernel exception) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack like ipre +; +;---------------------------------------------------------------------------- + + + + + + +default_kdebug_exception: + + ; check if kdebug is locked by another processor + + push ds + push ebx + push eax + + push phys_mem + pop ds + + sub eax,eax + str ax + shr ax,3 + and eax,0ffh + + lock bts [kd_proc_mask],eax + ; if there is a lock, simply wait until it is released + + DO + DO + mov ebx,ds:[kd_proc_dest] + cmp ebx,eax + EXITZ + cmp ebx, 0 + REPEATNZ + OD + mov ebx,eax + lock xchg ds:[kd_proc_dest],ebx + cmp ebx,eax + EXITZ + cmp ebx,0 + EXITZ + lock xchg ds:[kd_proc_dest],ebx + REPEAT + OD +kd_nosynch: + + ; postcondition: kd_proc_dest is set to our PID, which prevents + ; other processors from entering kdebug + + pop eax + mov ds:[kd_proc_eax],eax + + pop ebx + pop ds + + kdpre + + lea ebp,[esp+sizeof kd_save_area] + + + IFAE ebp, + push phys_mem + pop ds + + push eax + movzx eax,[physical_kernel_info_page].kdebug_start_port + IFA eax,16 + call set_remote_info_mode + FI + pop eax + FI + + + IF kernel_x2 + call enter_single_processor_mode + ENDIF + + movzx eax,al + lea esi,[(eax*2)+id_table] + + IFZ al,3 + mov ebx,[ebp+ip_eip] + + IFZ [ebp+ip_cs],linear_space_exec + CANDA ebp, + + push ds + push es + push eax + + push ds + pop es + push linear_space + pop ds + mov edi,offset kdebug_buffer + push edi + mov al,sizeof kdebug_buffer + DO + mov ah,0 + test__page_present ebx + IFNC + mov ah,ds:[ebx] + FI + mov es:[edi],ah + inc ebx + inc edi + dec al + REPEATNZ + OD + pop ebx + + pop eax + pop es + pop ds + FI + + mov ax,[ebx] + cmp al,3Ch ; cmp al + jz kdebug_io_call + cmp al,90h ; nop + jz kdebug_display + + + inc ebx + IFZ ah,4 + CANDZ , + mov ebx,[ebx+1] + add ebx,4 + FI + + mov al,[ebx+1] + IFNZ al,'*' + cmp al,'#' + FI + jz trace_event + + + ELIFAE al,8 + CANDBE al,17 + CANDNZ al,16 + + mov cl,12 + mov edi,offset ec_exception_error_code + DO + mov eax,ss:[ebp+ip_error_code] + shr eax,cl + and eax,0Fh + IFB_ al,10 + add al,'0' + ELSE_ + add al,'a'-10 + FI + mov [edi],al + inc edi + sub cl,4 + REPEATNC + OD + mov ax,[esi] + mov word ptr [ec_exception_id],ax + mov ebx,offset ec_exception_string+PM + ELSE_ + mov ax,[esi] + mov word ptr [exception_id],ax + mov ebx,offset exception_string+PM + FI + + + cli + + IFAE ebp, + mov edi,phys_mem + mov ds,edi + mov es,edi + and ebx,NOT PM + + DO + mov edi,[kdebug_sema] + test edi,edi + EXITZ + xor edi,esp + and edi,-sizeof tcb + EXITZ + pushad + push ds + push es + sub esi,esi + int thread_switch + pop es + pop ds + popad + REPEAT + OD + mov [kdebug_sema],ebp + FI + + + push [kdebug_esp] + push [kdebug_text] + + mov [kdebug_esp],ebp + mov [kdebug_text],ebx + + +;;call open_debug_keyboard + call open_debug_screen + + call show_active_trace_buffer_tail + + kd____disp <6,lines-1,0,13,10> + mov ecx,columns-12 + DO + mov al,'-' + kd____outchar + RLOOP + OD + mov eax,[ebp+ip_eip] + kd____outhex32 + + kd____disp <'=EIP',13,10,6,lines-1,6> + call out_id_text + + DO + call kernel_debug + + cmp bl,'s' + je pseudo_go + + cmp bl,'g' + REPEATNZ + + OD + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + ; release the kdebug flag + + push ds + push eax + + push phys_mem + pop ds + + sub eax,eax + str ax + shr ax,3 + and eax,0ffh + + lock btr ds:[kd_proc_mask],eax + mov ds:[kd_proc_dest],0 + + pop eax + pop ds + +ret_from_kdebug: + + IF kernel_x2 + call exit_single_processor_mode + ENDIF + + kdpost + + ipost + + +pseudo_go: + + ; inform user that we are about to release the debugger + + kd____disp <'switching to next processor',13,10> + + ; do some cleanup + + call flush_active_trace_buffer + + pop [kdebug_text] + pop [kdebug_esp] + + mov [kdebug_sema],0 + + IFZ [ebp+ip_error_code],debug_ec + mov eax,dr7 + mov al,[esp+kd_dr7] + test al,10b + CANDNZ + shr eax,16 + test al,11b + CANDZ + bts [ebp+ip_eflags],r_flag + FI + + ; kd_proc_dest is reset. it is now safe to enter kdebug + + mov [kd_proc_dest],0 + + ; restore old status code to EAX + + mov eax,[kd_proc_eax] + + kdpost + + ; jump back to the top. if any other processor was waiting for + ; kdebug, it has entered by now and stored its PID in kd_proc_dest. + ; if this is not the case, we simply enter again. + + jmp default_kdebug_exception + + + + +id_table db 'DVDBNM03OVBNUD07DF09TSNPSFGPPF15FPAC' + +exception_string db 14,'LN Kernel: #' +exception_id db 'xx' + +ec_exception_string db 21,'LN Kernel: #' +ec_exception_id db 'xx (' +ec_exception_error_code db 'xxxx)' + + + + +;---------------------------------------------------------------------------- +; +; kernel debug +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS,ES phys mem +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; BL exit char +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +kernel_debug: + + push ebp + + call open_debug_keyboard + call open_debug_screen + DO + kd____disp <6,lines-1,0,10> + call get_kdebug_cmd + + DO + cmp al,'g' + OUTER_LOOP EXITZ long + + cmp al,'s' + OUTER_LOOP EXITZ long + + mov ah,[physical_kernel_info_page].kdebug_permissions + + IFZ al,'a' + call display_module_addresses + ELIFZ al,'b',long + call set_breakpoint + ELIFZ al,'t',long + call display_tcb + cmp al,0 + REPEATNZ + ELIFZ al,'d',long + call display_mem + cmp al,0 + REPEATNZ + IFDEF task_proot + ELIFZ al,'p',long + call display_ptabs + cmp al,0 + REPEATNZ + ELIFZ al,'m',long + call display_mappings + cmp al,0 + REPEATNZ + ELIFZ al,'P',long + call page_fault_prot + ELIFZ al,'v',long + call virtual_address_info + ENDIF + ELIFZ al,'k',long + call display_kernel_data + ELIFZ al,'X',long + call monit_exception + ELIFZ al,'I',long + call ipc_prot + ELIFZ al,'R' + call remote_kd_intr + ELIFZ al,'i' + call port_io + ELIFZ al,'o' + call port_io + ELIFZ al,'H' + call halt_current_thread + ELIFZ al,'K' + call ke_disable_reenable + ELIFZ al,' ' + call out_id_text + ELIFZ al,'T' + call dump_trace_buffer + cmp al,0 + REPEATNZ + ELIFZ al,'V' + call set_video_mode + ELIFZ al,'y' + call special_test + ELIFZ al,'^' + call reset_system + ELSE_ + call out_help + FI + OD + REPEAT + OD + + call close_debug_keyboard + mov bl,al + kd____disp <13,10> + + pop ebp + + ret + + + +get_kdebug_cmd: + + kd____disp <6,lines-1,0,'LNKD'> + + ; display processor number on command prompt + + str cx + shr cx,3 + and ecx,0Fh + mov al,030h + add al,cl + kd____outchar + + ; display numbers of processors who are waiting to enter kdebug + +; mov ebx,[kd_proc_mask] +mov ebx,0 ;;; + mov edx,1 + shl edx,cl + + xor ebx,edx + test ebx,0FFh + jz nobody_active + + mov al,'['; + kd____outchar + mov ecx,16 + mov eax,030h +see_active: + test ebx,1 + jz is_not_active + push eax + push ebx + push ecx + kd____outchar + pop ecx + pop ebx + pop eax +is_not_active: + shr ebx,1 + inc eax + loop see_active + mov al,']' + kd____outchar + +nobody_active: + + mov al,':' + kd____outchar + mov al,' ' + kd____outchar + + kd____inchar + push eax + IFAE al,20h + kd____outchar + FI + + pop eax + + ret + + + + +is_main_level_command_key: + + IFNZ al,'a' + CANDNZ al,'b' + CANDNZ al,'t' + CANDNZ al,'d' + CANDNZ al,'p' + CANDNZ al,'m' + CANDNZ al,'k' + CANDNZ al,'m' + CANDNZ al,'P' + CANDNZ al,'I' + CANDNZ al,'X' + CANDNZ al,'T' + CANDNZ al,'R' + CANDNZ al,'i' + CANDNZ al,'o' + CANDNZ al,'H' + CANDNZ al,'K' + CANDNZ al,'V' + CANDNZ al,'g' + CANDNZ al,'s' + IFZ al,'q' + mov al,0 + FI + FI + ret + + + +;---------------------------------------------------------------------------- +; +; reset system +; +;---------------------------------------------------------------------------- + +reset_system: + + push ds + push phys_mem + pop ds + + kd____disp <' RESET ? (y/n)'> + kd____inchar + mov ecx,esp + cmp al,'y' + jz reset + + pop ds + ret + + + +;---------------------------------------------------------------------------- +; +; out id text +; +;---------------------------------------------------------------------------- + + +out_id_text: + + mov al,'"' + kd____outchar + mov eax,cs:[kdebug_text] + kd____outstring + mov al,'"' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; help +; +;---------------------------------------------------------------------------- + +out_help: + + mov al,ah + + kd____disp <13,10,'a : modules, xxxx : find module and rel addr'> + kd____disp <13,10,'t : current tcb, xxxxx : tcb of thread xxxx'> + kd____disp <13,10,' xxx.yy : task xxx, lthread yy'> + test al,kdebug_dump_mem_enabled + IFNZ + kd____disp <13,10,'d : dump mem, xxxxxxxx : dump memory'> + FI + test al,kdebug_dump_map_enabled + IFNZ ,,long + kd____disp <13,10,'p : dump ptab, xxx : ptabs (pdir) of task xxxx'> + kd____disp <13,10,' xxxxx000 : ptab at addr xxxxx000'> + kd____disp <13,10,'m : dump mappings xxxx : mappings of frame xxxx'> + FI + kd____disp <13,10,'k : kernel data'> + kd____disp <13,10,'b : bkpnt, i/w/a/p : set instr/wr/rdwr/ioport bkpnt'> + kd____disp <13,10,' -/b/r : reset/base/restrict'> + test al,kdebug_protocol_enabled + IFNZ ,,long + kd____disp <13,10,'P : monit PF +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'I : monit ipc +/-/*/r : on/off/trace/restrict'> + kd____disp <13,10,'X : monit exc +xx/-/*xx : on/off/trace'> + FI + IFNZ [physical_kernel_info_page].kdebug_pages,0 + kd____disp <13,10,'T : dump trace'> + FI + kd____disp <13,10,'R : remote kd intr +/- : on/off'> + test al,kdebug_io_enabled + IFNZ ,,long + kd____disp <13,10,'i : in port 1/2/4xxxx : byte/word/dword'> + kd____disp <13,10,' apic/PCIconf a/i/pxxxx : apic/ioapic/PCIconf-dword'> + kd____disp <13,10,'o : out port/apic...'> + FI + kd____disp <13,10,'H : halt current thread'> + kd____disp <13,10,'^ : reset system'> + kd____disp <13,10,'K : ke -/+xxxxxxxx: disable/reenable'> + kd____disp <13,10,'V : video mode a/c/m/h : auto/cga/mono/hercules'> + kd____disp <13,10,' 1/2/- : com1/com2/no-com'> + kd____disp <13,10,' : id text [s: switch processor]'> + + ret + + +;---------------------------------------------------------------------------- +; +; set video mode +; +;---------------------------------------------------------------------------- + +set_video_mode: + + kd____inchar + kd____outchar + CORZ al,'2' + IFZ al,'1' + IFZ al,'1' + mov ebx,3F8h SHL 4 + ELSE_ + mov ebx,2F8h SHL 4 + FI + mov al,byte ptr [physical_kernel_info_page].kdebug_start_port + and eax,0Fh + or eax,ebx + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'p',long + kd____disp <'ort: '> + kd____inhex16 + + push eax + kd____disp <' ok? (y/n) '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'z' + pop eax + ret + FI + pop eax + + shl eax,4 + mov bl,byte ptr [physical_kernel_info_page].kdebug_start_port + and bl,0Fh + or al,bl + mov [physical_kernel_info_page].kdebug_start_port,ax + call set_remote_info_mode + + ELIFZ al,'b',long + kd____disp <'aud rate divisor: '> + kd____inhex8 + CORZ al,0 + IFA al,15 + mov al,1 + FI + and byte ptr [physical_kernel_info_page].kdebug_start_port,0F0h + or byte ptr [physical_kernel_info_page].kdebug_start_port,al + IFZ al,12 + kd____disp <' 9600'> + ELIFZ al,6 + kd____disp <' 19200'> + ELIFZ al,3 + kd____disp <' 38400'> + ELIFZ al,2 + kd____disp <' 57600'> + ELIFZ al,1 + kd____disp <' 115200'> + FI + + ELSE_ + kd____outchar + call init_kdio + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; ke disable / reenable +; +;---------------------------------------------------------------------------- + + +ke_disable_reenable: + + IFA esp,max_physical_memory_size + + kd____inchar + mov bl,al + kd____outchar + kd____inhex32 + + mov ebp,[kdebug_esp] + + test eax,eax + IFZ + mov eax,ss:[ebp+ip_eip] + test byte ptr ss:[ebp+ip_cs],11b + IFZ + add eax,PM + FI + FI + + push ds + push linear_kernel_space + pop ds + + dec eax + test__page_writable eax + IFNC + IFZ bl,'-' + CANDZ ,0CCh + mov byte ptr ds:[eax],90h + ELIFZ bl,'+' + CANDZ ,90h + mov byte ptr ds:[eax],0CCh + FI + FI + pop ds + FI + ret + + + +;---------------------------------------------------------------------------- +; +; halt current thread +; +;---------------------------------------------------------------------------- + +halt_current_thread: + + kd____disp <' are you sure? '> + kd____inchar + CORZ al,'j' + IFZ al,'y' + kd____disp <'y',13,10> + call close_debug_keyboard + + sub eax,eax + mov ss:[kdebug_sema+PM],eax + + mov ebp,esp + and ebp,-sizeof tcb + + mov ss:[ebp+coarse_state],unused_tcb + mov ss:[ebp+fine_state],aborted + + DO + ke 'H' + sub esi,esi + int thread_switch + REPEAT + OD + + FI + mov al,'n' + kd____outchar + ret + + +;---------------------------------------------------------------------------- +; +; display_module_addresses +; +;---------------------------------------------------------------------------- + + +display_module_addresses: + + kd____inhex16 + test eax,eax + IFNZ ,,long + + mov esi,offset first_lab + IFB_ eax, + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi] + test edi,edi + IFZ + call to_next_lab + REPEAT + FI + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + ELSE_ + DO + call is_module_header + EXITNZ + movzx edi,word ptr [esi+2] + cmp eax,edi + EXITB + mov ebx,edi + mov edx,esi + call to_next_lab + REPEAT + OD + FI + mov esi,edx + sub eax,ebx + IFNC + push eax + mov ah,lines-1 + mov al,20 + kd____cursor + call display_module + kd____disp <' : '> + pop eax + kd____outhex16 + FI + + + ELSE_ long + + kd____clear_page + mov al,0 + mov ah,1 + kd____cursor + + mov eax,offset kernelstring + kd____outcstring + kd____disp <13,10,10,'kernel: '> + + mov esi,offset first_lab + + DO + call is_module_header + EXITNZ + + movzx edi,word ptr [esi+2] + IFZ edi, + kd____disp <13,'kdebug: '> + ELIFZ edi, + kd____disp <13,'sigma: '> + FI + + call display_module + kd____disp <13,10,' '> + + call to_next_lab + REPEAT + OD + FI + ret + + + +is_module_header: + + mov ecx,32 + push esi + DO + cmp word ptr [esi+8],'C(' + EXITZ + inc esi + RLOOP + OD + pop esi + ret + + + + +to_next_lab: + + add esi,7 + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + DO + inc esi + cmp byte ptr [esi],0 + REPEATNZ + OD + inc esi + ret + + + + +display_module: + + movzx eax,word ptr [esi] + test eax,eax + IFZ + kd____disp <' '> + ELSE_ + kd____outhex16 + kd____disp <','> + FI + movzx eax,word ptr [esi+2] + kd____outhex16 + kd____disp <', '> + + lea ebx,[esi+8] + mov eax,ebx + kd____outcstring + kd____disp <', '> + + DO + cmp byte ptr [ebx],0 + lea ebx,[ebx+1] + REPEATNZ + OD + mov eax,ebx + kd____outcstring + + mov edx,[esi+4] + + kd____disp <', '> + + mov eax,edx + and eax,32-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5 + and eax,16-1 + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,5+4 + and eax,128-1 + add eax,90 + IFAE eax,100 + sub eax,100 + FI + IFB_ eax,10 + push eax + mov al,'0' + kd____outchar + pop eax + FI + kd____outdec + + mov al,' ' + kd____outchar + mov eax,edx + shr eax,16+10 + kd____outdec + mov al,'.' + kd____outchar + mov eax,edx + shr eax,16 + and ah,3 + kd____outdec + + ret + + + +;---------------------------------------------------------------------------- +; +; set breakpoint +; +;---------------------------------------------------------------------------- + + +set_breakpoint: + + mov ebp,[kdebug_esp] + + kd____inchar + IFZ al,13 + + mov ah,lines-1 + mov al,20 + kd____cursor + + mov eax,dr7 + mov al,[ebp-sizeof kd_save_area+kd_dr7] + test al,10b + IFZ + mov al,'-' + kd____outchar + ELSE_ + shr eax,8 + mov al,'I' + test ah,11b + IFNZ + mov al,'W' + test ah,10b + IFNZ + mov al,'A' + FI + kd____outchar + mov eax,dr7 + shr eax,18 + and al,11b + add al,'1' + FI + kd____outchar + kd____disp <' at '> + mov ebx,dr0 + mov eax,[breakpoint_base] + test eax,eax + IFNZ + sub ebx,eax + kd____outhex32 + mov al,'+' + kd____outchar + FI + mov eax,ebx + kd____outhex32 + FI + ret + FI + + IFZ al,'-' + kd____outchar + sub eax,eax + mov dr7,eax + mov [ebp-sizeof kd_save_area+kd_dr7],al + mov dr6,eax + mov [bx_size],al + sub eax,eax + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + + mov eax,[debug_exception_handler] + test eax,eax + IFNZ + mov bl,debug_exception + call set_exception_handler + mov [debug_exception_handler],0 + FI + ret + FI + + push eax + IFZ [debug_exception_handler],0 + mov bl,debug_exception + call get_exception_handler + mov [debug_exception_handler],eax + FI + mov bl,debug_exception + mov eax,offset kdebug_debug_exception_handler + call set_exception_handler + pop eax + + IFZ al,'b' + kd____outchar + kd____inhex32 + mov [breakpoint_base],eax + ret + FI + + CORZ al,'p' + CORZ al,'i' + CORZ al,'w' + IFZ al,'a' + sub ecx,ecx + IFNZ al,'i' + IFZ al,'w' + mov cl,01b + FI + IFZ al,'p' + mov cl,10b + FI + IFZ al,'a' + mov cl,11b + FI + kd____outchar + kd____inchar + IFZ al,'2' + or cl,0100b + ELIFZ al,'4' + or cl,1100b + ELSE_ + mov al,'1' + FI + FI + kd____outchar + shl ecx,16 + mov cx,202h + kd____disp <' at: '> + mov eax,[breakpoint_base] + test eax,eax + IFNZ + kd____outhex32 + mov al,'+' + kd____outchar + FI + kd____inhex32 + add eax,[breakpoint_base] + mov dr0,eax + mov dr7,ecx + mov [ebp-sizeof kd_save_area+kd_dr7],cl + sub eax,eax + mov dr6,eax + + ret + FI + + IFZ al,'r',long + kd____disp <'r',6,lines-1,columns-58,'t/T/124/e/-: thread/non-thread/monit124/reg/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [bx_size],al + mov [breakpoint_thread],eax + mov [no_breakpoint_thread],eax + ret + FI + + + CORZ al,'e' + CORZ al,'1' + CORZ al,'2' + IFZ al,'4',long + sub al,'0' + mov [bx_size],al + IFZ al,'e'-'0',long + kd____disp <8,' E'> + sub ebx,ebx + kd____inchar + and al,NOT ('a'-'A') + mov ah,'X' + IFZ al,'A' + mov bl,7*4 + ELIFZ al,'B' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'P' + mov bl,2*4 + mov ah,al + ELSE_ + mov bl,4*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'C' + mov bl,6*4 + ELIFZ al,'D' + kd____outchar + kd____inchar + and al,NOT ('a'-'A') + IFZ al,'I' + mov bl,0*4 + mov ah,al + ELSE_ + mov bl,5*4 + mov ah,'X' + FI + mov al,0 + ELIFZ al,'S' + mov bl,1*4 + mov ah,'I' + ELIFZ al,'I' + mov bl,8*4+iret_eip+4 + mov ah,'P' + FI + IFNZ al,0 + push eax + kd____outchar + pop eax + FI + mov al,ah + kd____outchar + mov eax,ebx + + ELSE_ + + kd____disp <' at ',> + kd____inhex32 + + FI + mov [bx_addr],eax + kd____disp <' ['> + kd____inhex32 + mov [bx_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [bx_high],eax + mov al,']' + kd____outchar + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [breakpoint_thread],eax + ret + FI + + IFZ al,'T' + kd____inhex16 + mov [no_breakpoint_thread],eax + ret + FI + + mov al,'?' + kd____outchar + ret + FI + + IFZ al,'#' + kd____outchar + kd____inhex32 + mov [debug_breakpoint_counter_value],eax + mov [debug_breakpoint_counter],eax + FI + + ret + + + + +kdebug_debug_exception_handler: + + + push eax + mov eax,dr6 + and al,NOT 1b + mov dr6,eax + + lno___thread eax,esp + + IFZ cs:[no_breakpoint_thread],eax + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + + IFNZ cs:[breakpoint_thread],0 + cmp cs:[breakpoint_thread],eax + CANDNZ + pop eax + bts [esp+iret_eflags],r_flag + iretd + FI + pop eax + + + call check_monitored_data + IFNZ + bts [esp+iret_eflags],r_flag + iretd + FI + + IFA esp,max_physical_memory_size + CANDA ss:[debug_breakpoint_counter_value+PM],0 + dec ss:[debug_breakpoint_counter+PM] + IFNZ + + bts [esp+iret_eflags],r_flag + iretd + + FI + push eax + mov eax,ss:[debug_breakpoint_counter_value+PM] + mov ss:[debug_breakpoint_counter+PM],eax + pop eax + FI + + + jmp cs:[debug_exception_handler] + + + +;---------------------------------------------------------------------------- +; +; check monitored data +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; Z monitored data meets condition +; +; NZ no data monitored OR NOT monitored data meets condition +; +;---------------------------------------------------------------------------- + + +check_monitored_data: + + IFNZ cs:[bx_size],0,long + CANDAE esp,,long + CANDB esp,,long + CANDZ ss:[debug_exception_active_flag+PM],false,long + + pushad + + mov ss:[debug_exception_active_flag+PM],true + mov ebx,ss:[bx_addr+PM] + mov ecx,ss:[bx_low+PM] + mov edx,ss:[bx_high+PM] + mov al,ss:[bx_size+PM] + IFZ al,1 + movzx eax,byte ptr ss:[ebx] + ELIFZ al,2 + movzx eax,word ptr ss:[ebx] + ELIFZ al,4 + mov eax,ss:[ebx] + ELSE_ + mov eax,ss:[esp+ebx] + FI + mov ss:[debug_exception_active_flag+PM],false + + IFBE ecx,edx + CORB eax,ecx + IFA eax,edx + popad + test esp,esp ; NZ ! + ret + FI + ELSE_ + IFA eax,edx + CANDB eax,ecx + popad + test esp,esp ; NZ ! + ret + FI + FI + popad + FI + + cmp eax,eax ; Z ! + ret + + + + +;---------------------------------------------------------------------------- +; +; display tcb +; +;---------------------------------------------------------------------------- + + +display_tcb: + + CORB esp, + IFAE esp, + + kd____clear_page + mov ebp,[kdebug_esp] + add ebp,sizeof tcb/2 + mov esi,ebp + call display_regs_and_stack + + ret + FI + + push ds + push es + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + mov ebp,esp + and ebp,-sizeof tcb + + kd____inhext + test eax,eax + IFZ + mov esi,ebp + ELSE_ + IFB_ eax,threads + shl eax,thread_no + FI + lea___tcb esi,eax + FI + + test__page_present esi + IFC + kd____disp <' not mapped, force mapping (y/n)? '> + kd____inchar + IFNZ al,'y' + CANDNZ al,'j' + mov al,'n' + kd____outchar + mov al,0 + pop es + pop ds + ret + FI + or byte ptr [esi],0 + FI + + kd____clear_page + + kd____disp <6,0,0,'thread: '> + mov eax,[esi+myself] + lno___thread eax,eax + push eax + kd____outhex16 + kd____disp <' ('> + pop eax + push eax + shr eax,width lthread_no + kd____outhex12 + mov al,'.' + kd____outchar + pop eax + and al,lthreads-1 + kd____outhex8 + + show <') ',60>,myself + mov al,62 + kd____outchar + + IFNZ [esi+ressources],0 + kd____disp <6,0,45,'resrc: '> + mov al,[esi+ressources] + test al,mask x87_used + IFNZ + push eax + kd____disp <'num '> + pop eax + FI + test al,mask dr_used + IFNZ + push eax + kd____disp <'dr '> + pop eax + FI + and al,NOT (x87_used+dr_used) + IFNZ + kd____outhex8 + FI + FI + + + show <6,1,0,'state : '>,coarse_state + kd____disp <', '> + mov bl,[esi+fine_state] + test bl,nwait + IFZ + kd____disp <'wait '> + FI + test bl,nclos + IFZ + kd____disp <'clos '> + FI + test bl,nlock + IFZ + kd____disp <'lock '> + FI + test bl,npoll + IFZ + kd____disp <'poll '> + FI + test bl,nready + IFZ + kd____disp <'ready '> + FI + test bl,nwake + IFZ + show <', wakeup: '>,wakeup_low + show <'+'>,wakeup_high + FI + show <6,1,45,'lists: '>,list_state + + show <6,0,72,'prio: '>,prio + IFNZ [esi+max_controlled_prio],0 + show <6,1,73,'mcp: '>,max_controlled_prio + FI + + IFDEF state_sp + movzx eax,[esi+state_sp] + shl eax,2 + IFNZ + push eax + kd____disp <6,2,42,'state_sp: '> + pop eax + kd____outhex12 + FI + ENDIF + + + kd____disp <6,3,0, 'wait for: '> + lea ebx,[esi+waiting_for] + call show_thread_id + + kd____disp <6,4,0, 'sndq : '> + lea ecx,[esi+sndq_root] + call show_llinks + mov al,' ' + kd____outchar + lea ecx,[esi+sndq_llink] + call show_llinks + + show <6,3,40,' rcv descr: '>,rcv_descriptor + show <6,4,40,' timeouts: '>,timeouts + + show <6,3,60,' partner: '>,com_partner + IFDEF waddr + kd____disp <6,4,60,' waddr0/1: '> + mov eax,[esi+waddr] + shr eax,22 + kd____outhex12 + mov al,'/' + kd____outchar + movzx eax,word ptr [esi+waddr] + shr eax,22-16 + kd____outhex12 + ENDIF + + kd____disp <6,5,0, 'cpu time: '> + mov al,[esi+cpu_clock_high] + kd____outhex8 + mov eax,[esi+cpu_clock_low] + kd____outhex32 + + show <' timeslice: '>,rem_timeslice + mov al,'/' + kd____outchar + mov al,[esi+timeslice] + kd____outhex8 + + IFDEF pager + kd____disp <6,7,0, 'pager : '> + lea ebx,[esi+pager] + call show_thread_id + ENDIF + + kd____disp <6,8,0, 'ipreempt: '> + lea ebx,[esi+int_preempter] + call show_thread_id + + kd____disp <6,9,0, 'xpreempt: '> + lea ebx,[esi+ext_preempter] + call show_thread_id + + kd____disp <6, 7,40, 'prsent lnk: '> + test [esi+list_state],is_present + IFNZ + lea ecx,[esi+present_llink] + call show_llinks + FI + kd____disp <6, 8,40, 'ready link : '> + IFDEF ready_llink + test [esi+list_state],is_ready + IFNZ + lea ecx,[esi+ready_llink] + call show_llinks + FI + ELSE + lea ecx,[esi+ready_link] + call show_link + kd____disp <6,9,40, 'intr link : '> + lea ecx,[esi+interrupted_link] + call show_link + ENDIF + + kd____disp <6,10,40, 'soon wakeup lnk: '> + test [esi+list_state],is_soon_wakeup + IFNZ + lea ecx,[esi+soon_wakeup_link] + call show_link + FI + kd____disp <6,11,40, 'late wakeup lnk: '> + test [esi+list_state],is_late_wakeup + IFNZ + lea ecx,[esi+late_wakeup_link] + call show_link + FI + + IFNZ [esi+thread_idt_base],0 + kd____disp <6,7,63,'IDT: '> + mov eax,[esi+thread_idt_base] + kd____outhex32 + FI + + mov eax,[esi+thread_dr7] + test al,10101010b + IFZ ,,long + test al,01010101b + CANDNZ + kd____disp <6,9,63,'DR7: '> + mov eax,[esi+thread_dr7] + kd____outhex32 + kd____disp <6,10,63,'DR6: '> + mov al,[esi+thread_dr6] + mov ah,al + and eax,0000F00Fh + kd____outhex32 + kd____disp <6,11,63,'DR3: '> + mov eax,[esi+thread_dr3] + kd____outhex32 + kd____disp <6,12,63,'DR2: '> + mov eax,[esi+thread_dr2] + kd____outhex32 + kd____disp <6,13,63,'DR1: '> + mov eax,[esi+thread_dr1] + kd____outhex32 + kd____disp <6,14,63,'DR0: '> + mov eax,[esi+thread_dr0] + kd____outhex32 + FI + + + call display_regs_and_stack + + pop es + pop ds + ret + + + + +show_thread_id: + + IFZ ,0 + + kd____disp <'--'> + ELSE_ + mov eax,[ebx] + lno___thread eax,eax + kd____outhex16 + kd____disp <' ',60> + mov eax,[ebx] + kd____outhex32 + mov al,' ' + kd____outchar + mov eax,[ebx+4] + kd____outhex32 + mov al,62 + kd____outchar + FI + + ret + + + + +show_llinks: + + mov eax,[ecx].succ + test eax,eax + IFNZ + CANDNZ eax,-1 + call show_link + mov al,1Dh + kd____outchar + add ecx,offset pred + call show_link + sub ecx,offset pred + FI + ret + + + +show_link: + + mov eax,[ecx] + IFAE eax, + CANDB eax, + lno___thread eax,eax + kd____outhex16 + ret + FI + IFAE eax, + CANDB eax, + push eax + kd____disp <' i'> + pop eax + sub eax,offset intrq_llink + shr eax,3 + kd____outhex8 + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + IFAE eax, + CANDB eax, + kd____disp <' -- '> + ret + FI + test eax,eax + IFZ + kd____disp <' -- '> + ret + FI + kd____outhex32 + ret + + + + +show_reg macro txt,reg + + kd____disp + mov eax,[ebp+ip_®] + kd____outhex32 + endm + + + +show_sreg macro txt,sreg + + kd____disp + mov ax,[ebp+ip_&sreg] + kd____outhex16 + endm + + + + +display_regs_and_stack: + + test cs:[physical_kernel_info_page].kdebug_permissions,kdebug_dump_regs_enabled + IFZ + mov al,0 + ret + FI + + + IFZ esi,ebp + mov eax,cs:[kdebug_esp] + test eax,eax + CANDNZ + mov ebx,eax + mov ecx,eax + lea ebp,[eax+sizeof int_pm_stack-sizeof iret_vec] + ELSE_ + mov ebx,[esi+thread_esp] + test bl,11b + CORNZ + CORB ebx,esi + lea ecx,[esi+sizeof tcb] + IFAE ebx,ecx + sub ebx,ebx + FI + sub ecx,ecx ; EBX : stack top + mov ebp,ebx ; ECX : reg pointer / 0 + FI ; EBP : cursor pointer + +; IFAE ebx,KB256 +; CORB ebx,esi +; lea eax,[esi+sizeof pl0_stack] +; IFAE ebx,eax +; mov al,0 +; ret +; FI +; FI + + + DO + pushad + call show_regs_and_stack + popad + + call get_kdebug_cmd + call is_main_level_command_key + EXITZ + + IFZ al,2 + add ebp,4 + FI + IFZ al,8 + sub ebp,4 + FI + IFZ al,10 + add ebp,32 + FI + IFZ al,3 + sub ebp,32 + FI + mov edx,ebp + and edx,-sizeof tcb + add edx,sizeof pl0_stack-4 + IFA ebp,edx + mov ebp,edx + FI + IFB_ ebp,ebx + mov ebp,ebx + FI + + IFZ al,13 + lea ecx,[ebp-(sizeof int_pm_stack-sizeof iret_vec)] + IFB_ ecx,ebx + mov ecx,ebx + FI + FI + + REPEAT + OD + ret + + + +show_regs_and_stack: + + test ecx,ecx + IFNZ ,,long + push ebp + mov ebp,ecx + show_reg <6,11,0, 'EAX='>,eax + show_reg <6,12,0, 'EBX='>,ebx + show_reg <6,13,0, 'ECX='>,ecx + show_reg <6,14,0, 'EDX='>,edx + show_reg <6,11,14,'ESI='>,esi + show_reg <6,12,14,'EDI='>,edi + show_reg <6,13,14,'EBP='>,ebp + + IFZ ebp,cs:[kdebug_esp] + + kd____disp <6,11,28,'DS='> + mov ax,[ebp-sizeof kd_save_area].kd_ds + kd____outhex16 + kd____disp <6,12,28,'ES='> + mov ax,[ebp-sizeof kd_save_area].kd_es + kd____outhex16 + ELSE_ + kd____disp <6,11,28,' ',6,12,28,' '> + FI + pop ebp + FI + + kd____disp <6,14,14,'ESP='> + mov eax,ebp + kd____outhex32 + + test ebp,ebp + IFNZ ,,long + + lea ebx,[esi+sizeof pl0_stack-8*8*4] + IFA ebx,ebp + mov ebx,ebp + FI + and bl,-32 + mov cl,16 + DO + mov ah,cl + mov al,0 + kd____cursor + mov eax,ebx + kd____outhex12 + mov al,':' + kd____outchar + mov al,5 + kd____outchar + add ebx,32 + inc cl + cmp cl,16+8 + REPEATB + OD + lea ebx,[esi+sizeof pl0_stack] + sub ebx,ebp + IFC + sub ebx,ebx + FI + shr ebx,2 + DO + cmp ebx,8*8 + EXITBE + sub ebx,8 + REPEAT + OD + sub ebx,8*8 + neg ebx + DO + mov eax,ebx + and al,7 + imul eax,9 + IFAE eax,4*9 + add eax,3 + FI + add eax,6 + mov ah,bl + shr ah,3 + add ah,16 + kd____cursor + mov eax,[ebp] + kd____outhex32 + inc ebx + add ebp,4 + cmp ebx,8*8 + REPEATB + OD + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; display mem +; +;---------------------------------------------------------------------------- + + +display_mem: + + test ah,kdebug_dump_mem_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_base],0 + mov [dump_area_size],linear_address_space_size + + kd____inhex32 + test eax,eax + IFZ ,,long + mov eax,ss + CANDZ eax,linear_kernel_space,long + kd____disp <' Gdt/Idt/Task/Sigma0/Redir ? '> ;REDIR ---- + kd____inchar + IFZ al,'g' + mov eax,offset gdt + ELIFZ al,'i' + mov eax,offset idt + IFDEF task_proot + ELIFZ al,'t' + mov eax,offset task_proot + ENDIF + ELIFZ al,'s' + mov edi,offset logical_info_page + mov eax,ss:[edi+reserved_mem1].mem_begin + mov ecx,ss:[edi+main_mem].mem_end + shr ecx,log2_pagesize + sub eax,ecx + and eax,-pagesize + add eax,PM + ELIFZ al,'r' ;REDIR begin ---------------- + kd____disp <'task: '> ; + kd____inhex16 ; + and eax,tasks-1 ; + shl eax,log2_tasks+2 ; + add eax,offset redirection_table ; + ; mov [dump_area_size],tasks*4 ;REDIR ends ----------------- + ELSE_ + sub eax,eax + FI + FI + + mov esi,eax + mov edi,eax + + kd____clear_page + + push esi + push edi + mov ebp,offset dump_dword + DO + mov al,'d' + call dump + IFZ al,13 + CANDNZ edx,0 + pop eax + pop eax + push esi + push edi + mov edi,edx + mov esi,edx + REPEAT + FI + IFZ al,1 + pop edi + pop esi + push esi + push edi + REPEAT + FI + call is_main_level_command_key + REPEATNZ + OD + pop esi + pop edi + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + +dump_dword: + + call display_dword + mov ebx,esi + ret + + + + +;---------------------------------------------------------------------------- +; +; display ptab +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +display_ptabs: + + test ah,kdebug_dump_map_enabled + IFZ + mov al,0 + ret + FI + + + mov [dump_area_size],pagesize + + kd____inhex32 + + test eax,eax + IFZ + mov eax,cr3 + ELIFB eax,tasks + mov ebx,cr0 + bt ebx,31 + CANDC + push ds + push linear_kernel_space + pop ds + load__proot eax,eax + pop ds + FI + and eax,-pagesize + mov [dump_area_base],eax + + kd____clear_page + + DO + mov esi,[dump_area_base] + + mov edi,esi + mov ebp,offset dump_pdir + DO + mov al,'p' + call dump + + cmp al,13 + EXITNZ long + + test edx,edx + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,edx + mov ebp,offset dump_ptab + xchg [dump_area_base],edx + push edx + DO + mov al,'p' + call dump + + IFZ al,'m' + push esi + push edi + push ebp + mov eax,edx + call display_mappings_of + pop ebp + pop edi + pop esi + cmp al,1 + REPEATZ + EXIT + FI + + cmp al,13 + EXITNZ + + test edx,edx + REPEATZ + + test [physical_kernel_info_page].kdebug_permissions,kdebug_dump_mem_enabled + REPEATZ + + push esi + push edi + push ebp + mov esi,edx + mov edi,esi + mov ebp,offset dump_page + xchg [dump_area_base],edx + push edx + DO + mov al,'d' + call dump + cmp al,13 + REPEATZ + OD + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + + call is_main_level_command_key + REPEATNZ + + OD + + pop [dump_area_base] + pop ebp + pop edi + pop esi + + cmp al,1 + REPEATZ + OD + + cmp al,1 + REPEATZ + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + ret + + + + +dump_pdir: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,22-2 + mov [virt_4M_base],ebx + + ret + + + +dump_ptab: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + and edx,-pagesize + + mov ebx,esi + and ebx,pagesize-1 + shl ebx,12-2 + add ebx,[virt_4M_base] + mov [virt_4K_base],ebx + + ret + + + + +dump_page: + + push esi + mov eax,cr0 + bt eax,31 + IFC + add esi,PM + FI + call display_dword + pop esi + + mov ebx,esi + and ebx,pagesize-1 + add ebx,[virt_4K_base] + + ret + + + + ENDIF + + + align 4 + + +virt_4M_base dd 0 +virt_4K_base dd 0 + +dump_area_base dd 0 +dump_area_size dd -1 + +dump_type db 'd' + + +;---------------------------------------------------------------------------- +; +; dump +; +;---------------------------------------------------------------------------- +;PRECONDITION: +; +; AL dump type +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +;---------------------------------------------------------------------------- +;POSTCONDITION: +; +; ESI actual dump dword address (0 mod 4) +; EDI begin of dump address (will be 8*4-aligned) +; EBP dump operation +; +; EBX,EDX can be loaded by dump operation +; +; EAX,ECX scratch +; +;---------------------------------------------------------------------------- + +dumplines equ (lines-1) + + +dump: + + mov [dump_type],al + + mov al,0 + DO + mov ecx,[dump_area_base] + IFB_ esi,ecx + mov esi,ecx + FI + IFB_ edi,ecx + mov edi,ecx + FI + add ecx,[dump_area_size] + sub ecx,4 + IFA esi,ecx + mov esi,ecx + FI + sub ecx,dumplines*8*4-4 + IFA edi,ecx + mov edi,ecx + FI + + and esi,-4 + + IFB_ esi,edi + mov edi,esi + mov al,0 + FI + lea ecx,[edi+dumplines*8*4] + IFAE esi,ecx + lea edi,[esi-(dumplines-1)*8*4] + mov al,0 + FI + and edi,-8*4 + + IFZ al,0 + + push esi + mov esi,edi + mov ch,lines-dumplines-1 + DO + mov cl,0 + mov eax,ecx + kd____cursor + mov eax,esi + kd____outhex32 + mov al,':' + kd____outchar + add cl,8+1 + + DO + call ebp + add esi,4 + add cl,8+1 + cmp cl,80 + REPEATB + OD + + inc ch + cmp ch,lines-1 + EXITAE + mov eax,[dump_area_base] + add eax,[dump_area_size] + dec eax + cmp esi,eax + REPEATB + OD + pop esi + FI + + mov ecx,esi + sub ecx,edi + shr ecx,2 + + mov ch,cl + shr ch,3 + add ch,lines-dumplines-1 + mov al,cl + and al,8-1 + mov ah,8+1 + IFZ [dump_type],'c' + mov ah,4 + FI + imul ah + add al,9 + mov cl,al + + mov eax,ecx + kd____cursor + + call ebp + kd____disp <6,lines-1,0,'LNKD: '> + mov al,[dump_type] + kd____outchar + mov al,'<' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,'>' + kd____outchar + kd____disp <6,lines-1,columns-35,'++KEYS: ',24,' ',25,' ',26,' ',27,' Pg',24,' Pg',25,' CR Home '> + IFDEF task_proot + IFZ ebp, + kd____disp <6,lines-1,columns-3,3Ch,'m',3Eh> + FI + ENDIF + mov eax,ecx + kd____cursor + + kd____inchar + + IFZ al,2 + add esi,4 + FI + IFZ al,8 + sub esi,4 + FI + IFZ al,10 + add esi,8*4 + FI + IFZ al,3 + sub esi,8*4 + FI + CORZ al,'+' + IFZ al,11h + add esi,dumplines*8*4 AND -100h + add edi,dumplines*8*4 AND -100h + mov al,0 + FI + CORZ al,'-' + IFZ al,10h + sub esi,dumplines*8*4 AND -100h + sub edi,dumplines*8*4 AND -100h + mov al,0 + FI + IFZ al,' ' + mov al,[dump_type] + IFZ al,'d' + mov al,'b' + ELIFZ al,'b' + mov al,'c' + ELIFZ al,'c' + mov al,'p' + ELSE_ + mov al,'d' + FI + mov [dump_type],al + kd____clear_page + mov al,0 + FI + + cmp al,1 + EXITZ + cmp al,13 + REPEATB + OD + + ret + + + + + +display_dword: + + mov eax,esi + lno___task ebx,esp + call page_phys_address + + IFZ + IFZ [dump_type],'c' + kd____disp <250,250,250,250> + ELSE_ + kd____disp <250,250,250,250,250,250,250,250,250> + FI + sub edx,edx + ret + FI + + mov edx,[eax] + + mov al,[dump_type] + IFZ al,'d' + IFZ edx,0 + kd____disp <' 0'> + ELIFZ edx,-1 + kd____disp <' -1'> + sub edx,edx + ELSE_ + mov eax,edx + kd____outhex32 + FI + mov al,' ' + kd____outchar + ret + FI + IFZ al,'b' + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + shr edx,16 + mov al,dl + kd____outhex8 + mov al,dh + kd____outhex8 + sub edx,edx + mov al,' ' + kd____outchar + ret + FI + IFZ al,'c' + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + shr edx,8 + call out_dump_char + sub edx,edx + ret + FI + IFZ al,'p',long + + IFZ edx,0 + kd____disp <' - '> + ELSE_ + test dl,page_present + ;; IFZ + ;; mov eax,edx + ;; kd____outhex32 + ;; mov al,' ' + ;; kd____outchar + ;; ret + ;; FI + call dump_pte + FI + ret + + FI + + sub edx,edx + ret + + + + + +out_dump_char: + + mov al,dl + IFB_ al,20h + mov al,'.' + FI + kd____outchar + ret + + + + +dump_pte: + + + mov eax,edx + shr eax,28 + IFZ + mov al,' ' + ELIFB al,10 + add al,'0' + ELSE_ + add al,'A'-10 + FI + kd____outchar + mov eax,edx + test dl,superpage + CORZ + test edx,(MB4-1) AND -pagesize + IFNZ + shr eax,12 + kd____outhex16 + ELSE_ + shr eax,22 + shl eax,2 + kd____outhex8 + mov al,'/' + bt edx,shadow_ptab_bit + IFC + mov al,'*' + FI + kd____outchar + mov al,'4' + kd____outchar + FI + mov al,'-' + kd____outchar + test dl,page_write_through + IFNZ + mov al,19h + FI + test dl,page_cache_disable + IFNZ + mov al,17h + FI + kd____outchar + test dl,page_present + IFNZ + mov al,'r' + test dl,page_write_permit + IFNZ + mov al,'w' + FI + ELSE_ + mov al,'y' + test dl,page_write_permit + IFNZ + mov al,'z' + FI + FI + test dl,page_user_permit + IFZ + sub al,'a'-'A' + FI + kd____outchar + mov al,' ' + kd____outchar + + ret + + + + + + + + + + +;---------------------------------------------------------------------------- +; +; display mappings +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + + +display_mappings: + + IFB_ esp, + ret + FI + + kd____inhex32 + shl eax,log2_pagesize + + + +display_mappings_of: + + push ds + push es + + push linear_kernel_space + pop ds + push linear_kernel_space + pop es + + + mov esi,eax + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + lea edi,[eax+pnode_base] + mov ebx,edi + + kd____clear_page + sub eax,eax + kd____cursor + + kd____disp <'phys frame: '> + mov eax,esi + kd____outhex32 + + kd____disp <' cache: '> + mov eax,[edi+cache0] + kd____outhex32 + mov al,',' + kd____outchar + mov eax,[edi+cache1] + kd____outhex32 + + kd____disp <13,10,10> + + mov cl,' ' + DO + mov eax,edi + kd____outhex32 + kd____disp <' '> + mov al,cl + kd____outchar + + kd____disp <' pte='> + mov eax,[edi+pte_ptr] + kd____outhex32 + kd____disp <' ('> + mov eax,[edi+pte_ptr] + mov edx,[eax] + call dump_pte + kd____disp <') v=...'> + mov eax,[edi+pte_ptr] + and eax,pagesize-1 + shr eax,2 + kd____outhex12 + kd____disp <'000 ',25> + mov eax,[edi+child_pnode] + kd____outhex32 + mov al,' ' + kd____outchar + IFNZ edi,ebx + mov eax,[edi+pred_pnode] + kd____outhex32 + mov al,29 + kd____outchar + mov eax,[edi+succ_pnode] + kd____outhex32 + FI + + kd____inchar + + IFZ al,10 + mov cl,25 + mov edi,[edi+child_pnode] + ELIFZ al,8 + CANDNZ edi,ebx + mov cl,27 + mov edi,[edi+pred_pnode] + ELIFZ al,2 + CANDNZ edi,ebx + mov cl,26 + mov edi,[edi+succ_pnode] + ELSE_ + call is_main_level_command_key + EXITZ + FI + kd____disp <13,10> + + and edi,-sizeof pnode + REPEATNZ + + mov edi,ebx + REPEAT + OD + + push eax + mov ah,lines-1 + mov al,0 + kd____cursor + kd____disp <'LNKD: ',5> + pop eax + push eax + IFAE al,20h + kd____outchar + FI + pop eax + + pop es + pop ds + ret + + + ENDIF + + + +;---------------------------------------------------------------------------- +; +; display kernel data +; +;---------------------------------------------------------------------------- + + +display_kernel_data: + + IFB_ esp, + ret + FI + + push ds + push es + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + + kd____clear_page + + sub esi,esi ; required for show macro ! + + show <6,2,1,'sys clock : '>,system_clock_high + mov eax,ds:[system_clock_low] + kd____outhex32 + + kd____disp <6,7,40,'present root : '> + mov eax,offset present_root + lno___thread eax,eax + kd____outhex16 + + IFDEF highest_active_prio + kd____disp <6,6,1,'highest prio : '> + mov eax,ds:[highest_active_prio] + lno___thread eax,eax + kd____outhex16 + + ELSE + kd____disp <6,6,1,'ready actual : '> + mov eax,ds:[ready_actual] + lno___thread eax,eax + kd____outhex16 + + kd____disp <6,8,1,'ready root : '> + mov ecx,offset dispatcher_tcb+ready_link + call show_link + kd____disp <6,9,1,'intr root : '> + mov ecx,offset dispatcher_tcb+interrupted_link + call show_link + ENDIF + + kd____disp <6,11,1, 'soon wakeup root :'> + mov ecx,offset dispatcher_tcb+soon_wakeup_link + call show_link + kd____disp <6,12,1, 'late wakeup root :'> + mov ecx,offset dispatcher_tcb+late_wakeup_link + call show_link + + kd____disp <6,11,40, 'intrq link :'> + sub ebx,ebx + DO + mov eax,ebx + and al,7 + imul eax,5 + add al,41 + mov ah,bl + shr ah,3 + add ah,12 + kd____cursor + lea ecx,[(ebx*4)+intrq_llink] + call show_llinks + add ebx,2 + cmp ebx,lengthof intrq_llink + REPEATB + OD + + kd____disp <6,18,61,' CR3 : '> + mov eax,cr3 + kd____outhex32 + + kd____disp <6,19,61,'ESP0 : '> + mov eax,ds:[cpu_esp0] + kd____outhex32 + + pop es + pop ds + ret + + + + +;---------------------------------------------------------------------------- +; +; page fault prot +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +page_fault_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + + CORZ al,'+' + IFZ al,'*' + mov [page_fault_prot_state],al + kd____outchar + IFZ [page_fault_handler],0 + mov bl,page_fault + call get_exception_handler + mov [page_fault_handler],eax + FI + mov eax,offset show_page_fault + mov bl,page_fault + call set_exception_handler + ret + FI + IFZ al,'-' + mov [page_fault_prot_state],al + kd____outchar + sub ecx,ecx + mov [page_fault_low],ecx + dec ecx + mov [page_fault_high],ecx + sub eax,eax + xchg eax,[page_fault_handler] + test eax,eax + IFNZ + mov bl,page_fault + call set_exception_handler + FI + ret + FI + IFZ al,'x' + mov [page_fault_prot_state],al + kd____disp 'x [' + kd____inhex32 + mov [page_fault_low],eax + mov al,',' + kd____outchar + kd____inhex32 + mov [page_fault_high],eax + mov al,']' + kd____outchar + ret + FI + + mov al,'?' + kd____outchar + + ret + + + +show_page_fault: + + ipre ec_present + + mov eax,cr2 + and eax,-pagesize + IFNZ eax,,long + CANDAE eax,[page_fault_low+PM],long + CANDBE eax,[page_fault_high+PM],long + + mov ebx,cr2 + mov ecx,[esp+ip_eip] + lno___thread eax,esp + shl eax,8 + + IFZ [page_fault_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_page_fault + call event_ack + FI + FI + + pop ds + + popad + jmp cs:[page_fault_handler] + + + + + +display_page_fault: ; EBX fault address + ; ECX fault EIP + ; EAX thread no SHL 8 + 00 + + ; --> EAX scratch + mov edx,eax + shr edx,8 + kd____disp <'#PF: '> + mov eax,ebx + kd____outhex32 + kd____disp <', eip='> + mov eax,ecx + kd____outhex32 + kd____disp <', thread='> + mov eax,edx + kd____outhex16 + + ret + + + ENDIF + + + +event_ack: + + call open_debug_keyboard + kd____inchar + IFZ al,'i' + ke 'kdebug' + FI + call close_debug_keyboard + + ret + + + +;---------------------------------------------------------------------------- +; +; IPC prot +; +;---------------------------------------------------------------------------- + + +ipc_prot: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + mov eax,cr0 + bt eax,31 + CORNC + mov eax,ss + IFNZ eax,linear_kernel_space + + mov al,'-' + kd____outchar + ret + FI + + + kd____inchar + kd____outchar + + CORZ al,'+' + IFZ al,'*' + mov [ipc_prot_state],al + IFZ [ipc_handler],0 + mov bl,ipc + call get_exception_handler + mov [ipc_handler],eax + FI + mov eax,offset show_ipc + mov bl,ipc + call set_exception_handler + ret + FI + IFZ al,'-' + sub eax,eax + xchg eax,[ipc_handler] + test eax,eax + IFNZ + mov bl,ipc + call set_exception_handler + FI + ret + FI + + IFZ al,'r',long + kd____disp <6,lines-1,columns-58,'t/T/s/- : thread/non-thread/send-only/reset restrictions',6,lines-1,8> + kd____inchar + kd____disp <5> + kd____outchar + + IFZ al,'-' + sub eax,eax + mov [ipc_prot_thread],eax + mov [ipc_prot_non_thread],eax + mov [ipc_prot_mask],0FFh + ret + FI + + IFZ al,'t' + kd____inhex16 + mov [ipc_prot_thread],eax + ret + FI + IFZ al,'T' + kd____inhex16 + mov [ipc_prot_non_thread],eax + ret + FI + + IFZ al,'s' + mov [ipc_prot_mask],08h + ret + FI + FI + + mov al,'?' + kd____outchar + + ret + + + +show_ipc: + + ipre fault + + mov ecx,ebp + and cl,11b + IFB_ ebp,virtual_space_size + or cl,100b + FI + and al,11b + IFB_ eax,virtual_space_size + or al,100b + FI + shl cl,3 + add cl,al + add cl,40h + lno___thread eax,esp + + IFNZ [ipc_prot_thread+PM],0 + cmp [ipc_prot_thread+PM],eax + FI + IFZ + CANDNZ eax,[ipc_prot_non_thread+PM] + test cl,[ipc_prot_mask+PM] + CANDNZ + + shl eax,8 + mov al,cl + mov ecx,esi + + IFZ [ipc_prot_state+PM],'*' + + call put_into_trace_buffer + + ELSE_ + kd____disp <13,10> + call display_ipc + call event_ack + FI + FI + + pop ds + + popad + add esp,4 + jmp cs:[ipc_handler] + + + + +display_ipc: ; EAX : src SHL 8 + ipc type + ; EBX : msg w1 + ; ECX : dest + ; EDX : msg w0 + + ; --> EAX scratch + kd____disp <'ipc: '> + push eax + shr eax,8 + kd____outhex16 + pop eax + + mov ah,al + and al,00101100b + push eax + + IFZ al,00100000b + kd____disp <' waits for '> + ELIFZ al,00101000b + kd____disp <' waits '> + ELIFZ al,00000100b + kd____disp <' -sends--> '> + ELIFZ al,00100100b + kd____disp <' -calls--> '> + ELIFZ al,00101100b + kd____disp <' replies-> '> + FI + IFNZ al,00101000b + lno___thread eax,ecx + test eax,eax + IFZ + kd____disp <' - '> + ELSE_ + kd____outhex16 + FI + FI + pop eax + + push eax + test al,00000100b + IFNZ + test ah,00000010b + IFZ + kd____disp <' ('> + ELSE_ + kd____disp <' map ('> + FI + mov eax,edx + kd____outhex32 + mov al,',' + kd____outchar + mov eax,ebx + kd____outhex32 + mov al,')' + kd____outchar + FI + pop eax + + IFZ al,00101100b + kd____disp <' and waits'> + FI + + ret + + + +;---------------------------------------------------------------------------- +; +; monit exception +; +;---------------------------------------------------------------------------- + + +monit_exception: + + test ah,kdebug_protocol_enabled + IFZ + mov al,0 + ret + FI + + + kd____inchar + kd____outchar + + push eax + CORZ al,'*' + CORZ al,'+' + IFZ al,'-' + + mov al,false + xchg al,[exception_monitoring_flag] + IFZ al,true + mov eax,[monitored_exception_handler] + mov bl,[monitored_exception] + call set_exception_handler + FI + FI + pop eax + + + CORZ al,'*' + IFZ al,'+' + + kd____disp <' #'> + kd____inhex8 + + CORZ al,debug_exception + CORZ al,breakpoint + IFA al,sizeof idt/8 + mov al,'-' + kd____outchar + ret + FI + + mov [exception_monitoring_flag],true + mov [monitored_exception],al + mov bl,al + + IFAE al,11 + CANDB al,15 + + kd____disp <' ['> + kd____inhex16 + mov [monitored_ec_min],ax + mov al,',' + kd____outchar + kd____inhex16 + mov [monitored_ec_max],ax + mov al,']' + kd____outchar + FI + + call get_exception_handler + mov [monitored_exception_handler],eax + + mov eax,offset exception_monitor + call set_exception_handler + FI + + ret + + + + + +exception_monitor: + + ipre ec_present + + mov al,cs:[monitored_exception] + mov ebp,esp + DO + + IFZ al,general_protection + CANDZ ss:[ebp+ip_cs],linear_space_exec + bt ss:[ebp+ip_eflags],vm_flag + CANDNC + cmp ss:[ebp+ip_ds],0 + EXITZ + + mov ebx,ss:[ebp+ip_eip] + mov ecx,ebx + and ecx,pagesize-1 + IFBE ecx,pagesize-4 + push ds + mov ds,ss:[ebp+ip_cs] + mov ebx,[ebx] + pop ds + cmp bx,010Fh ; LIDT (emulated) etc. + EXITZ + FI + FI + + IFAE al,11 + CANDB al,15 + movzx eax,word ptr ss:[ebp+ip_error_code] + movzx ebx,cs:[monitored_ec_min] + movzx ecx,cs:[monitored_ec_max] + IFBE ebx,ecx + cmp eax,ebx + EXITB + cmp eax,ecx + EXITA + ELSE_ + IFBE eax,ebx + cmp eax,ecx + EXITAE + FI + FI + FI + + ke 'INTR' + + OD + + + pop ds + + popad + + CORB cs:[monitored_exception],8 + IFA cs:[monitored_exception],14 + IFNZ cs:[monitored_exception],17 + add esp,4 + FI + FI + + jmp cs:[monitored_exception_handler] + + + + +;---------------------------------------------------------------------------- +; +; remote kd intr +; +;---------------------------------------------------------------------------- + + +remote_kd_intr: + + kd____inchar + + IFZ al,'+' + CANDAE esp, + CANDB esp, + + kd____outchar + IFZ [timer_intr_handler],0 + mov bl,irq0_intr+8 + call get_exception_handler + mov [timer_intr_handler],eax + FI + mov eax,offset kdebug_timer_intr_handler + ELSE_ + mov al,'-' + kd____outchar + sub eax,eax + xchg eax,[timer_intr_handler] + FI + test eax,eax + IFNZ + mov bl,irq0_intr+8 + call set_exception_handler + FI + ret + + + +kdebug_timer_intr_handler: + + dec byte ptr ss:[kdebug_timer_intr_counter+PM] + IFZ + + ipre fault,no_load_ds + + kd____incharety + IFZ al,27 + ke 'ESC' + FI + + ko T + + pop ds + + popad + add esp,4 + FI + + jmp cs:[timer_intr_handler] + + + +;---------------------------------------------------------------------------- +; +; single stepping on/off +; +;---------------------------------------------------------------------------- +; +; +; +;single_stepping_on_off: +; +; kd____inchar +; mov edi,[kdebug_esp] +; IFA edi, +; push ds +; push linear_kernel_space +; pop ds +; FI +; +; IFZ al,'+' +; bts [edi+ip_eflags],t_flag +; else_ +; btr [edi+ip_eflags],t_flag +; mov al,'-' +; FI +; +; IFA edi, +; pop ds +; FI +; kd____outchar +; ret + + + +;---------------------------------------------------------------------------- +; +; virtual address info +; +;---------------------------------------------------------------------------- + + + IFDEF task_proot + + +virtual_address_info: + + kd____inhex32 + mov ebx,eax + kd____disp <' Task='> + kd____inhex16 + test eax,eax + IFZ + lno___task eax,esp + FI + xchg eax,ebx + call page_phys_address + IFZ + kd____disp <' not mapped'> + ELSE_ + push eax + kd____disp <' phys address = '> + pop eax + kd____outhex32 + FI + + ret + + + ENDIF + +;---------------------------------------------------------------------------- +; +; port io +; +;---------------------------------------------------------------------------- + + +pic1_imr equ 21h + + +pci_address_port equ 0CF8h +pci_data_port equ 0CFCh + + +port_io: + + test ah,kdebug_io_enabled + IFZ + mov al,0 + ret + FI + + + + mov bh,al + IFZ al,'i' + kd____disp <'n '> + ELSE_ + kd____disp <'ut '> + FI + + kd____inchar + mov bl,al + kd____outchar + IFZ al,'a' + kd____disp <'pic '> + ELIFZ al,'i' + kd____disp <'o apic '> + ELIFZ al,'p' + kd____disp <'ci conf dword '> + ELSE_ + kd____disp <'-byte port '> + FI + + kd____inhex16 + mov edx,eax + + kd____disp <': '> + IFZ bh,'o' + kd____inhex32 + FI + + IFZ bl,'1' + + IFZ bh,'o' + IFZ dx,pic1_imr + mov [old_pic1_imr],al + ELSE_ + out dx,al + FI + ELSE_ + IFZ dx,pic1_imr + mov al,[old_pic1_imr] + ELSE_ + in al,dx + FI + kd____outhex8 + FI + ret + FI + + IFZ bl,'2' + + IFZ bh,'o' + out dx,ax + ELSE_ + in ax,dx + kd____outhex16 + FI + ret + FI + + IFZ bl,'4' + + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + IFZ bl,'p' + + push eax + mov eax,edx + or eax,8000000h + mov dx,pci_address_port + out dx,eax + pop eax + + mov dx,pci_data_port + IFZ bh,'o' + out dx,eax + ELSE_ + in eax,dx + kd____outhex32 + FI + ret + FI + + + + + + + + + IFB_ esp,virtual_space_size + ret + FI + + + push ds + push linear_kernel_space + pop ds + + + IFZ bl,'a' + + and edx,00000FF0h + IFZ bh,'o' + mov ds:[edx+local_apic],eax + ELSE_ + mov eax,ds:[edx+local_apic] + kd____outhex32 + FI + + ELIFZ bl,'i' + + and edx,000000FFh + mov byte ptr ds:[io_apic+0],dl + IFZ bh,'o' + mov ds:[io_apic+10h],eax + ELSE_ + mov eax,ds:[io_apic+10h] + kd____outhex32 + FI + FI + + pop ds + + + ret + + + + +;---------------------------------------------------------------------------- +; +; page phys address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX linear address +; EBX task no +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; page present: +; +; NZ +; EAX phys address (lower 12 bits unaffected) +; +; +; page not present: +; +; Z +; +;---------------------------------------------------------------------------- + + +page_phys_address: + + + IFNDEF task_proot + + test esp,esp + ret + + ELSE + + + push eax + mov eax,cr0 + bt eax,31 + pop eax + + IFNC + test esp,esp ; NZ ! + ret + FI + + + push ds + push ecx + push edx + + mov edx,linear_kernel_space + mov ds,edx + + load__proot edx,ebx + IFAE eax,shared_table_base + CANDBE eax,shared_table_base+shared_table_size-1 + lno___prc edx + mov edx,ds:[kernel_proot+8*edx-8] + FI + + xpdir ebx,eax + xptab ecx,eax + mov ebx,dword ptr [(ebx*4)+edx+PM] + mov dl,bl + and ebx,-pagesize + + test dl,page_present + IFNZ + test dl,superpage + IFZ + mov ecx,dword ptr [(ecx*4)+ebx+PM] + mov dl,cl + and ecx,-pagesize + ELSE_ + and ebx,-1 SHL 22 + shl ecx,12 + add ecx,ebx + FI + IFAE ecx, ; no access beyond PM + mov dl,0 ; ( 0 ... 64 M ) + FI ; + FI + test dl,page_present + IFNZ + and eax,pagesize-1 + add eax,ecx + test esp,esp ; NZ ! + FI + + pop edx + pop ecx + pop ds + ret + + + ENDIF + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +set_exception_handler: + + push eax + push ebx + + call address_idt + + mov ss:[ebx],ax + shr eax,16 + mov ss:[ebx+6],ax + + pop ebx + pop eax + ret + + + +get_exception_handler: + + push ebx + + call address_idt + + mov ax,ss:[ebx+6] + shl eax,16 + mov ax,ss:[ebx] + + pop ebx + ret + + + +address_idt: + + movzx ebx,bl + shl ebx,3 + sidt [idt_descriptor] + add ebx,dword ptr [idt_descriptor+2] + ret + + +idt_descriptor df 0 + + + + + + + + +;-------------------------------------------------------------------------- +; +; set / get exception handler +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX offset +; BL interrupt number +; +; SS linear_kernel_space +; +;--------------------------------------------------------------------------- + + +csr1 equ 08h +csr5 equ 28h +csr6 equ 30h + + + +wait100 macro + + mov eax,ecx + DO + dec eax + REPEATNZ + OD + endm + + + +special_test: + + kd____disp <'21140 base: '> + kd____inhex16 + mov ebx,eax + + kd____disp <' snoop interval: '> + kd____inhex8 + mov ecx,eax + + kd____disp <' : '> + + lea edx,[ebx+csr1] + sub eax,eax + out dx,eax + + lea edx,[ebx+csr5] + DO + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATNZ + OD + + rdtsc + mov edi,eax + lea edx,[ebx+csr5] + DO + wait100 + in eax,dx + and eax,00700000h + cmp eax,00300000h + REPEATZ + OD + rdtsc + sub eax,edi + sub edx,edx + mov edi,6 + div edi + kd____outdec + kd____disp <' PCI cycles'> + + ret + + + + +;-------------------------------------------------------------------------- +; +; trace events +; +;-------------------------------------------------------------------------- + + +trace_event: + + IFAE esp,virtual_space_size + + mov esi,ebx + mov cl,al + lno___thread eax,esp + shl eax,8 + + push ds + push linear_kernel_space + pop ds + + add esi,PM + + IFZ cl,'*' + mov al,80h + mov ebx,[esi+13] + mov ecx,[esi+17] + call put_words_4_to_5_into_trace_buffer + mov ebx,[esi+1] + mov bl,[esi] + dec bl + IFA bl,19 + mov bl,19 + FI + mov ecx,[esi+5] + mov edx,[esi+9] + ELSE_ + mov al,81h + mov ebx,[esi+9] + mov ebx,[esi+13] + call put_words_4_to_5_into_trace_buffer + mov ebx,[ebp+ip_eax] + mov ecx,[esi+1] + mov cl,[esi] + dec cl + IFA cl,15 + mov cl,15 + FI + mov edx,[esi+5] + FI + call put_into_trace_buffer + DO + + pop ds + FI + + jmp ret_from_kdebug + + + + +display_event: + + push eax + IFZ al,80h + kd____disp <'ke : *'> + lea eax,[esi+trace_entry_string] + kd____outstring + ELSE_ + kd____disp <'ke : #'> + lea eax,[esi+trace_entry_string+4] + kd____outstring + kd____disp <' ('> + mov eax,ebx + kd____outhex32 + kd____disp <')'> + FI + kd____disp <', thread='> + pop eax + shr eax,8 + kd____outhex16 + + ret + + + + +;-------------------------------------------------------------------------- +; +; init trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------------- + + +init_trace_buffer: + + pushad + + IFNZ [physical_kernel_info_page].kdebug_pages,0 + + call grab_frame + mov ebx,eax + mov ecx,KB4 + DO + call grab_frame + sub ebx,eax + IFNC + CANDZ ebx,KB4 + add ecx,ebx + mov ebx,eax + movzx edx,[physical_kernel_info_page].kdebug_pages + shl edx,log2_pagesize + cmp ecx,edx + REPEATB + ELSE_ + lea eax,[eax+ebx] + FI + OD + + mov [trace_buffer_begin],eax + mov [trace_buffer_in_pointer],eax + mov edi,eax + add eax,ecx + mov [trace_buffer_end],eax + + call flush_active_trace_buffer + + shr ecx,2 + sub eax,eax + cld + rep stosd + FI + + popad + ret + + + + +;-------------------------------------------------------------------------- +; +; put into trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX 0 src/ipc type +; EBX fault addr msg w1 +; ECX fault EIP dest +; EDX thread msg w0 +; +; DS linear kernel space +; +;--------------------------------------------------------------------------- + + + +put_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_type],eax + mov [edi+trace_entry_string],ebx + mov [edi+trace_entry_string+4],ecx + mov [edi+trace_entry_string+8],edx + + get___timestamp + mov [edi+trace_entry_timestamp],eax + mov [edi+trace_entry_timestamp+4],edx + + IFNZ [trace_perf_monitoring_mode+PM],no_perf_mon + mov ecx,event_select_msr + rdmsr + mov ebx,eax + and eax,NOT ((11b SHL 22)+(11b SHL 6)) + wrmsr + mov ecx,event_counter0_msr + rdmsr + mov [edi+trace_entry_perf_count0],eax + mov ecx,event_counter1_msr + rdmsr + mov [edi+trace_entry_perf_count1],eax + mov ecx,event_select_msr + mov eax,ebx + wrmsr + FI + + add edi,sizeof trace_buffer_entry-PM + IFAE edi,[trace_buffer_end+PM] + mov edi,[trace_buffer_begin+PM] + FI + mov [trace_buffer_in_pointer+PM],edi + FI + + ret + + + +put_words_4_to_5_into_trace_buffer: + + mov edi,[trace_buffer_in_pointer+PM] + test edi,edi + IFNZ + add edi,PM + + mov [edi+trace_entry_string+12],ebx + mov [edi+trace_entry_string+16],ecx + FI + ret + + + + +flush_active_trace_buffer: + + get___timestamp + mov [trace_buffer_active_stamp],eax + mov [trace_buffer_active_stamp+4],edx + + ret + + + + +open_trace_buffer: + + mov ebx,[trace_buffer_begin] + test ebx,ebx + IFNZ + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + CANDNZ + DO + mov esi,ebx + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE esi,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + REPEATC + OD + ret ; NC! + FI + + stc + ret + + + + + +forward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + add ebx,sizeof trace_buffer_entry + IFAE ebx,[trace_buffer_end] + mov ebx,[trace_buffer_begin] + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITNC + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 ; NC! + REPEATNZ + + pop ebx + ret + + OD + stc + + pop ebx + ret + + +backward_trace_buffer: + + push ebx + + mov ebx,esi + DO + mov eax,[ebx+trace_entry_timestamp] + mov edx,[ebx+trace_entry_timestamp+4] + sub ebx,sizeof trace_buffer_entry + IFB_ ebx,[trace_buffer_begin] + mov ebx,[trace_buffer_end] + sub ebx,sizeof trace_buffer_entry + FI + sub eax,[ebx+trace_entry_timestamp] + sbb edx,[ebx+trace_entry_timestamp+4] + EXITC + mov eax,[ebx+trace_entry_timestamp] + or eax,[ebx+trace_entry_timestamp+4] + EXITZ + + IFNZ [trace_display_mask],0 + mov eax,[ebx+trace_entry_type] + cmp eax,[trace_display_mask] + REPEATNZ + IFNZ [trace_display_mask+4],0 + mov eax,[ebx+trace_entry_string] + cmp eax,[trace_display_mask+4] + REPEATNZ + FI + FI + mov esi,ebx + sub cl,1 + REPEATNZ ; NC! + + pop ebx + ret + OD + stc + + pop ebx + ret + + + + +;-------------------------------------------------------------------------- +; +; show active trace buffer tail +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +show_active_trace_buffer_tail: + + + IFAE esp,virtual_space_size + call open_trace_buffer + CANDNC + sub eax,eax + mov [trace_display_mask],eax + mov cl,lines-3 + call backward_trace_buffer + + DO + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + sub eax,[trace_buffer_active_stamp] + sbb edx,[trace_buffer_active_stamp+4] + IFAE + kd____disp <13,10> + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + FI + mov cl,1 + call forward_trace_buffer + REPEATNC + OD + + FI + ret + + + +;-------------------------------------------------------------------------- +; +; dump trace buffer +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +dump_trace_buffer: + + mov al,0 + + CORB esp,virtual_space_size + call open_trace_buffer + IFC + ret + FI + + mov [trace_link_presentation],display_trace_index_mode + mov [trace_reference_mode],no_references + sub eax,eax + mov [trace_display_mask],eax + + mov cl,lines-2 + call backward_trace_buffer + + DO + + kd____clear_page + mov al,1 + kd____outchar + sub ecx,ecx + + sub ecx,ecx + mov ebp,esi + mov edi,esi + DO + push ecx + mov eax,[esi+trace_entry_type] + mov ebx,[esi+trace_entry_string] + mov ecx,[esi+trace_entry_string+4] + mov edx,[esi+trace_entry_string+8] + IFB_ al,40h + IFDEF task_proot + call display_page_fault + ENDIF + ELIFB al,80h + call display_ipc + ELSE_ + call display_event + FI + mov al,5 + kd____outchar + pop ecx + + IFNZ [trace_reference_mode],no_references + mov al,columns-40 + mov ah,cl + kd____cursor + kd____disp <5,' '> + + IFZ [trace_reference_mode],performance_counters + call display_trace_performance_counters + ELSE_ + push ebp + mov ebx,offset backward_trace_buffer + IFZ [trace_reference_mode],forward_references + mov ebx,offset forward_trace_buffer + FI + call display_trace_reference + pop ebp + FI + FI + + push ecx + mov al,columns-19 + mov ah,cl + kd____cursor + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov ch,' ' + call display_trace_index + ELIFZ al,display_trace_delta_time_mode + mov ch,' ' + call display_trace_timestamp + ELIFZ al,display_trace_offset_time_mode + mov ch,'t' + xchg ebp,edi + call display_trace_timestamp + xchg ebp,edi + FI + kd____disp <13,10> + mov ebp,esi + mov cl,1 + call forward_trace_buffer + pop ecx + EXITC + inc ecx + cmp ecx,lines-1 + REPEATB + OD + + call backward_trace_buffer + + call get_kdebug_cmd + + mov cl,0 + IFZ al,10 + mov cl,1 + FI + IFZ al,3 + mov cl,-1 + FI + CORZ al,'+' + IFZ al,11h + mov cl,lines-1 + FI + CORZ al,'-' + IFZ al,10h + mov cl,-(lines-1) + FI + + IFZ cl,0,long + + IFZ al,8 + mov ebx,offset trace_reference_mode + IFZ ,forward_references + mov byte ptr [ebx],no_references + ELIFZ ,performance_counters + mov byte ptr [ebx],forward_references + ELSE_ + mov byte ptr [ebx],backward_references + FI + + ELIFZ al,2,long + mov ebx,offset trace_reference_mode + IFZ ,backward_references + mov byte ptr [ebx],no_references + ELIFZ ,forward_references + CANDNZ [trace_perf_monitoring_mode],no_perf_mon + mov byte ptr [ebx],performance_counters + ELSE_ + mov byte ptr [ebx],forward_references + FI + + ELIFZ al,13 + mov ebx,offset trace_display_mask + sub eax,eax + IFZ [ebx],eax + mov [ebx+4],eax + mov eax,[esi] + mov [ebx],eax + ELSE_ + mov eax,[esi+4] + mov [ebx+4],eax + FI + + ELIFZ al,1 + mov ebx,offset trace_display_mask + sub eax,eax + IFNZ [ebx+4],eax + mov [ebx+4],eax + ELSE_ + mov [ebx],eax + FI + + + ELIFZ al,' ' + mov al,[trace_link_presentation] + IFZ al,display_trace_index_mode + mov al,display_trace_delta_time_mode + ELIFZ al,display_trace_delta_time_mode + mov al,display_trace_offset_time_mode + ELSE_ + mov al,display_trace_index_mode + FI + mov [trace_link_presentation],al + + ELIFZ al,'P' + bt ss:[cpu_feature_flags],pentium_style_msrs_bit + CANDC + call set_performance_tracing + + ELSE_ + call is_main_level_command_key + EXITZ + FI + FI + + IFG cl,0 + mov ch,cl + call forward_trace_buffer + push esi + mov cl,lines-2 + call forward_trace_buffer + pop esi + IFNZ cl,0 + IFB_ ch,cl + mov cl,ch + FI + call backward_trace_buffer + FI + ELIFL cl,0 + neg cl + call backward_trace_buffer + FI + + REPEAT + + OD + + + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace index +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_index: + + push eax + + mov al,ch + kd____outchar + mov eax,esi + sub eax,[trace_buffer_in_pointer] + IFC + add eax,[trace_buffer_end] + sub eax,[trace_buffer_begin] + FI + log2 <(sizeof trace_buffer_entry)> + shr eax,log2_ + kd____outhex12 + + pop eax + ret + + + + +;-------------------------------------------------------------------------- +; +; display trace timestamp +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; CH prefix char +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_timestamp: + + push eax + push ebx + push ecx + push edx + + + mov eax,[esi+trace_entry_timestamp] + mov edx,[esi+trace_entry_timestamp+4] + + IFNZ esi,ebp + mov cl,'+' + sub eax,ds:[ebp+trace_entry_timestamp] + sbb edx,ds:[ebp+trace_entry_timestamp+4] + IFC + mov cl,'-' + neg eax + adc edx,0 + neg edx + FI + FI + + push ecx + + mov ebx,eax + mov ecx,edx + + mov eax,2000000000 + sub edx,edx + div dword ptr ds:[physical_kernel_info_page+cpu_clock_freq] + shr eax,1 + adc eax,0 + + imul ecx,eax + mul ebx + add edx,ecx ; eax,edx : time in nanoseconds + + pop ecx + + IFZ esi,ebp + IFZ ch,'t' + kd____disp <' t=.'> + ELSE_ + kd____disp <' .'> + FI + mov cl,'.' + mov ch,'.' + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + + ELSE_ + CORA edx,0 + IFAE eax,1000000000 + mov ebx,1000000000/200 + call outdec2 + kd____disp <' s'> + + ELIFAE eax,1000000 + kd____disp <' '> + mov ebx,1000000/200 + call outdec2 + kd____disp <' ms'> + ELSE_ + kd____disp <' '> + mov ebx,1000/200 + call outdec2 + kd____disp <' us'> + FI + FI + + + pop edx + pop ecx + pop ebx + pop eax + ret + + + +outdec2: + + sub edx,edx + div ebx + shr eax,1 + adc eax,0 + + mov ebx,100 + sub edx,edx + div ebx + + IFB_ eax,10 + kd____disp <' '> + ELIFB eax,100 + kd____disp <' '> + FI + + push eax + mov al,ch + kd____outchar + mov al,cl + kd____outchar + pop eax + + kd____outdec + kd____disp <'.'> + mov eax,edx + IFB_ eax,10 + kd____disp <'0'> + FI + kd____outdec + + ret + + + + +;-------------------------------------------------------------------------- +; +; display reference +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + +display_trace_reference: + + push eax + push ecx + push ebp + + mov ebp,esi + + DO + mov cl,1 + call ebx + EXITC + + mov eax,[esi+trace_entry_type] + cmp eax,ds:[ebp+trace_entry_type] + REPEATNZ + mov eax,[esi+trace_entry_string] + cmp eax,ds:[ebp+trace_entry_string] + REPEATNZ + + mov ch,'@' + IFZ [trace_link_presentation],display_trace_index_mode + call display_trace_index + ELSE_ + call display_trace_timestamp + FI + OD + + mov esi,ebp + pop ebp + pop ecx + pop eax + ret + + + +;-------------------------------------------------------------------------- +; +; set performance tracing +; +;-------------------------------------------------------------------------- + + + +event_select_msr equ 11h +event_counter0_msr equ 12h +event_counter1_msr equ 13h + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 00011111b +w_stall equ 00011001b +r_stall equ 00011010b +x_stall equ 00011011b +agi_stall equ 00011111b + +bus_util equ 00011000b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + + +set_performance_tracing: + + kd____clear_page + call show_trace_perf_monitoring_mode + kd____disp <' Performance Monitoring',13,10,10,'- : off, + : kernel+user, k : kernel, u : user',13,10,10> + kd____disp <'i : Instructions (total/V-pipe)',13,10> + kd____disp <'c : Cache Misses (DCache/ICache)',13,10> + kd____disp <'t : TLB Misses (DTLB/ITLB)',13,10> + kd____disp <'m : Memory Stalls (read/write)',13,10> + kd____disp <'a : Interlocks (AGI/Bank Conflict)',13,10> + kd____disp <'b : Bus Utilization (Bus/Instructions)',13,10> + + DO + kd____inchar + kd____outchar + + + IFZ al,'-' + mov [trace_perf_monitoring_mode],no_perf_mon + sub eax,eax + mov ecx,event_select_msr + wrmsr + ret + FI + + CORZ al,'+' + CORZ al,'k' + IFZ al,'u' + IFZ al,'+' + mov al,kernel_user_perf_mon + ELIFZ al,'k' + mov al,kernel_perf_mon + ELIFZ al,'u' + mov al,user_perf_mon + FI + mov [trace_perf_monitoring_mode],al + call show_trace_perf_monitoring_mode + REPEAT + FI + OD + + sub ebx,ebx + IFZ al,'i' + mov ebx,instrs_ex + (instrs_ex_V SHL 16) + FI + IFZ al,'c' + mov ebx,rw_miss + (ex_miss SHL 16) + FI + IFZ al,'t' + mov ebx,rw_tlb + (ex_tlb SHL 16) + FI + IFZ al,'m' + mov ebx,r_stall + (w_stall SHL 16) + FI + IFZ al,'a' + mov ebx,agi_stall + (bank_conf SHL 16) + FI + IFZ al,'b' + mov ebx,bus_util + (instrs_ex SHL 16) + FI + + test ebx,ebx + IFNZ + sub eax,eax + mov ecx,event_select_msr + wrmsr + mov ecx,event_counter0_msr + wrmsr + mov ecx,event_counter1_msr + wrmsr + mov al,[trace_perf_monitoring_mode] + IFZ al,kernel_perf_mon + mov al,01b + ELIFZ al,user_perf_mon + mov al,10b + ELSE_ + mov al,11b + FI + shl eax,6 + or ebx,eax + shl eax,22-6 + or eax,ebx + mov ecx,event_select_msr + wrmsr + FI + + ret + + + + + + +show_trace_perf_monitoring_mode: + + mov al,1 + mov ah,1 + kd____cursor + + mov al,[trace_perf_monitoring_mode] + + IFZ al,no_perf_mon + kd____disp <' '> + ELIFZ al,kernel_user_perf_mon + kd____disp <'Kernel+User'> + ELIFZ al,kernel_perf_mon + kd____disp <' Kernel'> + ELSE_ + kd____disp <' User'> + FI + + ret + + + +;-------------------------------------------------------------------------- +; +; display trace performance counters +; +;-------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to current trace entry +; EBP pointer to reference trace entry +; +; DS phys mem +; +;-------------------------------------------------------------------------- + + + + +display_trace_performance_counters: + + push eax + + IFNZ esi,ebp + + kd____disp <'P: '> + + mov eax,[esi+trace_entry_perf_count0] + sub eax,ds:[ebp+trace_entry_perf_count0] + kd____outdec + + kd____disp <' / '> + + mov eax,[esi+trace_entry_perf_count1] + sub eax,ds:[ebp+trace_entry_perf_count1] + kd____outdec + + FI + + pop eax + ret + + + + + + + +;--------------------------------------------------------------------------- + +default_kdebug_end equ $ + + + + dcod ends + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/kernel.asm b/l4-x86/smp/lx/kern/kernel.asm new file mode 100644 index 0000000..70aadf4 --- /dev/null +++ b/l4-x86/smp/lx/kern/kernel.asm @@ -0,0 +1,83 @@ +.386p + NAME kernel + PAGE 60, 132 + TITLE MODULE kernel module + + + PUBLIC kernelver + PUBLIC kernelstring + PUBLIC kcod_start + PUBLIC cod_start + PUBLIC dcod_start + PUBLIC scod_start + PUBLIC max_kernel_end + PUBLIC labseg_start + PUBLIC first_lab + PUBLIC icod_start + +strt16 segment para public use16 'code' ; only to ensure that 16-bit offset are +strt16 ends ; calculated relative to 0 by masm + +strt segment para public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg_start: + + +kernelver EQU 21000 +kerneltxt EQU '24.08.99' + +dver macro ver +db '&ver&' +endm + +kernelstring: + db 'L4-X Nucleus (x86), Copyright (C) IBM 1997 & University of Karlsruhe 1999',13,10,'Version ' + dver %kernelver + db ', ',kerneltxt + db 0 + +first_lab: + +labseg ends + + +c16 segment para public use16 'code' +c16_start: +c16 ends + + +kcod segment para public use32 'code' +kcod_start: +kcod ends + + +code segment para public use32 'code' +cod_start: + code ends + +dcod segment para public use32 'code' +dcod_start: +dcod ends + +scod segment para public use32 'code' +scod_start: +scod ends + +icod segment para public use32 'code' +icod_start: +icod ends +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +max_kernel_end: +lastseg ends + end + + + + + + diff --git a/l4-x86/smp/lx/kern/ktest.asm b/l4-x86/smp/lx/kern/ktest.asm new file mode 100644 index 0000000..5c8fda9 --- /dev/null +++ b/l4-x86/smp/lx/kern/ktest.asm @@ -0,0 +1,1074 @@ +include l4pre.inc + + scode + + Copyright IBM+UKA, L4.KTEST, 02,09,97, 15 + +;********************************************************************* +;****** ****** +;****** Kernel Test ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 02.09.97 ****** +;****** ****** +;********************************************************************* + + + extrn startup_ap:near + + + public ktest0_start + public ktest1_start + public ktest0_stack + public ktest1_stack + public ktest0_stack2 + public ktest1_stack2 + public ktest_begin + public ktest_end + public rdtsc_clocks + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include msg.inc +include intrifc.inc +include cpucb.inc +include schedcb.inc +include lbmac.inc +include pagmac.inc +include syscalls.inc +include kpage.inc +include l4kd.inc +.list +include perfmon.inc + + + + +ok_for x86 + + + + + + assume ds:codseg + + +ktest_begin equ $ + + +ping_thread equ booter_thread +pong_thread equ (sigma1_task+3*sizeof tcb) +;pong_thread equ (sigma1_thread+sizeof tcb) +;pong_thread equ (booter_thread+sizeof tcb) + + + align 16 + + dd 31 dup (0) +ktest0_stack dd 0 + dd 31 dup (0) +ktest0_stack2 dd 0 + dd 31 dup (0) +ktest1_stack dd 0 + dd 31 dup (0) +ktest1_stack2 dd 0 + +rdtsc_clocks dd 0 + + + align 16 +ping_dest_vec dd 0,0 + clign 16-8 +ping_snd_msg dd 0,0,0,128 dup (0) + align 16 +ping_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + clign 16-8 +pong_snd_msg dd 0,0,0,128 dup (0) + align 16 +pong_rcv_msg dd 0,128 SHL md_mwords,0,128 dup (0) + + dd 1,2,3,4 +counter dd 0 + +cycles dd 0 +public cycles + + +large_space db 0 + + + + + + +;------------------------------------------------------ +; +; ping +; +;------------------------------------------------------ + + + align 4 + +order msg_vector <0,4 SHL 13,4 SHL 13> + dd 0,0,0,0 + + + assume ds:codseg + + +ktest0_start: + + mov ecx,1000 + DO + push ecx + sub esi,esi + int thread_switch + pop ecx + dec ecx + REPEATNZ + OD + + + + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + +; call get_rtc +; push eax +; mov ecx,1000000 +; DO +; sub edx,edx +; mov eax,12345678h +; div ecx +; dec ecx +; REPEATNZ +; OD +; pop ebx +; call get_rtc +; sub eax,ebx +; add eax,rtc_micros_per_pulse/2 +; sub edx,edx +; mov ebx,rtc_micros_per_pulse +; div ebx +; mul ebx +; mov ebx,42000 +; call microseconds +; +; ke 'ns per cycle' +; +; +; +; mov esi,MB1 ; map memory +; mov ecx,MB1/4+KB4 +; cld +; rep lodsd +; +; DO +; cli +; +; mov esi,MB1 ; flush L1 + L2 +; mov ecx,MB1/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov eax,[esi] +; mov ecx,1000 +; loop $ +; +; rdtsc +; mov ebx,eax +; +; mov esi,MB1 +; mov ecx,1024 +; DO +; mov eax,[esi] +; mov eax,[esi+28] +; add esi,32 +; dec ecx +; REPEATNZ +; OD +; +; rdtsc +; sub eax,ebx +; sub eax,12 +; add eax,511 +; shr eax,10 +; push eax +; +; +; +; rdtsc +; mov ebx,eax +; rdtsc +; sub eax,ebx +; mov edi,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; +; push eax +; push ecx +; +; mov esi,MB1+KB4 ; flush L1 +; mov ecx,KB16/4 +; cld +; rep lodsd +; mov ecx,1000 +; loop $ +; +; mov esi,MB1+MB1 +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+64] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ecx,eax +; +; rdtsc +; mov ebx,eax +; mov eax,[esi+256] +; mov eax,[esi+256+32-8] +; rdtsc +; sub eax,ebx +; sub eax,edi +; mov ebx,eax +; +; kd____disp <13,10,'L1 cache delay: '> +; mov eax,ecx +; kd____outdec +; mov al,'-' +; kd____outchar +; mov eax,ebx +; kd____outdec +; kd____disp <' cycles'> +; +; kd____disp <13,10,'L2 cache delay: '> +; pop eax +; kd____outdec +; mov al,'-' +; kd____outchar +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; kd____disp <13,10,'RAM cache-line read: '> +; pop eax +; kd____outdec +; kd____disp <' cycles',13,10> +; +; +; +; +; +; +; +; +; ke 'cache' +; +; REPEAT +; OD + + + + mov eax,0AA00010h + ((3*64/4*2+64/4) SHL 8) + mov ebx,0FFFFFFFFh + mov esi,sigma0_task + int thread_schedule + + + DO + + call enter_ktest + + + mov al,[large_space] + kd____outhex8 + + mov eax,0AA00010h + ((1*64/4*2+64/4) SHL 8) + test [large_space],01h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,pong_thread + int thread_schedule + + mov eax,0AA00010h + ((2*64/4*2+64/4) SHL 8) + test [large_space],02h + IFNZ + mov ah,0 + FI + mov ebx,0FFFFFFFFh + mov esi,ping_thread + int thread_schedule + + inc [large_space] + + + kd____disp <13,10,10,'PageFault: '> + call pf_1024 + + mov [ping_dest_vec],pong_thread + + mov [ping_snd_msg+msg_dope],0 + mov [pong_snd_msg+msg_dope],0 + + + sub eax,eax + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,1000h + ; cmp byte ptr ds:[ebx],0 + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 1' + ; + ; mov eax,2 + ; sub ecx,ecx + ; mov edx,4711h + ; mov ebx,MB16 + ; and ebx,-pagesize + ; sub ebp,ebp + ; mov esi,pong_thread + ; int ipc + ; ke 'translate 2' + ; + + + + + + kd____disp <13,10,10,'ipc_8 : '> + call ping_short_100000 + + + mov eax,offset pong_snd_msg + mov dword ptr ds:[ps0+1],eax + mov dword ptr ds:[ps1+1],eax + mov dword ptr ds:[ps2+1],eax + mov dword ptr ds:[ps3+1],eax + + + kd____disp <13,10,'ipc_12 : '> + mov [ping_snd_msg+msg_dope],3 SHL md_mwords + mov [pong_snd_msg+msg_dope],3 SHL md_mwords + call ping_100000 + + + kd____disp <13,10,'ipc_128 : '> + mov [ping_snd_msg+msg_dope],32 SHL md_mwords + mov [pong_snd_msg+msg_dope],32 SHL md_mwords + call ping_100000 + + kd____disp <13,10,'ipc_512 : '> + mov [ping_snd_msg+msg_dope],128 SHL md_mwords + mov [pong_snd_msg+msg_dope],128 SHL md_mwords + call ping_100000 + +; kd____disp <13,10,'ipc_1024 : '> +; mov [ping_snd_msg+msg_dope],256 SHL md_mwords +; mov [pong_snd_msg+msg_dope],256 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_2048 : '> +; mov [ping_snd_msg+msg_dope],512 SHL md_mwords +; mov [pong_snd_msg+msg_dope],512 SHL md_mwords +; call ping_100000 +; +; kd____disp <13,10,'ipc_4096 : '> +; mov [ping_snd_msg+msg_dope],1024 SHL md_mwords +; mov [pong_snd_msg+msg_dope],1024 SHL md_mwords +; call ping_100000 + + + + + call exit_ktest + + + ke 'done' + + IF kernel_x2 + lno___prc eax + test eax,eax + ; jz $ + sti + ENDIF + + +; ke 'pre_GB1' +; +; mov edx,GB1 +; sub eax,eax +; sub ecx,ecx +; mov ebp,32*4+map_msg +; mov esi,sigma0_task +; int ipc +; +; ke 'GB1' + + + + + +; mov esi,sigma1_task +; mov eax,edi +; sub ebx,ebx +; sub ebp,ebp +; ke 'xx' +; int task_new +; ke '-yy' + + REPEAT + OD + + + + + + +ping_short_100000: + + sub ecx,ecx + mov eax,ecx + mov ebp,ecx + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + mov [cycles],0 + + call get_rtc + push eax + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 + rdtsc + push eax + + clign 16 + DO + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc +; push eax +; push edx +; rdtsc +; mov [rdtsc_clocks],eax +; pop edx +; pop eax + +; push eax +; push edx +; rdtsc +; sub eax,[rdtsc_clocks] +; ke 'rdtsc' +; pop edx +; pop eax + test al,al + EXITNZ + sub ecx,ecx + sub eax,eax + ; mov edx,ecx + sub ebp,ebp + ; mov esi,[ping_dest_vec] + ; mov edi,[ping_dest_vec+4] + mov esi,pong_thread + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + + pop ebx + + push eax + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,2*100000 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + IFNZ [cycles],0 + + kd____disp <', spec: '> + mov eax,[cycles] + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + kd____outdec + + kd____disp <' cycles'> + FI + + ret + + + + + + +ping_100000: + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + + mov [counter],100000 + + call get_rtc + push eax + + + clign 16 + DO + + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + mov eax,offset ping_snd_msg + sub ecx,ecx + mov ebp,offset ping_rcv_msg + mov esi,[ping_dest_vec] + mov edi,[ping_dest_vec+4] + int ipc + test al,al + EXITNZ + sub [counter],4 + REPEATNZ + OD + test al,al + IFNZ + ke 'ping_err' + FI + + pop ebx + + call get_rtc + + sub eax,ebx + add eax,rtc_micros_per_pulse/2 + sub edx,edx + mov ebx,rtc_micros_per_pulse + div ebx + mul ebx + mov ebx,2*100000 + call microseconds + + ret + + + + +;------------------------------------------------------ +; +; pong +; +;------------------------------------------------------ + + +ktest1_start: + + mov eax,3 + mov ecx,offset ktest1_stack + mov edx,offset kktest1_start + sub ebx,ebx + mov ebp,ebx + mov esi,sigma0_task + int lthread_ex_regs + + DO + sub ebp,ebp + lea eax,[ebp-1] + sub esi,esi + sub edi,edi + sub ecx,ecx + int ipc + REPEAT + OD + + + kktest1_start: + + sub ecx,ecx + mov eax,ecx + lea edx,[ecx+1] + mov ebx,edx + mov ebp,1000h+(12 SHL 2)+map_msg + mov esi,sigma0_task + int ipc + + + mov eax,-1 + + ;------------------- for translate test only: + ; or byte ptr ds:[MB4],0 + ;---------------------------------------- + + clign 16 + DO + DO + mov ebp,offset pong_rcv_msg+open_receive + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps1: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps2: mov eax,0 + sub ecx,ecx + int ipc + test al,al + EXITNZ + mov ebp,offset pong_rcv_msg+open_receive +ps3: mov eax,0 + sub ecx,ecx + int ipc + test al,al +ps0: mov eax,0 + REPEATZ + OD + test al,ipc_error_mask + mov al,0 + REPEATZ + ke '-pong_err' + REPEAT + OD + + + + + + +timer_counter equ 40h +timer_control equ 43h + +counter0_mode0_16_cmd equ 00110000b +counter0_mode2_16_cmd equ 00110100b +counter0_mode3_16_cmd equ 00110110b +counter0_latch_cmd equ 00000000b + + + + +timer_start macro + +mov al,counter0_mode0_16_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +mov al,0FFh +out [timer_counter],al +jmp $+2 +jmp $+2 +out [timer_counter],al +endm + + + +timer_stop macro + +mov al,counter0_latch_cmd +out [timer_control],al +jmp $+2 +jmp $+2 +in al,[timer_counter] +mov ah,al +jmp $+2 +jmp $+2 +in al,[timer_counter] +xchg ah,al +neg ax +movzx eax,ax +lea eax,[eax+eax-1] +imul eax,(1000*1000/1193)/2 +endm + + + align 4 + + + + + +pf_1024: + + lno___prc eax + test al,al + IFZ + mov ebx,2*MB1 + ELSE_ + mov ebx,MB16 + FI + lea ecx,[ebx+128*pagesize] + + mov eax,[ebx] + add ebx,pagesize + + timer_start + +; P_count rw_tlb,cnt_event,ex_tlb,cnt_event +; P_count rw_miss,cnt_event,ex_miss,cnt_event +; P_count r_stall,cnt_event,w_stall,cnt_event +; P_count a_stall,cnt_event,x_stall,cnt_event +; P_count ncache_refs,cnt_event,r_stall,cnt_event +; P_count mem2pipe,cnt_event_PL0,bank_conf,cnt_event_PL0 +; P_count mem2pipe,cnt_event,bank_conf,cnt_event +; P_count instrs_ex,cnt_event_PL0,instrs_ex_V,cnt_event_PL0 +; P_count instrs_ex,cnt_event_PL3,instrs_ex_V,cnt_event_PL3 +; P_count instrs_ex,cnt_clocks_pl0,instrs_ex,cnt_clocks_pl3 +; P_count r_stall,cnt_event_PL3,w_stall,cnt_event_PL3 + rdtsc + push eax + + clign 16 + DO + mov eax,ebx + mov eax,[ebx] + add ebx,pagesize + cmp ebx,ecx + REPEATB + OD + + ; P_count off + rdtsc + pop ebx + sub eax,ebx + push eax + + timer_stop + + mov ebx,127*1000 + call microseconds + + pop eax + + kd____disp <' cycles: '> + sub edx,edx + mov ebx,127 + div ebx + kd____outdec + + ; kd____disp <', events: ca='> + ; P_read P_event_counter0 + ; div ebx + ; kd____outdec + ; + ; kd____disp <', cb='> + ; P_read P_event_counter1 + ; div ebx + ; kd____outdec + + + + lno___prc eax + test al,al + IFZ + mov eax,2*MB1 + ELSE_ + mov eax,MB16 + FI + add eax,21*4 + mov ecx,80000002h + int fpage_unmap + + ret + +; call get_rtc +; push eax +; +; +; mov ebx,MB2 +; clign 16 +; DO +; mov eax,[ebx] +; add ebx,pagesize +; cmp ebx,MB2+512*pagesize +; REPEATB +; OD +; +; pop ebx +; +; call get_rtc +; +; sub eax,ebx +; inc eax +; shr eax,1 +; imul eax,100000/512 +; call microseconds +; +; ret + + + align 16 + + + +microseconds: + + pushad + + sub edx,edx + div ebx + kd____outdec + mov al,'.' + kd____outchar + imul eax,edx,200 + add eax,ebx + shr eax,1 + sub edx,edx + div ebx + mov edx,eax + IFB_ edx,10 + mov al,'0' + kd____outchar + FI + mov eax,edx + kd____outdec + kd____disp <' us'> + + popad + ret + + + + + + +;---------------------------------------------------------------------------- +; +; get real time clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX ms (low) +; +;---------------------------------------------------------------------------- + + align 16 + + +get_rtc: + + mov eax,ds:[user_clock+1000h] + ret + + + + + + +;--------------------------------------------------------------------- +; +; enter/exit ktest mutex +; +;--------------------------------------------------------------------- +; PRECONDITION: +; +; DS phys mem +; +;--------------------------------------------------------------------- + + + +ktest_mutex db 0FFh +ktest_depth db 0 + + + +enter_ktest: + + push eax + push ecx + + lno___prc ecx + DO + mov al,0FFh + lock cmpxchg ds:[ktest_mutex],cl + EXITZ + cmp al,cl + REPEATNZ + OD + inc ds:[ktest_depth] + + pop ecx + pop eax + ret + + +exit_ktest: + + dec ds:[ktest_depth] + IFZ + mov ds:[ktest_mutex],0FFh + FI + + ret + + +;====================================================================================== + +rsend_task_no equ 7 +rsend_task equ (rsend_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +rmaster: + mov eax,0ffh ; mcp + mov ebx,sigma0_task ; pager + mov ecx,rstack1 ; initial sp + mov edx,rsend ; initial ip + mov esi,rsend_task ; task no + int task_new + jmp $ + +rsend: ke 'task running' + + db 32 dup (0) +rstack1 equ $ + + +ktest_end equ $ + + + scod ends + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/mailbox.asm b/l4-x86/smp/lx/kern/mailbox.asm new file mode 100644 index 0000000..3cdc810 --- /dev/null +++ b/l4-x86/smp/lx/kern/mailbox.asm @@ -0,0 +1,7 @@ + + + + + + + diff --git a/l4-x86/smp/lx/kern/mpconf.asm b/l4-x86/smp/lx/kern/mpconf.asm new file mode 100644 index 0000000..3a426e4 --- /dev/null +++ b/l4-x86/smp/lx/kern/mpconf.asm @@ -0,0 +1,164 @@ + + +include l4pre.inc + + + + Copyright IBM+UKA, L4.MPCONF, 07,01,00, 31 + +;********************************************************************* +;****** ****** +;****** Multi Processor Configuration ****** +;****** ****** +;****** Author: M.Voelp ****** +;****** ****** +;****** ****** +;****** modified: 7.1.00 ****** +;****** ****** +;********************************************************************* + + + public determine_mp_system_type + + + + extrn physical_kernel_info_page:dword + +.nolist + include l4const.inc + include uid.inc +.list + +include adrspace.inc + +.nolist + include kpage.inc + include apic.inc + include cpucb.inc +.list + +ok_for x86 + +;********************************************************************* +;****** ****** +;****** Multi Processor Configuration ****** +;****** ****** +;****** ****** +;********************************************************************* + + assume ds:codseg + icode + + +;--------------------------------------------------------------------- +; +; determin mp system type +; +;--------------------------------------------------------------------- + +determine_mp_system_type: + ; Find that MP Floating Pointer Structure + ; Looking for _PM_ = 5F504D5F + ; First look at 1. kb EBDA 09fc00h + ; Then in last kb of System Memory + ; Last in 0F0000h + + mov esi, 09fc00h + call find_float_struc + IFZ eax,5F504D5Fh + call mp_float_struc + ELSE_ + + ; Look at last kb of System Memory + mov eax, [edi+main_mem].mem_end ; System Memory + sub eax, 400h + mov esi, eax + call find_float_struc + IFZ eax,5F504D5Fh + call mp_float_struc + ELSE_ + ; Look at kb starting at 0f0000h + mov esi, 0F0000h + call find_float_struc + IFZ eax,5F504D5Fh + call mp_float_struc + ELSE_ + ; Nothing of that stuff was found + mov [physical_kernel_info_page].mpfloatstruc, 00h + mov [physical_kernel_info_page].mpconftbl, 00h + mov [physical_kernel_info_page].proc_data, 00h + FI + FI + FI + ret + +;------------------------------------------------------------------------- +; +; search for _PM_ in the first kb pointed to by esi +; +;------------------------------------------------------------------------- + +find_float_struc: + mov ecx, 00h + DO + mov eax, [esi] + cmp eax, 5F504D5Fh ; look for _PM_ + EXITZ + inc esi + inc ecx + cmp ecx,10000h ; repeat until (1kb == ecx) + REPEATB + OD + ret + +;---------------------------------------------------------------------------- +; +; MP_float_structure found: +; look for the MP_configuration table, processor data +; +;---------------------------------------------------------------------------- + +mp_float_struc: ; MP floating point structure found at esi + mov [physical_kernel_info_page].mpfloatstruc, esi + add esi, 04h + mov ebx, [esi] + mov [physical_kernel_info_page].mpconftbl, ebx + IFZ ebx,0 ; No MP Configuration Table exists + mov al,[esi+07h] + IFNZ al,0 + ;; dammed intel standard configuration is used + ;; MP Standard type in al + CANDB al, 08h + call determine_standard_configuration + ELSE_ + FI + ELSE_ + mov eax,ebx ; MPconftbl in ebx + add eax, 02Ch + mov [physical_kernel_info_page].proc_data, eax ; Start adress of proc info in eax + FI + ret + +;---------------------------------------------------------------------------- +; ******** NOT YET IMPLEMENTED ********* +; determine standard configuration +; No MP_configuration table present. Build needed entries of configuration +; table out of the standard type: +; Dual machine, local APIC ID == 0, 1 +;---------------------------------------------------------------------------- + +;; PRECONDITION id of standard configuration in al +determine_standard_configuration: + ; + ;; build MP table out of scratch + ;; Construct a new MP Configuration Table and link it to the needed position + ret + + icod ends + code ends +end + + + + + diff --git a/l4-x86/smp/lx/kern/pagmap.asm b/l4-x86/smp/lx/kern/pagmap.asm new file mode 100644 index 0000000..15ef11d --- /dev/null +++ b/l4-x86/smp/lx/kern/pagmap.asm @@ -0,0 +1,1936 @@ +include l4pre.inc + + + Copyright IBM+UKA, L4.PAGMAP, 27,08,99, 43 + + +;********************************************************************* +;****** ****** +;****** Page Mapper ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 27.08.99 ****** +;****** ****** +;********************************************************************* + + + public alloc_initial_pagmap_pages + public init_pagmap + public map_ur_page_initially + public pagmap_fault + public grant_fpage + public map_fpage + public flush_address_space + public translate_address + + + extrn request_fresh_frame:near + extrn map_fresh_ptab:near + extrn alloc_kernel_pages:near + extrn alloc_shared_kernel_pages:near + extrn map_page_initially:near + extrn map_system_shared_page:near + extrn define_idt_gate:near + extrn phys_frames:dword + extrn physical_kernel_info_page:dword + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +include schedcb.inc +include syscalls.inc +.list +include pagconst.inc +include pagmac.inc +include pagcb.inc +include kpage.inc +.nolist +include msg.inc +.list + + + + + +ok_for x86 + + + + +include pnodes.inc + + + + assume ds:codseg + + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** PAGMAP INITITIALIZATION ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + icode + + +;---------------------------------------------------------------------------- +; +; alloc pagmap pages +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging still disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; pages for chapter_map and pnode_space allocated +; +; regs scratch +; +;---------------------------------------------------------------------------- + + + +alloc_initial_pagmap_pages: + + mov esi,offset shadow_pdir ;local + mov eax,sizeof shadow_pdir + mov cl, page_present+page_write_permit + call alloc_kernel_pages + + mov esi,offset chapter_map ; not mapped but why + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add esi,eax + sub ecx,eax + + mov eax,ecx + + lno___prc ecx + IFZ ecx,1 + mov cl, page_present+page_write_permit + call alloc_kernel_pages + ELSE_ + mov cl, page_present+page_write_permit + call alloc_shared_kernel_pages + FI + + mov esi,offset pnode_space + mov eax,[phys_frames] + add eax,max_M4_frames + shl eax,log2_size_pnode + + lno___prc ecx + IFZ ecx,1 + mov cl, page_present+page_write_permit + call alloc_kernel_pages + ELSE_ + mov cl, page_present+page_write_permit + call alloc_shared_kernel_pages + FI + + ret + + + + +;---------------------------------------------------------------------------- +; +; init pagmap +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +init_pagmap: + + ; clear shadow page dir space + mov edi,offset shadow_pdir + mov ecx,sizeof shadow_pdir/4 + sub eax,eax + cld + rep stosd + + ; clear chapter map area + mov edi,offset chapter_map + mov eax,[phys_frames] + imul eax,chapters_per_page + mov ecx,eax + sub eax,pagesize + IFC + sub eax,eax + FI + and eax,-pagesize + add edi,eax + sub ecx,eax + sub eax,eax + cld + rep stosb + + ; map pnode pages + mov eax,[phys_frames+PM] + shl eax,log2_size_pnode + lea esi,[eax+pnode_base] + + mov ds:[free_pnode_root],esi + movzx ecx,ds:[physical_kernel_info_page].pnodes_per_frame + sub ecx,1 + IFC + mov ecx,pnodes_per_frame_default-1 + FI + imul eax,ecx + + mov ecx,eax + mov edi,esi + + add esi,pagesize-1 + and esi,-pagesize + sub eax,esi + add eax,edi + + lno___prc ebx + IFZ ebx,1 + call alloc_kernel_pages + ELSE_ + call alloc_shared_kernel_pages + FI + + ; build free page node data structure + DO + add edi,sizeof pnode + sub ecx,sizeof pnode + EXITBE + + mov [edi-sizeof pnode].next_free,edi + REPEAT + OD + mov [edi-sizeof pnode].next_free,0 + + ; define IDT gate for unmap system call + lno___prc eax + IFZ eax,1 + mov bh,3 SHL 5 + + mov bl,fpage_unmap + mov eax,offset unmap_fpage_sc + call define_idt_gate + FI + + ret + + + + + icod ends + + +;---------------------------------------------------------------------------- +; +; pagmap fault +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; paging enabled +; +;---------------------------------------------------------------------------- + + + +pagmap_fault: + + mov esi,eax + call request_fresh_frame + IFNC + call map_system_shared_page + ELSE_ + ke 'pmf' + FI + + ipost + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** flexpage handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +do_source_dest_data struc + + source_pdir dd 0 + map_mask dd 0 + operation dd 0 + source_addr dd 0 + + dest_task dd 0 + dest_addr dd 0 + +do_source_dest_data ends + + +do_source_data struc + + dd 0 ; source_pdir + dd 0 ; map_mask + dd 0 ; operation + dd 0 ; source_addr + + tlb_flush_indicator dd 0 ; 0: no tlb flush required, 2: required + +do_source_data ends + + + + + + ; align 16 + + + +;---------------------------------------------------------------------------- +; +; grant fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +grant_fpage: + + mov ch,0FFh ; map mask: all + + push edi + push edx + push eax + + ; flush TLB + mov ebp,cr3 ; granting requires TLB flush on Pentium, + mov cr3,ebp ; because following addr space switch might + ; be executed *without* TLB flush + + ; do grant operation + push offset grant_page_ + jmp short do_fpage + + + + + +;---------------------------------------------------------------------------- +; +; unmap fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX fpage +; ECX map mask +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + +unmap_fpage_sc: + + tpre trap2,ds,es + + ; compute base_address: eax, fpage_size: cl + mov ch,cl ; map mask: f:31 0:30-2 w:1 0:0 f=flush w=0 w -> ro, 1 total + mov cl,al ; fpage: base/4096:20 0:4 size:6 ~:2 + shr cl,2 ; cl = log2(size) + shr eax,cl ; align base by 2^size + shl eax,cl + sub cl,log2_pagesize ; decrease cl by 1 pagesize + + ; if size to be unmapped is at least 4K + IFNC + ; save return pointer of unmap call + push offset unmap_fpage_ret ; dest address + + ; reserve stackspace for do_source_dest_data structure + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + ; store 0 and fpage base address on stack + sub edx,edx + push edx + push eax + + ; if not flush operation + test ecx,ecx + IFNS + ; if total unmap + test ch,page_write_permit + IFNZ + ; unmap page + push offset unmap_page + jmp short do_fpage + FI + ; revoke writer rights + push offset unmap_write_page + jmp short do_fpage + FI + ; else if flush operation + ; if total unmap + test ch,page_write_permit + IFNZ + ; flush page + push offset flush_page + jmp short do_fpage + FI + ; revoke writer rights including own page + push offset flush_write_page + jmp short do_fpage + + + unmap_fpage_ret: + + ; flush tlb entries on local processor + IFNC + mov eax,cr3 + mov cr3,eax + FI + FI + + tpost eax,ds,es + + +;---------------------------------------------------------------------------- +; +; map fpage +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX dest tcb addr (determines dest address space only) +; EDI dest fpage addr +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +;---------------------------------------------------------------------------- + + + +map_fpage: + + push edi + push edx + push eax + + ; map page + push offset map_page + + + + +;---------------------------------------------------------------------------- +; +; do fpage operation +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX source fpage addr +; CL log2 (fpage size / pagesize) +; CH map mask +; EDX 0 / dest tcb addr (determines dest address space only) +; EDI - / dest fpage addr +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EDI,EBP scratch +; +; map/grant: +; +; NC: all mapping/granting was successful +; C: aborted due to requested ptab unavailable +; +; +; flush/unmap: +; +; NC: at least one page unmapped, TLB flush required +; C: no page of current AS unmapped, no TLB flush needed +; +;---------------------------------------------------------------------------- + +do_fpage: + + ; load current page directory + mov ebp,cr3 + IFAE , + ; if in small space load page root of small task + lno___task ebp,esp + load__proot ebp,ebp + FI + ; page root in ebp + + +;####################################################################################### + +do_fpage_in_address_space: + + mov ebx,1 + shl ebx,cl + + mov cl,ch + or ecx,NOT page_write_permit + + and ebp,-pagesize + + push ecx + + mov ecx,PM + add ebp,ecx + + inc ds:[do_fpage_counter] + + push ebp + + + DO + + cmp eax,virtual_space_size + jae do_fpage_ret + + mov ebp,esp + + push eax + push edi + + mov esi,eax + and eax,0FFC00000h + mov edx,[ebp+source_pdir] + shr eax,22-2 + and esi,003FF000h + mov ecx,eax + add edx,eax + shr esi,log2_pagesize-2 + add esi,PM + + mov eax,[edx] + + + test al,superpage + IFNZ + test al,page_present ; not present 4M pages can only exist in sigma0 device + xc z,gen_emulated_4M_page,long ; mem on machines that do not support 4M pages + + cmp ebx,MB4/pagesize + IF____xc ae,do_M4_operation,long + ELSE__ + test ah,shadow_ptab SHR 8 + mov eax,[ecx+shadow_pdir] + xc z,lock_shadow_ptab,long + FI____ + FI + + test al,superpage+page_present + IFPO ,,long ; note: NOT present => NOT M4 rpage + and eax,-pagesize + add esi,eax + + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task ecx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot ecx,ecx + mov eax,edi + shr eax,22 + and edi,003FF000h + lea ecx,[eax*4+ecx+PM] + + shr edi,log2_pagesize-2 + add edi,PM + + mov eax,[ecx] + test al,superpage+page_present + xc pe,do_fpage_map_fresh_ptab,long + and eax,-pagesize + add edi,eax + FI + + IFB_ ebx,ptes_per_chapter + + sub esi,4 + sub edi,4 + DO + add esi,4 + add edi,4 + + sub ebx,1 + EXITB + + mov eax,[esi] + test eax,eax + REPEATZ + + push ebx + call [ebp+operation] + pop ebx + + test ebx,ebx + REPEATNZ + OD + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + FI + + mov ch,0 + + sub edi,esi + shr esi,log2_chaptersize + DO + mov cl,[esi+chapter_map-(PM SHR log2_chaptersize)] + test cl,cl + IFZ + inc esi + sub ebx,ptes_per_chapter + test ebx,pagesize/4-1 + REPEATNZ + + EXIT + FI + + push ebx + shl esi,log2_chaptersize + DO + mov eax,[esi] + add esi,4 + test eax,eax + REPEATZ + + sub esi,4 + add edi,esi + + call [ebp+operation] + + sub edi,esi + add esi,4 + dec cl + REPEATNZ + OD + pop ebx + + sub esi,4 + shr esi,log2_chaptersize + inc esi + sub ebx,ptes_per_chapter + + dec ch + xc z,permit_intr_in_do_fpage + + test ebx,pagesize/4-1 + REPEATNZ + OD + + add ebx,MB4/pagesize + FI + + pop edi + pop eax + + add edi,MB4 + add eax,MB4 + sub ebx,MB4/pagesize + REPEATA + + OD + + + +do_fpage_ret: + + cmp [ebp+tlb_flush_indicator],1 + lea esp,[ebp+sizeof do_source_dest_data] + ret + + + + + + + + +XHEAD do_fpage_map_fresh_ptab + + jnz short do_fpage_pop_ret + + call map_fresh_ptab + xret nc,long + + + +do_fpage_pop_ret: + + pop edi + pop eax + jmp do_fpage_ret + + + + + + + + + +XHEAD permit_intr_in_do_fpage + + mov eax,ds:[do_fpage_counter] + sti + nop + nop + cli + cmp eax,ds:[do_fpage_counter] + xret z + + pop edi + pop eax + + + and esi,(pagesize-1) SHR log2_chaptersize + shl esi,log2_chaptersize + log2_pagesize + + mov eax,[ebp+source_addr] + add eax,esi + mov [ebp+source_addr],eax + + mov edx,[ebp+dest_task] + + mov edi,[ebp+dest_addr] + add edi,esi + mov [ebp+dest_addr],edi + + mov ebp,[ebp+source_pdir] + + jmp do_fpage + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +XHEAD do_M4_operation + + + mov esi,edx + mov edx,[ebp+dest_task] + IFA edx,2 + + lno___task edx,edx + + cmp edi,virtual_space_size + jae do_fpage_pop_ret + + load__proot edx,edx + shr edi,22 + lea edi,[edi*4+edx+PM] + FI + + push ebx + + test ah,shadow_ptab SHR 8 + IFNZ + pushad + + and byte ptr [esi+1],NOT (shadow_ptab SHR 8) + mov esi,[ecx+shadow_pdir] + and esi,-pagesize + mov ecx,esi + shr ecx,log2_pagesize + sub eax,eax + mov ds:[ecx*4+ptab_backlink],eax + DO + mov eax,dword ptr [esi+PM] + test eax,eax + IFNZ + call unmap_page + FI + add esi,4 + test esi,pagesize-1 + REPEATNZ + OD + popad + FI + + call [ebp+operation] + + sub eax,eax + + pop ebx + xret ,long + + + + + + + +XHEAD lock_shadow_ptab + + + push ebx + + mov ebx,eax + shr ebx,log2_pagesize + IFNZ + CANDZ [ebx*4+ptab_backlink],0 + + IFZ [ebp+operation], + push ecx + shl ecx,log2_size_pnode-2 + cmp [ecx+M4_pnode_base].pte_ptr,edx + pop ecx + CANDZ ; transfer to K4 pages if + sub eax,eax ; ur pages granted + xchg eax,[ecx+shadow_pdir] ; (typically sigma 0 to kernel) + mov [edx],eax + + ELSE_ + or byte ptr [edx+1],shadow_ptab SHR 8 + mov [ebx*4+ptab_backlink],edx + FI + + ELSE_ + sub eax,eax ; inhibit any 4K operation if no + FI ; shadow ptab (i.e. device mem) + + pop ebx + xret ,long + + + + + +XHEAD gen_emulated_4M_page + + push ebx + push ecx + + lea ebx,[eax+page_present] + + DO + mov ecx,edx + mov edx,esp ; denoting current task + call map_fresh_ptab + mov edx,ecx + IFC + sub eax,eax ; drop mem if no more ptabs available + EXIT ; + FI + test eax,(MB4-1) AND -pagesize ; take another ptab if this one at 0 modulo 4M + REPEATZ ; this enables to differentiate between real 4Ms + ; and emulated 4Ms (bits 12..21 non zero) + push eax + push ebx + and bl,NOT superpage + DO + mov dword ptr ds:[eax+PM],ebx + add ebx,pagesize + add eax,4 + test ebx,(MB4-1) AND -pagesize + REPEATNZ + OD + pop ebx + pop eax + + and ebx,pagesize-1 + or eax,ebx + OD + + mov dword ptr ds:[edx],eax + + pop ecx + pop ebx + xret ,long + + + + + +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +; kcode + + + +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode handling ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + + + +;---------------------------------------------------------------------------- +; +; alloc pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg new pnode +; EBX scratch +; +;---------------------------------------------------------------------------- + + +alloc_pnode macro reg + + mov reg,ds:[free_pnode_root] + test reg,reg + jz short free_pnode_unavailable + mov ebx,[reg].next_free + mov ds:[free_pnode_root],ebx + + endm + + + + +;---------------------------------------------------------------------------- +; +; release pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg allocated pnode to be released +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EDI scratch +; +;---------------------------------------------------------------------------- + + +release_pnode macro reg + + mov edi,reg + xchg edi,ds:[free_pnode_root] + mov [reg].next_free,edi + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; find pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX page table entry +; ESI pointer to PTE (denoting a present page !) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +find_pnode macro + + DO + test al,superpage + IFZ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + mov ebx,eax + + mov eax,[eax+cache0] + cmp [eax].pte_ptr,esi + EXITZ + + mov eax,[ebx+cache1] + cmp [eax].pte_ptr,esi + EXITZ + FI + call search_pnode + OD + + endm + + + + align 16 + + +search_pnode: + + test al,page_present ; = 1 ; means: EAX has superpage entry + IFNZ + test eax,(MB4-1) AND -pagesize + IFNZ + and eax,-pagesize ; for emulated 4Ms, phys + mov eax,dword ptr ds:[eax+PM] ; addr must be taken from ptab + FI + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + mov ebx,eax + FI + + mov eax,ebx + DO + cmp [eax].pte_ptr,esi + EXITZ + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + ret + + + + + + + +;---------------------------------------------------------------------------- +; +; refind cached0 pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to PTE (denoting a present page !) +; +; cache0 of corresponding pnode tree holds ESI-related pnode +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX pointer to pnode associated to ESI-PTE +; EBX pointer to root pnode +; +;---------------------------------------------------------------------------- + + +refind_cached0_pnode macro + + mov eax,[esi] + mov ebx,eax + + and bl,superpage + IFNZ + shr eax,22-log2_size_pnode + and eax,-sizeof pnode + add eax,offset M4_pnode_base + ELSE_ + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + FI + + mov ebx,eax + mov eax,[eax+cache0] + + endm + + + + +;---------------------------------------------------------------------------- +; +; cache pnode +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBX pointer to root pnode +; reg0 entry to be cached in cache0 / nil +; reg1 entry to be cached in cache1 / nil +; +;---------------------------------------------------------------------------- + +cache_pnode macro reg0,reg1 + + mov [ebx].cache0,reg0 + mov [ebx].cache1,reg1 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; grant page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to first source PTE (present!) +; EDI pointer to first dest PTE +; EBP pointer to do... variables +; +; dest PTE empty +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX scratch +; +; dest frame addr = old source frame addr +; dest access rights = old source access rights AND [ebp+map_mask] +; +; source PTE empty +; +;---------------------------------------------------------------------------- + + +XHEAD flush_grant_dest_page + + push eax + push ecx + push esi + push edi + + mov esi,edi + call flush_page + + pop edi + pop esi + pop ecx + pop eax + + xret + + + + + + + align 16 + + +grant_page_: + + + IFB_ esi, + + mov ebx,[edi] + test ebx,ebx + xc nz,flush_grant_dest_page + + + find_pnode + + mov [eax].pte_ptr,edi + mov eax,[esi] + mov dword ptr [esi],0 + mov [edi],eax + + mov eax,esi + mov ebx,edi + shr eax,log2_chaptersize + shr ebx,log2_chaptersize + dec [eax+chapter_map-(PM SHR log2_chaptersize)] + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + FI + ret + + + + + + +void_or_access_attribute_widening: + + and eax,[ebp+map_mask] + test al,page_write_permit + IFNZ + xor ebx,eax + and ebx,NOT (page_accessed+page_dirty) + CANDZ ebx,page_write_permit + + mov [edi],eax + + FI + + ret + + + + + +;---------------------------------------------------------------------------- +; +; map page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to source PTE (present!) +; EDI pointer to dest PTE +; EBP pointer to do... variables +; +; +; dest PTE empty OR dest frame addr = source frame addr, +; dest read only, source read/write, CL=FF +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX scratch +; +; dest frame addr = source frame addr +; dest access rights = source access rights AND CL +; +;---------------------------------------------------------------------------- + + + align 16 + + +map_page: + + mov ebx,[edi] + test ebx,ebx + jnz void_or_access_attribute_widening + + + alloc_pnode edx + + find_pnode + + cache_pnode eax,edx + + mov [edx].pte_ptr,edi + mov ebx,[esi] + and ebx,[ebp+map_mask] + mov [edi],ebx + + mov ebx,edi + shr ebx,log2_chaptersize + inc [ebx+chapter_map-(PM SHR log2_chaptersize)] + + lea ebx,[edx+1] + mov [edx].child_pnode,ebx + + mov ebx,[eax].child_pnode + mov [eax].child_pnode,edx + + mov [edx].succ_pnode,ebx + test bl,1 + IFZ + mov [ebx].pred_pnode,edx + FI + inc eax + mov [edx].pred_pnode,eax + + ret + + + + + + + +free_pnode_unavailable: + + ke '-free_pnode_unav' + + + + +;---------------------------------------------------------------------------- +; +; unmap page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL i +; CH j +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; CL i - number of unmapped pages in same chapter beyond esi +; CH max (1, j - number of unmapped pages) +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +unmap_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFNZ + cache_pnode edx,edx + ret + FI + + push edi + push ebp + + mov edi,[eax].pred_pnode + and edi,NOT 1 + cache_pnode edx,edi + + inc edx + mov edi,ds:[free_pnode_root] + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + mov [eax].next_free,edi + + mov edi,ebx + mov bl,[ebx] + + mov dword ptr [edi],0 + + shr edi,log2_chaptersize + + dec [edi+chapter_map-(PM SHR (log2_chaptersize))] + + shr edi,log2_pagesize-log2_chaptersize + + shr bl,superpage_bit ; always flush TLB if 4M page unmapped, + IFZ ; avoid backlink access in this case + + mov ebx,[(edi*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,0;;;;;;;;;;;;;;;;;;;;;;;;-pagesize + FI + xc z,unmap_in_own_address_space + + sub ch,2 + adc ch,1 + + mov edi,eax + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + mov ds:[free_pnode_root],edi + mov [eax-1].child_pnode,eax + + pop ebp + pop edi + + ret + + + + + + + +XHEAD unmap_in_own_address_space + + ; xchg ebp,[esp] + ; mov byte ptr [ebp+tlb_flush_indicator],2 + ; xchg ebp,[esp] + + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + + + mov ebx,[eax].pte_ptr + cmp ebx,esi + xret be + + lea edi,[esi+chaptersize-1] + and edi,-chaptersize + cmp ebx,edi + xret b + + dec cl + xret + + + + + +unmap_write_page: + + find_pnode + + mov edx,eax + mov eax,[eax].child_pnode + test al,1 + IFZ + cache_pnode edx,eax + + push ebp + + inc edx + mov ebp,ds:[cpu_cr3] + add ebp,PM + DO + mov ebx,[eax].pte_ptr + + and byte ptr [ebx],NOT page_write_permit + mov bl,[ebx] + ; flush TLB if 4 M page + shr bl,superpage_bit ; avoid backlink acc in this case + IFZ + shr ebx,log2_pagesize + mov ebx,[(ebx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + FI + shl bl,8 ; Z ! bit 0 -> cf + IFNC + xor ebx,ebp + test ebx,-pagesize + FI + xc z,unmap_write_in_own_address_space + + mov eax,[eax].child_pnode + test al,1 + REPEATZ + + DO + cmp eax,edx + OUTER_LOOP EXITZ + mov eax,[eax-1].succ_pnode + test al,1 + REPEATNZ + OD + REPEAT + OD + pop ebp + + FI + + ret + + + + + + + +XHEAD unmap_write_in_own_address_space + + push ecx + + mov ebx,[eax].pte_ptr + mov ecx,ebx + and ebx,(pagesize-1) AND -3 + shr ecx,log2_pagesize + shl ebx,log2_pagesize-2 + mov ecx,[(ecx*4)+ptab_backlink-((PM SHR log2_pagesize)*4)] + and ecx,(pagesize-1) AND -3 + shl ecx,2*log2_pagesize-4 + add ebx,ecx + invlpg [ebx] + + pop ecx + xret + + + + +; xchg ebp,[esp] +; mov byte ptr [ebp+tlb_flush_indicator],2 +; xchg ebp,[esp] +; xret + + + + + + +;---------------------------------------------------------------------------- +; +; flush page +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ESI pointer to dest PTE +; EBP pointer to do... variables +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,EDX,EDI scratch +; +;---------------------------------------------------------------------------- + + + align 16 + + +flush_page: + + IFB_ esi, + + call unmap_page + + refind_cached0_pnode + + mov edi,esi + shr edi,log2_chaptersize + sub edx,edx + mov dword ptr [esi],edx + dec [edi+chapter_map-(PM SHR log2_chaptersize)] + + release_pnode eax + + mov edx,[eax].succ_pnode + mov eax,[eax].pred_pnode + + test al,1 + IFZ + mov [eax].succ_pnode,edx + ELSE_ + mov [eax-1].child_pnode,edx + FI + test dl,1 + IFZ + mov [edx].pred_pnode,eax + FI + + and dl,NOT 1 + and al,NOT 1 + cache_pnode edx,eax + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + + + +flush_write_page: + + IFB_ esi, + + call unmap_write_page + + mov eax,[ebp].cache0 + + and byte ptr [esi],NOT page_write_permit + + mov byte ptr [ebp+tlb_flush_indicator],2 + + FI + ret + + + + +;---------------------------------------------------------------------------- +; +; translate address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX virtual address in source space +; EBP dest tcb +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX virtual address in dest space / FFFFFFFF +; +; EBX,ECX,EDX scratch +; +;---------------------------------------------------------------------------- + + + + + + +translate_address: + + lno___task edx,ebp + load__proot edx,edx + add edx,PM + + mov ecx,cr3 + IFAE , + lno___task ecx,esp + load__proot ecx,ecx + FI + and ecx,-pagesize + xpdir ebx,eax + mov ebx,dword ptr ds:[ebx*4+ecx+PM] + test bl,page_present + jz translate_to_nil + and ebx,-pagesize + xptab eax,eax + mov eax,dword ptr ds:[eax*4+ebx+PM] + test al,page_present + jz translate_to_nil + + + shr eax,log2_pagesize-log2_size_pnode + and eax,-sizeof pnode + add eax,offset pnode_base + lea ebx,[eax+1] + + DO + mov ecx,[eax].pte_ptr + shr ecx,log2_pagesize + mov ecx,ds:[ecx*4+ptab_backlink-(PM SHR log2_pagesize)*4] + sub ecx,edx + cmp ecx,pagesize + EXITB + mov eax,[eax].child_pnode + test eax,1 + REPEATZ + + DO + cmp eax,ebx + jz translate_to_nil + mov eax,[eax-1].succ_pnode + test eax,1 + REPEATNZ + OD + REPEAT + OD + + and ecx,-4 + shl ecx,log2_pagesize+10-2 + mov eax,[eax].pte_ptr + and eax,pagesize-1 + shl eax,log2_pagesize-2 + add eax,ecx + + ret + + +translate_to_nil: + + sub eax,eax + dec eax + ret + + + + + + + +; kcod ends +;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + + + + + +;---------------------------------------------------------------------------- +; +; flush address space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EDI phys pdir address (proot) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX,EBX,ECX,EDX,ESI,EBP scratch +; +;---------------------------------------------------------------------------- + + +flush_address_space: + + push edi + push offset flush_address_space_ret + + sub esp,sizeof do_source_dest_data-sizeof do_source_data + + sub edx,edx + push edx + sub eax,eax + push eax + + mov cl,32-log2_pagesize + + mov ebp,edi + + push offset flush_page + jmp do_fpage_in_address_space + + +flush_address_space_ret: + + pop edi + ret + + + + + +;---------------------------------------------------------------------------- +; +; map ur page initially +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX physical address (4K aligned) +; DL page attributes +; ESI linear address (only bits 31...12 relevant) +; +; +; DS,ES phys mem / linear space & kernel task +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; mapped (user, read/write, ur) +; corresponding pnode_root initialized +; +;---------------------------------------------------------------------------- + + + icode + + + +map_ur_page_initially: + + pushad + + mov ebx,eax + + load__proot ecx,<((sigma0_task AND mask task_no) SHR task_no)> + + xpdir eax,esi + lea ecx,[(eax*4)+ecx+PM] + + test dl,superpage + IFZ + mov eax,[ecx] + and eax,-pagesize + IFZ + push edx + mov edx,sigma0_task + call map_fresh_ptab + pop edx + FI + + xptab ecx,esi + lea ecx,[(ecx*4)+eax+PM] + + ELIFB ebx,ds:[logical_info_page+main_mem].mem_end ;;;; max_physical_memory_size + mov eax,ecx + and eax,pagesize-1 + test byte ptr ds:[eax+shadow_pdir],page_present + CANDZ + + pushad + mov eax,ebx + and dl,NOT superpage + DO + call map_ur_page_initially + add eax,pagesize + add esi,pagesize + test eax,MB4-1 + REPEATNZ + OD + mov eax,[ecx] + and ecx,pagesize-1 + mov ds:[ecx+shadow_pdir],eax + shr eax,log2_pagesize + sub ecx,ecx + mov ds:[eax*4+ptab_backlink],ecx + popad + + FI + + test dl,superpage + IFNZ + bt ds:[cpu_feature_flags],page_size_extensions_bit ; on 486, no 4M support, device mem is + CANDNC ; initialized as 4M NOT present + and dl,NOT page_present ; ptabs (4K pages)) are generated on demand + FI ; when sigma0 maps them to someone + + mov bl,dl + mov [ecx],ebx + + test dl,superpage + IFZ + shr ebx,log2_pagesize + shl ebx,log2_size_pnode + + lea eax,[ecx-PM] + shr eax,log2_chaptersize + inc [eax+chapter_map] + + add ebx,offset pnode_base + ELSE_ + shr ebx,22 + shl ebx,log2_size_pnode + add ebx,offset M4_pnode_base + FI + + mov [ebx].pte_ptr,ecx + mov [ebx].cache0,ebx + mov [ebx].cache1,ebx + inc ebx + mov [ebx-1].child_pnode,ebx + + popad + ret + + + + icod ends + + + + + + + + + code ends + end + diff --git a/l4-x86/smp/lx/kern/x.asm b/l4-x86/smp/lx/kern/x.asm new file mode 100644 index 0000000..c860e18 --- /dev/null +++ b/l4-x86/smp/lx/kern/x.asm @@ -0,0 +1,29 @@ +include l4pre.inc +include l4const.inc + + test byte ptr ds:[ebx+4],0FFH + +.list +include kpage.inc +include uid.inc +page +include adrspace.inc +page +include tcb.inc +.list +include schedcb.inc +include cpucb.inc + +include pagconst.inc + +include pagmac.inc + +include syscalls.inc + +include msg.inc +include msgmac.inc + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kern/y.asm b/l4-x86/smp/lx/kern/y.asm new file mode 100644 index 0000000..e646693 --- /dev/null +++ b/l4-x86/smp/lx/kern/y.asm @@ -0,0 +1,137 @@ + +Someone asked the following question about implementing LN on other processors: + +"Assuming that 10% of the Nucleus code is ipc code, what would be the overall +performance if on PPC these 10% would be implemented highly optimized in assembler +while the other 90% would be implemented in a higher-level language performing +only half as fast?" + +Although the question seems simple, there are two problems with it: the presupposition +"10% ipc code" is wrong (a), and the question itself may be a red herring (b). +I think the real question is "What performance can we achieve with what implementation +methodology / implementation costs (multiple scenarios)?" (Conclusion) + + + +a) The assumption that only 10% of the Nucleus code are ipc is wrong. In fact, + about 40% of the (non-initialization) code is ipc. If mapping (which is part + of ipc) is added, even 50% to 60% belong to ipc. Obviously, a 50:50 ass:C model + is much less attractive than the assumed 10:90 model, in particular, since + the non-ipc 50% have much simpler logic than the ipc routines. + + However, when aiming at a first LN implementation being 1.3 to 2 times slower + than the optimum, probably only 10% to 20% of the ipc code had to bee highly + optimized, i.e. only the original 10% of the entire LN code. + + However, optimizing only the critical path of ipc might be a big implementation + problem. Since "the critical path" is not a logical entity like a module or a + procedure but a set of basic blocks spread among multiple procedures and even + modules, glueing the assembler and the higher-level-language parts together + might become difficult and/or expensive. The costs depend heavily on language + and its compiler, in particular on the code generator and the link conventions. + I think that there is a good chance to master the problems. However, for a sound + answer, we have to do a basic design (on paper) of the ipc part, using a concrete + processor and a conrete compiler/code generator. + + +b) The original question seems to assume that the LN performance is basically due + to the higly micro-optimized code (doing code generation by hand better than + a compiler). When you look at the 93 SOSP paper, you see that coding-level + optimizations are only responsible for the last factor of 2 to 3. Relate this + to the overall factor of 20 to 50 (LN ipc being faster than some other ipc). + This illustrates the importance and effect of conceptual and architectural + optimizations. Although important at the very end, coding-level optimizations + make sense only if the mentioned conceptual and architectural optimizations + could be fully implemented and utilized. + + This however, is not trivial. It requires a Nucleus design integrated with + the hardware architecture (see also 95 SOSP paper). Such a design necessarily + works on the machine-architecture level (what registers can be used when, + how entering kernel mode for system call / faults / device interrupts, how + to handle TLB misses, using physical or virtual addresses for tcbs, etc.) + The critical question is whether and how the implementation methodolgy + (language, compiler, code generator) permits to implement the basic design. + If we get problems on this level, they might impose even worse performance + effects than the coding-level problems discussed in (a). + Once more, I am optimistic, but a basic LN design based on a concrete + implementation tool is required to get sound answers. + + + +Conclusion + +"What performance can we achieve with what implementation methodology / implementation costs?" + +That is probably the basic question we are interested in for any LN implementation. As (a) +and (b) already elucidated, answering the question requires detailed analysis of both the +target hardware architecture and the available implementation tools. For my experience, +the best way is to make a basic "first-cut" design on paper by three experts: a Nucleus +expert, a target-hardware expert, and a compiler expert: + + 1. Design the critical ipc path and the TLB-miss handling. This covers most + performance-critical parts as well as most basic architectural design decisions: + how to enter kernel mode, how to address tcbs, interface conventions, basic + address-space structure, page-table structure ... + + Since this task is strongly influenced by the machine architecture (registers, exceptions, + processor modes, TLBs, caches, instruction timing) and the algorithmic logic is rather + simple, the design should be based on machine instructions complemented by usual + data structures and pseudo code. Using C at this level instead of machine instructions + would make things much more difficult because it would not simplify the real problem + (which is the machine architecture) and additionally introduce the code-generator + problem. + + The outcome of this step is twofold: (a) the basic architectural design decisions + as mentioned above, and (b) a good estimation for the optimally achievable LN performance + on this architecture. (b) is based on a timing analysis of the resulting critical + ipc code and the TLB miss handler. For my experience, the first version of a real + implementation (fully optimized) can be expected with +-20% of this estimation. + + + 2. In a second step, the design of (1) should be partially redone based on a (or some) + higher-level language tool(s), e.g. a C compiler. At least two scenarios should be analyzed: + 2a) complete C implementation (rewrite all of step 1 in C) ; + 2b) partial C implementation (glue all machine code of step 1 to some C skeleton). + For both cases, structural consequences and performance implications (based on a thorough + inspection of the generated code) must be carefully analyzed. + + +Combining the outputs of both steps, we will have substantiated performance and implemetation-costs +estimations for various implementation models. Three weeks should be sufficient for both steps +provided that the experts are experts, the tools are available, and the work is not interrupted +by other activities. + + Jochen Liedtke, 01/13/98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/kern/yoonseva.asm b/l4-x86/smp/lx/kern/yoonseva.asm new file mode 100644 index 0000000..788c9b3 --- /dev/null +++ b/l4-x86/smp/lx/kern/yoonseva.asm @@ -0,0 +1,335 @@ +include l4pre.inc + + + Copyright IBM, L4.YOONSEVA, 25,01,98, 1 + + +;********************************************************************* +;****** ****** +;****** Yoonho's and Seva's Real Mode INT n handler ****** +;****** ****** +;****** Author: J.Liedtke ****** +;****** ****** +;****** ****** +;****** modified: 25.01.98 ****** +;****** ****** +;********************************************************************* + + + + public real_mode_int_n + + + +.nolist +include l4const.inc +include uid.inc +include adrspace.inc +include tcb.inc +include cpucb.inc +include intrifc.inc +.list + + +ok_for x86 + + + + assume ds:codseg + + + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype + highword (dsize-1)) + db high highword dbase + + endm + + + + + +;---------------------------------------------------------------------------- +; +; data +; +;---------------------------------------------------------------------------- + + + + + +pe_bit equ 0 +pg_bit equ 31 + + +intermediate_ds_64K_base_0 equ 8 +intermediate_cs_64K_base_0 equ 16 + + + + dd 128 dup (0) +real_mode_stack dd 0 + +pm_esp dd 0 +pm_edi dd 0 +pm_cr3 dd 0 +pm_gdt_ptr df 0 +pm_idt_ptr df 0 + +intermediate_cr3 dd 0 +intermediate_gdt_ptr dw 3*8-1 + dd offset intermediate_gdt + + +real_mode_idt_ptr df 256*4-1 + + + + +intermediate_gdt dd 0,0 ; dummy seg + + descriptor rw16, 0, 0, KB64 ; 08 : 64 K data seg + descriptor xr16, 0, 0, KB64 ; 10 : 64 K code seg + + + + + + +;---------------------------------------------------------------------------- +; +; Real Mode INT n handler +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; AH n (Int # ) +; EDI addr of int_pm +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; AL instruction length +; +;---------------------------------------------------------------------------- + + +real_mode_int_n: + + + mov ecx,cr3 + mov [pm_cr3+PM],ecx + + mov ecx,dword ptr ds:[kernel_proot] ; switch to kernel_proot to access lowest MB identy-mapped + mov cr3,ecx + mov [intermediate_cr3+PM],ecx + + mov [pm_esp+PM],esp + mov [pm_edi+PM],edi + sgdt fword ptr ds:[pm_gdt_ptr+PM] + sidt [pm_idt_ptr+PM] + + mov esp,offset real_mode_stack + + + ; load register set + mov ecx,[edi+ip_eax] + shl ecx,16 + mov cx,word ptr ds:[edi+ip_ecx] + mov edx,[edi+ip_edx] + mov ebx,[edi+ip_ebx] + mov ebp,[edi+ip_ebp] + mov esi,[edi+ip_esi] + mov edi,[edi+ip_edi] + + + pushf + push offset return_from_bios + + movzx eax,al ; push destination address of INT n handler + push [eax*4] + + + lgdt fword ptr ds:[intermediate_gdt_ptr+PM] + lidt [real_mode_idt_ptr+PM] + + jmpf32 run_identity_mapped_in_lowest_megabyte,intermediate_cs_64K_base_0 + + +run_identity_mapped_in_lowest_megabyte: + + mov al,intermediate_ds_64K_base_0 + mov ah,0 + mov ds,eax + mov ss,eax + mov es,eax + mov fs,eax + mov gs,eax + + + mov eax,cr0 + osp + and eax,NOT ((1 SHL pg_bit)+(1 SHL pe_bit)) + mov cr0,eax + + jmpf16 (LOWWORD offset run_in_real_mode),0 ; only for required for flushing prefetch que on 486 + + + +run_in_real_mode: ; REAL MODE, 16-BIT MODE ! + + sub eax,eax + mov cr3,eax + + mov ds,eax + mov ss,eax + mov fs,eax + mov gs,eax + + osp + mov eax,ebx ; mov es,ebx SHR 16 + osp + shr eax,16 + mov es,eax + + osp + mov eax,ecx ; mov ax,ecx SHR 16 + osp + shr eax,16 + + + db 0CBh ; RET FAR call INT n handler + + + +return_from_bios: ; 16 bit mode! + + pushf + osp + shl edx,16 + pop edx ; pop dx ! + osp + rol edx,16 + + osp + shl eax,16 + mov eax,ecx ; mov ax,cx ! + osp + mov ecx,eax + + mov eax,es + osp + shl eax,16 + mov eax,ebx + osp + mov ebx,eax + + + osp + asp + mov eax,[intermediate_cr3] + mov cr3,eax + + osp + asp + lgdt fword ptr ds:[intermediate_gdt_ptr] + + mov eax,cr0 + osp + or eax,(1 SHL pg_bit)+(1 SHL pe_bit) + mov cr0,eax + + jmpf16 (LOWWORD offset back_in_protected_mode),intermediate_cs_64K_base_0 + + +back_in_protected_mode: + + osp + mov eax,intermediate_ds_64K_base_0 + mov ds,eax + + osp + asp + lgdt [pm_gdt_ptr] + osp + asp + lidt [pm_idt_ptr] + + jmpf16 (LOWWORD offset back_in_LN_mode),phys_mem_exec + + +back_in_LN_mode: + + mov eax,linear_kernel_space + mov ds,eax + mov es,eax + mov ss,eax + sub eax,eax + mov fs,eax + mov gs,eax + + mov esp,[pm_esp] + + mov eax,[pm_cr3] + mov cr3,eax + + + mov eax,[pm_edi+PM] + + + mov word ptr ds:[eax+ip_ecx],cx + shr ecx,16 + mov word ptr ds:[eax+ip_eax],cx + mov word ptr ds:[eax+ip_edx],dx + shr edx,16 + mov byte ptr ds:[eax+ip_eflags],dl + mov [eax+ip_ebx],ebx + mov [eax+ip_ebp],ebp + mov [eax+ip_esi],esi + mov [eax+ip_edi],edi + + + ret + + + + + + + code ends + end \ No newline at end of file diff --git a/l4-x86/smp/lx/kifc/Adrspace.inc b/l4-x86/smp/lx/kifc/Adrspace.inc new file mode 100644 index 0000000..1451c53 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Adrspace.inc @@ -0,0 +1,31 @@ +;---------------------------------------------------------------------------- +; +; kernel type definition +; +;---------------------------------------------------------------------------- + + + + IF target EQ x86 + +subtitle L4/x86 Version X + +kernel_type = x86 + +kernel_char = '5' + +gver = 2 + +kernel_x2 = 0 + +; max_cpu = 2 ; defined as compiler constrait + +include adrspac5.inc + + ENDIF + + + + + + diff --git a/l4-x86/smp/lx/kifc/Intrifc.inc b/l4-x86/smp/lx/kifc/Intrifc.inc new file mode 100644 index 0000000..c9101d5 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Intrifc.inc @@ -0,0 +1,323 @@ +;----------------------------------------------------------------------- +; +; int identifier +; +;----------------------------------------------------------------------- + +divide_error equ 0h +debug_exception equ 1h +nmi equ 2h +breakpoint equ 3h +overflow equ 4h +bound_check equ 5h +invalid_opcode equ 6h +co_not_available equ 7h +double_fault equ 8h +co_seg_overrun equ 9h +pl3_fault equ 9h +invalid_tss equ 0Ah +seg_not_present equ 0Bh +stack_exception equ 0Ch +general_protection equ 0Dh +page_fault equ 0Eh +apic_error equ 0Fh +co_error equ 10h +alignment_check equ 11h +machine_check equ 12h + + +;---------------------------------------------------------------------------- +; +; intr stack descriptions +; +;---------------------------------------------------------------------------- + + +iret_vec struc + + iret_eip dd 0 + iret_cs dw 0,0 + iret_eflags dd 0 + iret_esp dd 0 + iret_ss dw 0,0 + +iret_vec ends + + + + + +int_pm_stack struc + + ip_ds dd 0 + + ip_edi dd 0 + ip_esi dd 0 + ip_ebp dd 0 + dd 0 + ip_ebx dd 0 + ip_edx dd 0 + ip_ecx dd 0 + ip_eax dd 0 + + ip_error_code dd 0 + + ip_eip dd 0 + ip_cs dw 0,0 + ip_eflags dd 0 + ip_esp dd 0 + ip_ss dw 0,0 + +int_pm_stack ends + + + +int_v86_stack struc + + dw 0,0 + + iv_edi dd 0 + iv_esi dd 0 + iv_ebp dd 0 + dd 0 + iv_ebx dd 0 + iv_edx dd 0 + iv_ecx dd 0 + iv_eax dd 0 + + iv_error_code dd 0 + + iv_ip dw 0,0 + iv_cs dw 0,0 + iv_eflags dd 0 + iv_sp dw 0,0 + iv_ss dw 0,0 + iv_es dw 0,0 + iv_ds dw 0,0 + iv_fs dw 0,0 + iv_gs dw 0,0 + +int_v86_stack ends + + + + + + + +;---------------------------------------------------------------------------- +; +; exception & intr codes +; +;---------------------------------------------------------------------------- +; +; FEeeeeee error code (eeeeee) generated by hardware +; +; FFFFFFkk code (kk) generated by kernel +; +;---------------------------------------------------------------------------- + + +hardware_ec equ 0FEh + + +fault equ (-128+0) +trap1 equ (-128+1) +trap2 equ (-128+2) +debug_ec equ (-128+3) +error_ec equ (-128+4) +co_error_ec equ (-128+5) +trap6 equ (-128+6) +trap8 equ (-128+8) + +switch_code equ (-128+9) + +ipc_code equ (-128+127) + + +min_icode equ (hardware_ec SHL 24) +max_icode equ switch_code + + +;---------------------------------------------------------------------------- +; +; ipre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +; icode = ec_present <=> stack contains hw generated error code +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; regs saved, stack image allows restart after shutdown +; +; EAX,EDX,ESI,EDI,EBP unchanged +; +;---------------------------------------------------------------------------- + + +ipre macro icode,dscode + + IFIDN , + mov byte ptr ss:[esp+3],hardware_ec + ELSE + IFDIF , + push icode + ENDIF + ENDIF + pushad + push ds + IFDIF , + push linear_kernel_space + pop ds + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; ipost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; ipre generated stack +; +; DS,ES linear space +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; saved context restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +ipost macro + + pop ds + popad + add esp,4 + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; tpre +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; stack contains iret vector generated by hardware +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; no regs saved, DS saved and set to linear_kernel_space at pentium +; +; regs unchanged +; +;---------------------------------------------------------------------------- + + +tpre macro icode,sg1,sg2 + + push icode + IFNB + push linear_kernel_space + pop sg1 + ENDIF + IFNB + push linear_kernel_space + pop sg2 + ENDIF + + endm + + + +;---------------------------------------------------------------------------- +; +; tpost +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tpre generated stack +; +; interrupts disabled ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; at Pentium saved DS restored, returned from interrupt/exception +; +;---------------------------------------------------------------------------- + + + +tpost macro reg,sg1,sg2 + + IFNB + push linear_space + pop sg1 + ENDIF + IFNB + push linear_space + pop sg2 + ENDIF + IFNB + pop reg + ELSE + add esp,4 + ENDIF + iretd + + endm + + + + + +;---------------------------------------------------------------------------- +; +; lea int_xx_stack bottom +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg addr of int_xx_stack to pl3 +; +;---------------------------------------------------------------------------- + + +lea___ip_bottom macro reg,tcb + + test [tcb+coarse_state],v86 + lea reg,[tcb+sizeof pl0_stack-sizeof int_pm_stack] + CORNZ + IFZ ,0 + sub reg,sizeof int_v86_stack - sizeof int_pm_stack + FI + endm \ No newline at end of file diff --git a/l4-x86/smp/lx/kifc/Kpage.inc b/l4-x86/smp/lx/kifc/Kpage.inc new file mode 100644 index 0000000..c3bc73a --- /dev/null +++ b/l4-x86/smp/lx/kifc/Kpage.inc @@ -0,0 +1,112 @@ +current_kpage_version equ 3 + + +kpage struc + + LN_magic_word dd 0 + LN_version_word dd 0 + LN_label_link db 0 + kpage_version db current_kpage_version + db 0,0 + next_kpage_link dd 0 + + init_kdebug dd ? + kdebug_exception dd ? + dd ? + kdebug_end dd ? + + sigma0_ktask dd ?,?,?,? + sigma1_ktask dd ?,?,?,? + booter_ktask dd ?,?,?,? + + ptabs_per_4M db ? + pnodes_per_frame db ? + db ?,? + + dd ? + + kdebug_pages db ? + kdebug_startflags db ? + kdebug_start_port dw ? + + kdebug_max_task db ? + kdebug_permissions db ? + db ?,? + + main_mem dd ?,? + reserved_mem0 dd ?,? + reserved_mem1 dd ?,? + + dedicated_mem0 dd ?,? + dedicated_mem1 dd ?,? + dedicated_mem2 dd ?,? + dedicated_mem3 dd ?,? + dedicated_mem4 dd ?,? + + user_clock dd 0,0 + dd 0,0 + cpu_clock_freq dd 0 + bus_clock_freq dd 0 + dd 0,0 + aliased_boot_mem dd 0,0 + alias_base dd 0 + start_ebx dd 0 + + mpfloatstruc dd 0 + mpconftbl dd 0 + dd 0 + proc_data dd 0 + + numb_proc db 0 + prc_sema db 0 + prc_release db 0 + db 0 + dd 0,0,0 + +kpage ends + + + +kpage_mem_regions = (offset dedicated_mem4-offset reserved_mem0)/sizeof mem_descriptor+1 + + + + + + +ktask_descriptor struc + + ktask_stack dd 0 + ktask_start dd 0 + ktask_begin dd 0 + ktask_end dd 0 + +ktask_descriptor ends + + +mem_descriptor struc + + mem_begin dd 0 + mem_end dd 0 + +mem_descriptor ends + + + + +kdebug_startup_flags_bits record ksf_free:7,skdebug:1 + +kdebug_permission_bits record kp_free:2,kp_p:1,kp_i:1,kp_w:1,kp_d:1,kp_r:1,kp_m:1 + + + +startup_kdebug equ (mask skdebug) + +kdebug_dump_map_enabled equ (mask kp_m) +kdebug_dump_regs_enabled equ (mask kp_r) +kdebug_dump_mem_enabled equ (mask kp_d) +kdebug_write_enabled equ (mask kp_w) +kdebug_io_enabled equ (mask kp_i) +kdebug_protocol_enabled equ (mask kp_p) + + diff --git a/l4-x86/smp/lx/kifc/L4const.inc b/l4-x86/smp/lx/kifc/L4const.inc new file mode 100644 index 0000000..df2a916 --- /dev/null +++ b/l4-x86/smp/lx/kifc/L4const.inc @@ -0,0 +1,95 @@ +;********************************************************************* +;****** ****** +;****** Controller Constants ****** +;****** ****** +;********************************************************************* + +;---------------------------------------------------------------------------- +; +; System Flags +; +;---------------------------------------------------------------------------- + +c_flag equ 0 +z_flag equ 6 +s_flag equ 7 +t_flag equ 8 +i_flag equ 9 +d_flag equ 10 +o_flag equ 11 +nt_flag equ 14 +r_flag equ 16 +vm_flag equ 17 +ac_flag equ 18 +vif_flag equ 19 +vip_flag equ 20 +id_flag equ 21 + +iopl_field equ 12 + + + +;------------------------------------------------------------------------ +; +; selectors +; +;------------------------------------------------------------------------ + +first_kernel_sgm equ 0008h + +linear_kernel_space equ 0008h + +linear_space equ (0010h+3) +linear_space_exec equ (0018h+3) + +phys_mem_exec equ 0020h +phys_mem equ 0028h + +cpu0_tss equ 0030h + + + +;------------------------------------------------------------------------- +; +; miscellaneous constants +; +;------------------------------------------------------------------------- + +KB equ 1024 +MB equ (KB*KB) +GB equ (KB*MB) + +KB1 equ 400h +KB2 equ 800h +KB4 equ 1000h +KB16 equ 4000h +KB32 equ 8000h +KB64 equ 10000h +KB128 equ 20000h +KB256 equ 40000h +KB512 equ 80000h +MB1 equ 100000h +MB2 equ 200000h +MB4 equ 400000h +MB8 equ 800000h +MB16 equ 1000000h +MB32 equ 2000000h +MB64 equ 4000000h +GB1 equ 40000000h + + + +;------------------------------------------------------------------------- +; +; processor types +; +;------------------------------------------------------------------------- + + +i386 equ 30h +i486 equ 40h +x86 equ 50h +pentium equ 51h +ppro equ 60h +pII equ 62h +pIII equ 63h \ No newline at end of file diff --git a/l4-x86/smp/lx/kifc/L4kd.inc b/l4-x86/smp/lx/kifc/L4kd.inc new file mode 100644 index 0000000..0b499dc --- /dev/null +++ b/l4-x86/smp/lx/kifc/L4kd.inc @@ -0,0 +1,103 @@ + +kd____outchar macro +int 3 +cmp al,0 +endm + +kd____outstring macro +int 3 +cmp al,1 +endm + +kd____outcstring macro +int 3 +cmp al,2 +endm + +kd____clear_page macro +int 3 +cmp al,3 +endm + +kd____cursor macro +int 3 +cmp al,4 +endm + +kd____outhex32 macro +int 3 +cmp al,5 +endm + +kd____outhex20 macro +int 3 +cmp al,6 +endm + +kd____outhex16 macro +int 3 +cmp al,7 +endm + +kd____outhex12 macro +int 3 +cmp al,8 +endm + +kd____outhex8 macro +int 3 +cmp al,9 +endm + +kd____outhex4 macro +int 3 +cmp al,10 +endm + +kd____outdec macro +int 3 +cmp al,11 +endm + +kd____incharety macro +int 3 +cmp al,12 +endm + +kd____inchar macro +int 3 +cmp al,13 +endm + +kd____inhex32 macro +int 3 +cmp al,14 +endm + +kd____inhex16 macro +int 3 +cmp al,15 +endm + +kd____inhex8 macro +int 3 +cmp al,16 +endm + +kd____inhext macro +int 3 +cmp al,17 +endm + + +kd____disp macro string + local xx + +int 3 +nop +jmp short xx +db string +xx: +endm + + diff --git a/l4-x86/smp/lx/kifc/L4pre.inc b/l4-x86/smp/lx/kifc/L4pre.inc new file mode 100644 index 0000000..58078de --- /dev/null +++ b/l4-x86/smp/lx/kifc/L4pre.inc @@ -0,0 +1,875 @@ +.nolist +.586p +option oldstructs,nokeyword:,expr32,offset:segment +.sall + +strt16 segment para public use16 'code' +strt16 ends + +strt segment byte public use32 'code' +strt ends + +labseg segment byte public use32 'code' +labseg ends + +kcod segment para public use32 'code' +kcod ends + +code segment para public use32 'code' + assume ds:nothing, es:nothing, ss:nothing + + +dcod segment para public use32 'code' +dcod ends + +scod segment para public use32 'code' +scod ends + +icod segment para public use32 'code' +icod ends + +ic16 segment para public use16 'code' +ic16 ends + +lastseg segment para public use32 'code' +lastseg ends + +strtseg macro +strt segment byte public use32 'code' +endm + +kcode macro +kcod segment para public use32 'code' +endm + +dcode macro +dcod segment para public use32 'code' +endm + + +scode macro +scod segment para public use32 'code' +endm + + +icode macro +icod segment para public use32 'code' +endm + + +icode16 macro +ic16 segment para public use16 'code' +endm + +;codseg group c16,kcod,dcod,scod,code,icod,ic16 + +codseg group strt,kcod,dcod,scod,code,icod +c16seg group strt16,ic16 + + +osp macro +db 66h +endm + +asp macro +db 67h +endm + +on equ 1 +off equ 0 + + +NST=0 +doNST=0 +clab=0 + +jY macro j,lab,lg +ifb +j short il&lab +else +j il&lab +endif +endm + +jX macro j,lab,d,lg +jY j,%lab&d,lg +endm + +dlY macro lab +il&lab: +endm + +dlab macro lab,d +dlY %lab&d +endm + +setv macro lab,d,val +lab&d=val +endm + +IF_ macro j,l,r,lg +NST=NST+1 +setv fil,%NST,clab+1 +setv elsel,%NST,clab+2 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +dlY %clab +clab=clab+3 +endm + +FI macro +dlab elsel,%NST +dlab fil,%NST +NST=NST-1 +endm + +ELSE_ macro lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +endm + +ELIF_ macro j,l,r,lg +jX jmp,fil,%NST,lg +dlab elsel,%NST +setv elsel,%NST,clab +clab=clab+1 +ifnb +cmp l,r +endif +ifnb +jX j,elsel,%NST,lg +endif +endm + +CAND macro j,l,r,lg +ifnb +cmp l,r +endif +jX j,elsel,%NST,lg +endm + +COR macro j,l,r +ifnb +cmp l,r +endif +jX j,clab +endm + +IFC macro l,r,lg +IF_ jnc,,,lg +endm +IFNC macro l,r,lg +IF_ jc,,,lg +endm +IFZ macro l,r,lg +IF_ jnz,,,lg +endm +IFNZ macro l,r,lg +IF_ jz,,,lg +endm +IFS macro l,r,lg +IF_ jns,,,lg +endm +IFNS macro l,r,lg +IF_ js,,,lg +endm +IFB_ macro l,r,lg +IF_ jnb,,,lg +endm +IFBE macro l,r,lg +IF_ jnbe,,,lg +endm +IFA macro l,r,lg +IF_ jna,,,lg +endm +IFAE macro l,r,lg +IF_ jnae,,,lg +endm +IFL macro l,r,lg +IF_ jnl,,,lg +endm +IFLE macro l,r,lg +IF_ jnle,,,lg +endm +IFG macro l,r,lg +IF_ jng,,,lg +endm +IFGE macro l,r,lg +IF_ jnge,,,lg +endm +IFPE macro l,r,lg +IF_ jpo,,,lg +endm +IFPO macro l,r,lg +IF_ jpe,,,lg +endm + +ELIFC macro l,r,lg +ELIF_ jnc,,,lg +endm +ELIFNC macro l,r,lg +ELIF_ jc,,,lg +endm +ELIFZ macro l,r,lg +ELIF_ jnz,,,lg +endm +ELIFNZ macro l,r,lg +ELIF_ jz,,,lg +endm +ELIFS macro l,r,lg +ELIF_ jns,,,lg +endm +ELIFNS macro l,r,lg +ELIF_ js,,,lg +endm +ELIFB macro l,r,lg +ELIF_ jnb,,,lg +endm +ELIFBE macro l,r,lg +ELIF_ jnbe,,,lg +endm +ELIFA macro l,r,lg +ELIF_ jna,,,lg +endm +ELIFAE macro l,r,lg +ELIF_ jnae,,,lg +endm +ELIFL macro l,r,lg +ELIF_ jnl,,,lg +endm +ELIFLE macro l,r,lg +ELIF_ jnle,,,lg +endm +ELIFG macro l,r,lg +ELIF_ jng,,,lg +endm +ELIFGE macro l,r,lg +ELIF_ jnge,,,lg +endm + +CANDC macro l,r,lg +CAND jnc,,,lg +endm +CANDNC macro l,r,lg +CAND jc,,,lg +endm +CANDZ macro l,r,lg +CAND jnz,,,lg +endm +CANDNZ macro l,r,lg +CAND jz,,,lg +endm +CANDS macro l,r,lg +CAND jns,,,lg +endm +CANDNS macro l,r,lg +CAND js,,,lg +endm +CANDB macro l,r,lg +CAND jnb,,,lg +endm +CANDBE macro l,r,lg +CAND jnbe,,,lg +endm +CANDA macro l,r,lg +CAND jna,,,lg +endm +CANDAE macro l,r,lg +CAND jnae,,,lg +endm +CANDL macro l,r,lg +CAND jnl,,,lg +endm +CANDLE macro l,r,lg +CAND jnle,,,lg +endm +CANDG macro l,r,lg +CAND jng,,,lg +endm +CANDGE macro l,r,lg +CAND jnge,,,lg +endm +CANDPE macro l,r,lg +CAND jpo,,,lg +endm +CANDPO macro l,r,lg +CAND jpe,,,lg +endm + +CORC macro l,r +COR jc,, +endm +CORNC macro l,r +COR jnc,, +endm +CORZ macro l,r +COR jz,, +endm +CORNZ macro l,r +COR jnz,, +endm +CORS macro l,r +COR js,, +endm +CORNS macro l,r +COR jns,, +endm +CORB macro l,r +COR jb,, +endm +CORBE macro l,r +COR jbe,, +endm +CORA macro l,r +COR ja,, +endm +CORAE macro l,r +COR jae,, +endm +CORL macro l,r +COR jl,, +endm +CORLE macro l,r +COR jle,, +endm +CORG macro l,r +COR jg,, +endm +CORGE macro l,r +COR jge,, +endm + + +DO macro +doNST=doNST+1 +setv dol,%doNST,clab +setv odl,%doNST,clab+1 +clab=clab+2 +dlab dol,%doNST +endm + +OD macro +dlab odl,%doNST +doNST=doNST-1 +endm + +REPEAT macro +jX jmp,dol,%doNST,lg +endm +REPEATC macro +jX jc,dol,%doNST,lg +endm +REPEATNC macro +jX jnc,dol,%doNST,lg +endm +REPEATZ macro +jX jz,dol,%doNST,lg +endm +REPEATNZ macro +jX jnz,dol,%doNST,lg +endm +REPEATS macro +jX js,dol,%doNST,lg +endm +REPEATNS macro +jX jns,dol,%doNST,lg +endm +REPEATA macro +jX ja,dol,%doNST,lg +endm +REPEATAE macro +jX jae,dol,%doNST,lg +endm +REPEATB macro +jX jb,dol,%doNST,lg +endm +REPEATBE macro +jX jbe,dol,%doNST,lg +endm +REPEATL macro +jX jl,dol,%doNST,lg +endm +REPEATLE macro +jX jle,dol,%doNST,lg +endm +REPEATG macro +jX jg,dol,%doNST,lg +endm +REPEATGE macro +jX jge,dol,%doNST,lg +endm + +RLOOP macro +jX loop,dol,%doNST,lg +endm +RLOOPZ macro +jX loopz,dol,%doNST,lg +endm +RLOOPNZ macro +jX loopnz,dol,%doNST,lg +endm + + +EXIT macro lg +jX jmp,odl,%doNST,lg +endm +EXITC macro lg +jX jc,odl,%doNST,lg +endm +EXITNC macro lg +jX jnc,odl,%doNST,lg +endm +EXITZ macro lg +jX jz,odl,%doNST,lg +endm +EXITNZ macro lg +jX jnz,odl,%doNST,lg +endm +EXITS macro lg +jX js,odl,%doNST,lg +endm +EXITNS macro lg +jX jns,odl,%doNST,lg +endm +EXITA macro lg +jX ja,odl,%doNST,lg +endm +EXITAE macro lg +jX jae,odl,%doNST,lg +endm +EXITB macro lg +jX jb,odl,%doNST,lg +endm +EXITBE macro lg +jX jbe,odl,%doNST,lg +endm +EXITL macro lg +jX jl,odl,%doNST,lg +endm +EXITLE macro lg +jX jle,odl,%doNST,lg +endm +EXITG macro lg +jX jg,odl,%doNST,lg +endm +EXITGE macro lg +jX jge,odl,%doNST,lg +endm + + +OUTER_LOOP macro exitmac +doNST=doNST-1 +exitmac +doNST=doNST+1 +endm + + + +xxl=0 + +defretl macro lab +xr&lab: +endm + +jret macro j,lab,lg +ifb +j short xr&lab +else +j xr&lab +endif +endm + +pret macro lab +push offset xr&lab +endm + +pret macro lab +push offset xr&lab +endm + +XC macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +defretl %x&lab +endm + +XHEAD macro lab +xh&lab: +ifndef x2&lab +x&lab=xxl +xxl=xxl+1 +x1&lab=0 +endif +xretl=x&lab +endm + +XRET macro cond,lg +ifb +jret jmp,%xretl,lg +else +jret j&cond,%xretl,lg +endif +endm + +push__xret macro +pret %xretl +endm + +CANDNZ_xc_ELSE macro lab,lg +ifb +jnz short xh&lab +else +jnz xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +endm + +FI_xr macro lab +FI +defretl %x&lab +endm + +IF____xc macro cond,lab,lg +ifb +j&cond short xh&lab +else +j&cond xh&lab +endif +ifndef x1&lab +x&lab=xxl +xxl=xxl+1 +x2&lab=0 +endif +fi____lab=x&lab +&lab&_false: +endm + +ELSE__ macro +endm + +FI____ macro +defretl %fi____lab +endm + + + +XXRET_FALSE macro lab,lg +ifb +jmp short &lab&_false +else +jmp &lab&_false +endif +endm + + +cmp___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0F8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0F8h,imm +else +cmp eax,imm +endif +endif +endm + +add___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0C0h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0C0h,imm +else +add eax,imm +endif +endif +endm + + +sub___eax macro imm +if ((imm le 127) AND (imm ge 0)) +db 83h,0E8h,imm +else +if ((-(imm) le 128) AND (-(imm) ge 0)) +db 83h,0E8h,imm +else +sub eax,imm +endif +endif +endm + + +movi macro reg,imm +if imm EQ 0 +sub reg,reg +else +mov reg,imm +endif +endm + + + +ccall macro cc,lab +j&cc& $+3 +db 81h +call lab +endm + + +log2 macro v +if v AND 0FFFF0000h +log2 <%(v SHR 16)> +log2_=log2_+16 +else +if v AND 0FF00h +log2 <%(v SHR 8)> +log2_=log2_+8 +else +if v AND 0F0h +log2 <%(v SHR 4)> +log2_=log2_+4 +else +if v AND 0Ch +log2 <%(v SHR 2)> +log2_=log2_+2 +else +if v eq 2 +log2_=1 +else +if v eq 1 +log2_=0 +else +log2_ovfl +endif +endif +endif +endif +endif +endif +endm + + + +eaxhl equ ax +ebxhl equ bx +ecxhl equ cx +edxhl equ dx +esihl equ si +edihl equ di +ebphl equ bp +eaxl equ al +ebxl equ bl +ecxl equ cl +edxl equ dl +eaxh equ ah +ebxh equ bh +ecxh equ ch +edxh equ dh +axl equ al +bxl equ bl +cxl equ cl +dxl equ dl +axh equ ah +bxh equ bh +cxh equ ch +dxh equ dh + +eaxcode equ 0 +ecxcode equ 1 +edxcode equ 2 +ebxcode equ 3 +espcode equ 4 +ebpcode equ 5 +esicode equ 6 +edicode equ 7 + +clign macro alignment,off + +ifb +aax=($-modstart) AND (alignment-1) +else +aax=($-modstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +klign macro alignment,off + +ifb +aax=($-kmodstart) AND (alignment-1) +else +aax=($-kmodstart+off) AND (alignment-1) +endif +if aax eq 0 +aax=alignment +endif +aax=aax+16-alignment +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax le 10 +db 8Dh,80h,0,0,0,0 +aax=aax+6 +endif +if aax eq 11 +db 8Dh,40h,0 +aax=aax+3 +endif +if aax eq 12 +mov eax,eax +mov eax,eax +endif +if aax eq 13 +db 8Dh,40h,0 +endif +if aax eq 14 +mov eax,eax +endif +if aax eq 15 +nop +endif +endm + + +ke macro text +local lab +int 3 +jmp short lab +db &text +lab: +endm + + +ko macro char +int 3 +cmp al,'&char' +endm + + + +true equ 1 +false equ 0 + + +kmeasure=off + +inc___measure macro cnt +IF kmeasure +inc cnt +ENDIF +endm + +jmpf32 macro off,seg +db 0EAh +dd off +dw seg +endm + +jmpf16 macro off,seg +db 0EAh +dw off +dw seg +endm + + + + + + + +Copyright macro who,name,dd,mm,yy,ver,type +title name +modstart equ $ +labseg segment byte public use32 'code' +labstart equ $ +ifidn , +kcod segment para public use32 'code' +kmodstart equ $ +kcod ends +dw lowword offset kmodstart +else +dw 0 +endif +dw lowword offset modstart +if yy LE 90 +dw ((yy+10) SHL 9)+(mm SHL 5)+dd +else +dw ((yy-90) SHL 9)+(mm SHL 5)+dd +endif +dw ver+gver*1024 +db '&name&',0 +db '(C)' +db '&who&',0 +if ($-labstart) LT 16 +dd 0,0,0 +endif +if ($-labstart) GT 32 +(c)ovfl +endif +labseg ends +endm + +ok_for macro k1,k2,k3 +xok %kernel_type,k1,k2,k3 +endm + +xok macro k,k1,k2,k3 +IFB +wrong kernel +ELSE +IF k NE k1 +xok k,k2,k3 +ENDIF +ENDIF +endm + +.list diff --git a/l4-x86/smp/lx/kifc/Lbmac.inc b/l4-x86/smp/lx/kifc/Lbmac.inc new file mode 100644 index 0000000..e515344 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Lbmac.inc @@ -0,0 +1,57 @@ + +rtc_pulses_per_second equ 512 +rtc_millis_per_pulse equ 2 +rtc_thousand_div_millis equ 500 +rtc_micros_per_pulse equ 2000 + + + + +;---------------------------------------------------------------------------- +; +; reset timer intr condition (exported to dispatch) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +reset_rtc_timer_intr macro + + mov al,0Ch ; rtc reg C + out 70h,al ; rtc address + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h ; rtc data + + mov al,60h ; seoi_rtc + out 0A0h,al ; pic2_ocw2 + mov al,1011b ; read_isr + out 0A0h,al + jmp $+2 + jmp $+2 + in al,0A0h + test al,al + IFZ + mov al,62h ; seoi master + out 20h,al ; pic1_ocw2 + FI + + mov al,0Ch + out 70h,al + jmp $+2 + jmp $+2 + jmp $+2 + jmp $+2 + in al,71h + test al,0C0h +; IFNZ +; ke 'RTC_dead' +; FI + + endm diff --git a/l4-x86/smp/lx/kifc/Pagcb.inc b/l4-x86/smp/lx/kifc/Pagcb.inc new file mode 100644 index 0000000..d60f8a5 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Pagcb.inc @@ -0,0 +1,20 @@ + + +pagman_control_block struc + + db offset pag_cb dup (?) + + free_pnode_root dd 0 + do_fpage_counter dd 0 + + first_free_fresh_frame dd 0 + free_fresh_frames dd 0 + + small_space_size_DIV_MB4 db 0 + log2_small_space_size_DIV_MB4 db 0 + + fresh_frame_pool_lock db 0 + db 0 + + +pagman_control_block ends diff --git a/l4-x86/smp/lx/kifc/Pagconst.inc b/l4-x86/smp/lx/kifc/Pagconst.inc new file mode 100644 index 0000000..7020d64 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Pagconst.inc @@ -0,0 +1,79 @@ +;---------------------------------------------------------------------------- +; +; page entry status bits +; +;---------------------------------------------------------------------------- + + +page_present_bit equ 0 +page_write_permit_bit equ 1 +page_user_permit_bit equ 2 +page_write_through_bit equ 3 +page_cache_disable_bit equ 4 +page_accessed_bit equ 5 +page_dirty_bit equ 6 +superpage_bit equ 7 +global_page_bit equ 8 + +shadow_ptab_bit equ 10 + + + +page_present equ (1 SHL page_present_bit) +page_write_permit equ (1 SHL page_write_permit_bit) +page_user_permit equ (1 SHL page_user_permit_bit) +page_write_through equ (1 SHL page_write_through_bit) +page_cache_disable equ (1 SHL page_cache_disable_bit) +page_accessed equ (1 SHL page_accessed_bit) +page_dirty equ (1 SHL page_dirty_bit) +superpage equ (1 SHL superpage_bit) +global_page equ (1 SHL global_page_bit) + +shadow_ptab equ (1 SHL shadow_ptab_bit) + + + +page_fault_due_to_priv_viol_bit equ page_present_bit +page_fault_due_to_write_bit equ page_write_permit_bit +page_fault_from_user_level_bit equ page_user_permit_bit + +page_fault_due_to_priv_violation equ (1 SHL page_fault_due_to_priv_viol_bit) +page_fault_due_to_write equ (1 SHL page_fault_due_to_write_bit) +page_fault_from_user_level equ (1 SHL page_fault_from_user_level_bit) + + + + + + + +;---------------------------------------------------------------------------- +; +; test page present / writable +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg address +; +; CS phys mem exec +; DS,ES linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; NC: present / writable (executes very fast) +; +; C: not present / not writable (executes slow) +; +;---------------------------------------------------------------------------- + + +test__page_present macro reg + db 0F6h,40h+reg&code,0,0FFh +endm + + +test__page_writable macro reg + db 80h,60h+reg&code,0,0FFh +endm diff --git a/l4-x86/smp/lx/kifc/Pagmac.inc b/l4-x86/smp/lx/kifc/Pagmac.inc new file mode 100644 index 0000000..a9308a1 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Pagmac.inc @@ -0,0 +1,159 @@ +;---------------------------------------------------------------------------- +; +; xpdir / xptab (calc pdir/ptab index out of address) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; addr linear address +; reg 32 bit register +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg index within pdir/ptab corresponding to addr, +; i.e. pdir/ptab + 4*reg hold pdir/ptab entry +; +;---------------------------------------------------------------------------- + + +xpdir macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + shr reg,22 + endm + + + +xptab macro reg,addr + + IFDIF , + mov reg,addr + ENDIF + and reg,003FF000h + shr reg,12 + endm + + + + + +;---------------------------------------------------------------------------- +; +; load/store/change proot +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; task_no +; reg proot addr of task (store only) +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg contains proot of task (load only) +; +;---------------------------------------------------------------------------- + + + + +x86_proot struc + + switch_ptr dd 0 + proot_ptr dd 0 + +x86_proot ends + +x86_prootx struc + + dd 0 + small_as db 0 + db 0,0,0 + +x86_prootx ends + + +load__proot macro reg,task_no + mov reg, task_no + shl reg, max_cpu + push edi + lno___prc edi + add reg, edi + pop edi + mov reg, ds:[(reg*8)+task_proot+4-8] + IFIDN , + mov al,0 + ELSEIFIDN , + mov bl,0 + ELSEIFIDN , + mov cl,0 + ELSEIFIDN , + mov dl,0 + ELSE + and reg,0FFFFFF00h + ENDIF + endm + + +store_proot macro reg,task_no + push ecx + mov ecx, 1 SHL max_cpu + shl task_no, max_cpu + DO + mov ds:[(task_no*8)+task_proot].switch_ptr,reg + mov ds:[(task_no*8)+task_proot].proot_ptr,reg + inc task_no + dec ecx + REPEATNZ + OD + pop ecx + endm + + +store_inactive_proot macro reg,task_no + shl task_no, max_cpu + IFIDN , + push esi + lno___prc esi + add task_no, esi + pop edi + ELSE + push edi + lno___prc edi + add task_no, edi + pop edi + ENDIF + mov ds:[(task_no*8)+task_proot-8],reg + mov ds:[(task_no*8)+task_proot+4-8],0 + endm + + +chnge_proot macro reg,task_no + shl task_no, max_cpu + IFIDN , + push esi + lno___prc esi + add task_no, esi + pop edi + ELSE + push edi + lno___prc edi + add task_no, edi + pop edi + ENDIF + test byte ptr ds:[(task_no*8)+task_proot+3-8],80h + IFZ + mov ds:[(task_no*8)+task_proot-8].switch_ptr,reg + FI + and ds:[(task_no*8)+task_proot-8].proot_ptr,000000FFh + or ds:[(task_no*8)+task_proot-8].proot_ptr,reg + endm + + + + diff --git a/l4-x86/smp/lx/kifc/Pnodes.inc b/l4-x86/smp/lx/kifc/Pnodes.inc new file mode 100644 index 0000000..cd24335 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Pnodes.inc @@ -0,0 +1,64 @@ +;**************************************************************************** +;***** ***** +;***** ***** +;***** pnode data structures ***** +;***** ***** +;***** ***** +;**************************************************************************** + + + +pnodes_per_frame_default equ 16 + + +pnode struc + + pte_ptr dd 0 + child_pnode dd 0 + succ_pnode dd 0 + pred_pnode dd 0 + +pnode ends + + +root_pnode struc + + dd 0 + dd 0 + cache0 dd 0 + cache1 dd 0 + +root_pnode ends + + +free_pnode struc + + next_free dd 0 + dd 0 + dd 0 + dd 0 + +free_pnode ends + + + + +log2_size_pnode equ 4 + +.errnz ((1 SHL log2_size_pnode) - sizeof pnode) + +.errnz (offset succ_pnode - offset cache0) +.errnz (offset pred_pnode - offset cache1) + + +.errnz offset pnode_space AND (pnode_space_size-1) + + + + + +M4_pnode_base equ offset pnode_space + +max_M4_frames equ 1024 ; 4GB/4MB + +pnode_base equ (offset pnode_space + max_M4_frames * sizeof pnode) diff --git a/l4-x86/smp/lx/kifc/Schedcb.inc b/l4-x86/smp/lx/kifc/Schedcb.inc new file mode 100644 index 0000000..0ecc9bc --- /dev/null +++ b/l4-x86/smp/lx/kifc/Schedcb.inc @@ -0,0 +1,460 @@ +include schedcb2.inc + + + +;---------------------------------------------------------------------------- +; +; timeslice, ticker & wakeups +; +;---------------------------------------------------------------------------- + + +std_timeslice_length equ 10 + + + +;---------------------------------------------------------------------------- +; +; double linked lists +; +;---------------------------------------------------------------------------- + + +double_linked_list struc + + succ dd 0 + pred dd 0 + +double_linked_list ends + + +double_linked_list_root struc + + head dd 0 + tail dd 0 + +double_linked_list_root ends + + + +;---------------------------------------------------------------------------- +; +; double linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +llinit macro tcb,list + + or [tcb+list_state],is_&list& + mov [tcb+list&_llink].head,tcb + mov [tcb+list&_llink].tail,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; double linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be inserted (REG) +; root addr of root (REG) +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +llins macro entry,root,temp,list + + or [entry+list_state],is_&list& + mov [entry+list&_llink].pred,root + mov temp,[root+list&_llink].succ + mov [root+list&_llink].succ,entry + mov [entry+list&_llink].succ,temp + mov [temp+list&_llink].pred,entry + endm + + + + +;---------------------------------------------------------------------------- +; +; double linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; entry tcb to be deleted (REG) +; temp... REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp_succ succ of deleted entry +; temp_pred pred of deleted entry +; +; [deleted].succ = 0 +; +;---------------------------------------------------------------------------- + + +lldel macro entry,temp_succ,temp_pred,list + + and [entry+list_state],NOT is_&list& + mov temp_succ,[entry+list&_llink].succ + mov temp_pred,[entry+list&_llink].pred + mov [temp_succ+list&_llink].pred,temp_pred + mov [temp_pred+list&_llink].succ,temp_succ + endm + + + + + + +;---------------------------------------------------------------------------- +; +; single linked lists +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; single linked list init +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; +;---------------------------------------------------------------------------- + +linit macro list + + mov ds:[dispatcher_tcb+&list&_link],0 + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list root / next / first +; +;---------------------------------------------------------------------------- +; next PRECONDITION: +; +; list link offset in tcb +; tcb first / next tcb in list +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; root POSTCONDITION: +; +; tcb root +; +;---------------------------------------------------------------------------- +; next POSTCONDITION: +; +; pred predecessing tcb in list +; +; tcb NZ: first/next tcb +; Z: end of list +; +;---------------------------------------------------------------------------- +; first POSTCONDITION: +; +; tcb first +; +;---------------------------------------------------------------------------- + + +movl__root macro tcb,list + + mov tcb,offset dispatcher_tcb + endm + + +movl__next macro tcb,pred,list + + mov pred,tcb + mov tcb,[tcb+&list&_link] + test tcb,tcb + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list ins +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be inserted +; temp REG +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; temp scratch +; +;---------------------------------------------------------------------------- + + +lins macro tcb,temp,list + + or [tcb+list_state],is_&list& + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+&list&_link] + mov [tcb+&list&_link],temp + endm + + + +linsr macro tcb,temp,list,listmask + + or [tcb+list_state],listmask + mov temp,tcb + xchg temp,ds:[dispatcher_tcb+list] + mov [tcb+list],temp + endm + + + +;---------------------------------------------------------------------------- +; +; single linked list del +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; list link offset in tcb +; tcb tcb to be deleted +; pred predecessing tcb in list +; +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; tcb pred +; pred scratch +; +;---------------------------------------------------------------------------- + + +ldel macro tcb,pred,list + + and [tcb+list_state],NOT is_&list& + mov tcb,[tcb+&list&_link] + mov [pred+&list&_link],tcb + mov tcb,pred + endm + + + + +;---------------------------------------------------------------------------- +; +; mark ready +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EDI scratch +; +; thread marked ready +; +;---------------------------------------------------------------------------- + + +mark__ready macro tcb + + test [tcb+list_state],is_ready + IFZ + IFDIF , + push ebx + mov ebx,tcb + ENDIF + call insert_into_ready_list + IFDIF , + pop ebx + ENDIF + FI + endm + + + + +;---------------------------------------------------------------------------- +; +; mark interrupted +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb = EBX tcb (write address) to be marked as ready +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; thread marked interrupted (also ready) +; +; EAX scratch +; +;---------------------------------------------------------------------------- + + +mark__interrupted macro tcb + + mark__ready tcb + + endm + + + + + + + + +;---------------------------------------------------------------------------- +; +; add clock +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg actual system clock offset added to reg +; +; C-flag set according to result +; +;---------------------------------------------------------------------------- + +adclk macro opn,reg,labpre,labno + + labpre&labno equ $+2 + opn reg,12345678h + + endm + + +clk=0 +clkx=0 + + + +add___clk macro reg + + clk = clk+1 + adclk add,reg,clk,%clk + endm + + + +sub___clk_plus_late_late macro reg + + clkx = clkx+1 + adclk sub,reg,clkx,%clkx + endm + + + + + +;---------------------------------------------------------------------------- +; +; set clock value +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EAX new clock value +; +;---------------------------------------------------------------------------- + + +set_clock_value macro + + add eax,late_late_wakeup_interval + IF clkx GE 1 + mov dword ptr ds:[clkx1+PM],eax + ENDIF + IF clkx GE 2 + mov dword ptr ds:[clkx2+PM],eax + ENDIF + IF clkx GE 3 + mov dword ptr ds:[clkx3+PM],eax + ENDIF + IF clkx GE 4 + mov dword ptr ds:[clkx4+PM],eax + ENDIF + IF clkx GE 5 + mov dword ptr ds:[clkx5+PM],eax + ENDIF + IF clkx GE 6 + mov dword ptr ds:[clkx6+PM],eax + ENDIF + IF clkx GE 7 + mov dword ptr ds:[clkx7+PM],eax + ENDIF + sub eax,late_late_wakeup_interval + + + IF clk GE 1 + mov dword ptr ds:[clk1+PM],eax + ENDIF + IF clk GE 2 + mov dword ptr ds:[clk2+PM],eax + ENDIF + IF clk GE 3 + mov dword ptr ds:[clk3+PM],eax + ENDIF + IF clk GE 4 + mov dword ptr ds:[clk4+PM],eax + ENDIF + IF clk GE 5 + mov dword ptr ds:[clk5+PM],eax + ENDIF + IF clk GE 6 + mov dword ptr ds:[clk6+PM],eax + ENDIF + IF clk GE 7 + mov dword ptr ds:[clk7+PM],eax + ENDIF + +.erre clk LE 7 + + endm + + + diff --git a/l4-x86/smp/lx/kifc/Schedcb2.inc b/l4-x86/smp/lx/kifc/Schedcb2.inc new file mode 100644 index 0000000..a90d535 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Schedcb2.inc @@ -0,0 +1,48 @@ + +intr_sources equ 16 + +.erre (intr_sources * 4) LE sizeof intr_cb + + +scheduler_control_block struc + + db offset sched_cb dup (?) + + intrq_llink dd intr_sources*2 dup (0) + + highest_active_prio dd 0 + pulse_counter dd 0 + system_clock_low dd 0 + system_clock_high db 0 + soon_wakeup_count db 0 + late_wakeup_count db 0 + late_late_wakeup_count db 0 + ; | +scheduler_control_block ends ; | + ; V +scheduler_control_block_size equ (offset late_late_wakeup_count+1) ; masm611 bug + + + +.erre scheduler_control_block_size LE (offset sched_cb + sizeof sched_cb) + +present_root equ (offset dispatcher_tcb) ;xxx + + +soon_wakeup_interval equ 1 +late_wakeup_interval equ 50 +late_late_wakeup_interval equ 1000 + + + + + + + + + + + + + + diff --git a/l4-x86/smp/lx/kifc/Tcb.inc b/l4-x86/smp/lx/kifc/Tcb.inc new file mode 100644 index 0000000..c63a5f1 --- /dev/null +++ b/l4-x86/smp/lx/kifc/Tcb.inc @@ -0,0 +1,306 @@ +new_tcb_version equ 0f2h ; 14.04.96 extended by proc_id 3.1.99 + +empty_tcb equ 0FFh + + + +thread_control_block struc +;CL1 + soon_wakeup_link dd 0 ; link of the soon wakeup queue + late_wakeup_link dd 0 ; link of the late wakeup queue + wakeup_low dd 0 ; low dword of the timeout + rem_timeslice db 0 ; remaining timeslice of the thread + timeslice db 0 ; total timeslice of the thread + max_controlled_prio db 0 ; maximum controlled priority + prio db 0 ; priority + + sndq_root dd 0,0 ; + sndq_llink dd 0,0 ; virtual sender, propagatee tcb + +;CL2 + ready_llink dd 0,0 ; + pager dd 0 ; thread id of the pager + proxy_completion dd 0 ; completion code for cp ipc + + com_partner dd 0 ; + waddr dd 0 ; + cpu_clock_low dd 0 ; + cpu_clock_high db 0 ; + wakeup_high db 0 ; high dword of the timeout + thread_dr6 db 0 ; store location for debug register 6 + state_sp db 0 ; + +;CL3 + myself dd 0 ; threadid of myself + dd 0 + + waiting_for dd 0 ; store threadID of destination and wait for it to enter receive phase + mword2 dd 0 ; temporary store location for second message word + + fine_state db 0 ; + coarse_state db 0 ; + list_state db 0 ; + ressources db 0 ; + thread_esp dd 0 ; + rcv_descriptor dd 0 ; temporary store location for the receive descriptor while being in the send phase. + timeouts dd 0 ; + +;CL4 + ext_preempter dd 0 ; external preempter of the thread + proc_id dd 0 ; processor id the thread is aligned to + int_preempter dd 0 ; internal preempter of the thread + clan_depth db 0 ; + db 0,0,0 + + thread_dr0 dd 0 ; store location for debug register 0 + thread_dr1 dd 0 ; store location for debug register 1 + thread_dr2 dd 0 ; store location for debug register 2 + thread_dr3 dd 0 ; store location for debug register 3 + +;CL5 + thread_idt_base dd 0 ; base address of the user level interrupt descriptor table + present_llink dd 0,0 ; present link + thread_dr7 dd 0 ; store location for debug register 7 + + reg_387 dd 108/4 dup (0) ; store location for the floating point registers + + tcb_id db 'TCB' + tcb_version db 0 + + +thread_control_block ends + + + + +virtual_sender equ sndq_llink +propagatee_tcb equ (sndq_llink+4) + + + +tcb struc + + pl0_stack dd (KB1)/4 dup (0) + +tcb ends + + +;---------------------------------------------------------------------------- +; +; ressource bits +; +;---------------------------------------------------------------------------- + +ressource_bits record rfree:4,com_used:1,dr_used:1,M4_locked:1,x87_used:1 + + +;.errnz M4_locked eq (9-2) ; i_flag - 2 + + +;---------------------------------------------------------------------------- +; +; list state +; +;---------------------------------------------------------------------------- + +liste_state_bits record zpres:1,zfree:2,zpolled:1,zpoll:1,zmwake:1,zswake:1,zready:1 + +is_present equ mask zpres +is_polled equ mask zpolled +is_polling equ mask zpoll +is_late_wakeup equ mask zmwake +is_soon_wakeup equ mask zswake +is_ready equ mask zready + + +;---------------------------------------------------------------------------- +; +; coarse states +; +;---------------------------------------------------------------------------- + +coarse_state_bits record ydead:1,yrestart:1,yautoprop:1,yfree:2,yiopl3:1,yv86:1,yblck:1 + +nblocked equ mask yblck +v86 equ mask yv86 +iopl3_right equ mask yiopl3 +restarting equ mask yrestart +auto_propagating equ mask yautoprop +ndead equ mask ydead +unused_tcb equ 0 + + + +;---------------------------------------------------------------------------- +; +; fine_states +; +;---------------------------------------------------------------------------- + +fine_state_bits record xnwt:1,xnrcv:1,xfree:1,xnlk:1,xnpo:1,xnbu:1,xnwk:1,xncl:1 + +nwait equ mask xnwt +nrcv equ mask xnrcv +nlock equ mask xnlk +npoll equ mask xnpo +nready equ mask xnbu +nclos equ mask xncl +nwake equ mask xnwk + + +running equ (-256+nwait+nrcv+nlock+npoll+ nclos+nwake) +locked_waiting equ (-256+nwait+ nlock+npoll+nready+nclos+nwake) +locked_closed_waiting equ (-256+nwait+ npoll+nready+ nwake) +locked_running equ (-256+nwait+nrcv+ npoll+ nclos+nwake) +polling equ (-256+nwait+nrcv+nlock+ nready+nclos) +open_wait equ ( nrcv+nlock+npoll+nready+nclos) +closed_wait equ ( nrcv+nlock+npoll+nready) +aborted equ (-256+nwait+nrcv+nlock+npoll+nready+nclos+nwake) + + + +.erre nwait EQ 80h ; nwt bit tested by IFS +.erre nclos EQ 01h ; nclos bit part of dword aligned address + + + + + +.erre tcb_space_size GE (1 SHL (thread_no + width thread_no)) +.errnz sizeof tcb - (1 SHL thread_no) +.errnz offset tcb_space AND (tcb_space_size-1) + +.erre sizeof task_proot/(dwords_per_task_proot*4*(1 SHL max_cpu)) GE tasks + +;---------------------------------------------------------------------------- +; +; prios +; +;---------------------------------------------------------------------------- + + +nil_prio equ 0 +min_prio equ 1 +max_prio equ 255 + +prios equ (max_prio-nil_prio+1) + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + + + +dispatcher_lthread equ (0 SHL lthread_no) +dispatcher_thread equ (kernel_task+dispatcher_lthread+initial_version) +dispatcher_tcb equ (kernel_task+dispatcher_lthread+offset tcb_space) + +kbooter_lthread equ (1 SHL lthread_no) +kbooter_thread equ (kernel_task+kbooter_lthread+initial_version) +kbooter_tcb equ (kernel_task+kbooter_lthread+offset tcb_space) + +proxy_lthread0 equ (2 SHL lthread_no) +proxy_thread0 equ (kernel_task+proxy_lthread0+initial_version) +proxy_tcb0 equ (kernel_task+proxy_lthread0+offset tcb_space) + +proxy_lthread1 equ (2 SHL lthread_no) +proxy_thread1 equ (kernel_task+proxy_lthread1+initial_version) +proxy_tcb1 equ (kernel_task+proxy_lthread1+offset tcb_space) + +; test threads + +ktest1_lthread equ (5 SHL lthread_no) +ktest1_thread equ (kernel_task+ktest1_lthread+initial_version) +ktest1_tcb equ (kernel_task+ktest1_lthread+offset tcb_space) + +ktest2_lthread equ (6 SHL lthread_no) +ktest2_thread equ (kernel_task+ktest2_lthread+initial_version) +ktest2_tcb equ (kernel_task+ktest2_lthread+offset tcb_space) + + + +dispatcher_table equ (kbooter_tcb + sizeof tcb) +dispatcher_table_size equ (prios*4) + +.erre (dispatcher_table+dispatcher_table_size-dispatcher_tcb)/sizeof tcb LE lthreads + +root_chief equ ((booter_task AND mask task_no) SHL (chief_no-task_no) + +max_root_tcb equ (kbooter_tcb+(lthreads-1)*sizeof tcb) + + + + + + +.errnz (offset sigma0_proot-offset task_proot)/(dwords_per_task_proot*4*(1 SHL max_cpu)) - sigma0_task_no + +.erre (kernel_task+offset tcb_space) GE (offset kernel_firewall+kernel_firewall_size) + + + +;---------------------------------------------------------------------------- +; +; tcb lea (access tcb) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg linear read / write addr of tcb +; +;---------------------------------------------------------------------------- + + +lea___tcb macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + add reg,offset tcb_space +endm + + + +;---------------------------------------------------------------------------- +; +; load pdir address +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb 32 bit register containing tcb or id (low) of addressed task/thread +; +; DS linear space +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg 32 bit register, contains address (r/w) of pdir +; +;---------------------------------------------------------------------------- + + +lea___pdir macro reg,tcb + + IFNB + IFDIF , + mov reg,tcb + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no-12-max_cpu ;task_no * 2^max_cpu * pagesize + add reg,offset pdir_space ; (+ current cpu_no * pagesize) + endm + diff --git a/l4-x86/smp/lx/kifc/adrspac5.inc b/l4-x86/smp/lx/kifc/adrspac5.inc new file mode 100644 index 0000000..199668b --- /dev/null +++ b/l4-x86/smp/lx/kifc/adrspac5.inc @@ -0,0 +1,234 @@ + +;---------------------------------------------------------------------------- +; +; address space description +; +;---------------------------------------------------------------------------- + + +;small_space_size equ (32*MB) + + + + +; shared by all tasks +; I +; I per task +; I I +; I I + + + virtual_space_size equ (3*GB) + + + small_virtual_spaces_size equ (512*MB) + + tcb_space_size equ (256*MB) + physical_kernel_mem_size equ ( 64*MB) + pnode_space_size equ ( 64*MB) + + reserved_space_1_size equ ( 88*MB) + + pdir_space_size equ ( 4*MB) + kernel_resident_tab_size equ ( 12*MB) + + vint_size equ 32 + iopbm_size equ ( 8*KB-32) + ldt_size equ (64*KB) ; = 16 Pages + + reserved_space_2_size equ (4*MB-(64+8)*KB) + + ptab_space_size equ ( 4*MB) + com0_space_size equ ( 8*MB) + com1_space_size equ ( 8*MB) + + + + cachelines_per_mailbox equ 1 + mailbox_size equ ((32*cachelines_per_mailbox)-4) + mailbox_space_size equ ((mailbox_size+4) * (1 SHL max_cpu) * (1 SHL max_cpu)) + proxies equ 3 + + + + + + +linear_address_space struc + + virtual_space db virtual_space_size dup (?) ; 0 .. C0000000 (3GB) + + small_virtual_spaces db small_virtual_spaces_size dup (?) ; C0000000 .. E0000000 (512MB) + ; C0000000 .. C0400000 Firewall + tcb_space db tcb_space_size dup (?) ; E0000000 .. F0000000 (256MB) +; first 4 tcbs (1st page) is local and not accessible cross processor boundaries + + physical_kernel_memory db physical_kernel_mem_size dup (?) ; dyn allocated ! ; F0000000 .. F4000000 (64MB) + pnode_space db pnode_space_size dup (?) ; dyn allocated ! ; F4000000 .. F8000000 (64MB) + + reserved_space_1 db reserved_space_1_size dup (?) ; F8000000 .. FD800000 (88MB) + + pdir_space db pdir_space_size dup (?) ; FD800000 .. FDC00000 (4MB) + kernel_resident_tables db kernel_resident_tab_size dup (?) ; dyn allocated ! ; FDC00000 .. FE800000 (12MB) + + dd vint_size/4 dup (?) ; FE800000 .. FE800020 (32B) + iopbm dd iopbm_size/4 dup (?) ; FE800020 .. FE802000 (8KB) + ldt dd ldt_size/4 dup (?) ; FE802000 .. FE812000 (64KB) + + reserved_space_2 db reserved_space_2_size dup (?) ; FE812000 .. FEC00000 + + ptab_space db ptab_space_size dup (?) ; FEC00000 .. FF000000 (4MB) + com0_space db com0_space_size dup (?) ; FF000000 .. FF800000 (8MB) + com1_space db com1_space_size dup (?) ; FF800000 .. FFFFFFFF (8MB) + + + +linear_address_space ends + + +linear_address_space_size equ (offset com1_space+com1_space_size) ; masm611 bug + + ; MOD 2**32 is ok , since only used for segment descriptor construction. + + + +max_small_spaces equ (small_virtual_spaces_size/MB4) + + + +kernel_firewall equ small_virtual_spaces ; is small space 0 (never used !) +kernel_firewall_size equ MB4 + + + +;.errnz virtual_space_size AND (small_space_size-1) + + + + +auxiliary_address_space struc + + db offset ptab_space dup (?); -offset tcb_space dup (?) + + dd offset ptab_space SHR 12 dup (?) + pdir dd ? + +auxiliary_address_space ends + + + +max_physical_memory_size equ (1*GB) + +max_phys_memory struc + + max_physical_memory db max_physical_memory_size dup (?) + +max_phys_memory ends + + +log2_pagesize equ 12 ; 4 K pages +pagesize equ (1 SHL log2_pagesize) ; + + +log2_chaptersize equ (5+2) ; 32 PTEs per chapter +chaptersize equ (1 SHL log2_chaptersize); +ptes_per_chapter equ (chaptersize / 4) ; +chapters_per_page equ (pagesize / chaptersize); + + + + +PM equ offset physical_kernel_memory + +max_ptabs equ (physical_kernel_mem_size / pagesize) + + +com0_base equ offset com0_space ; due to pharlap asm bug +com1_base equ offset com1_space ; [pdir+offset cs/MB4] generates + +shared_table_base equ offset small_virtual_spaces +shared_table_size equ (offset kernel_resident_tables+kernel_resident_tab_size - shared_table_base) + + + +dwords_per_task_proot equ 2 + +; MP structures: + gdt_size equ 8*4*2 ; 8 entries times 2 double words per entry ;;; + + + +kernel_r_tables struc + + db offset kernel_resident_tables dup (?) ;FDC00000 .. FE000000 + + accessed_bitmap dd max_physical_memory_size/pagesize/32 dup (?) ; global + ptab_backlink dd max_ptabs dup (?) ; sync needed if new ptab is build + chapter_map db max_ptabs*chapters_per_page dup (?) ; sync needed if new ptab is build + + reserved_space_3 db 00B63000h-6*KB4-KB256 dup (?) ;REDIR: -KB256 ; + + mailbox dd (mailbox_space_size*proxies)/4 dup (?) + + reserved_space_3a dd (KB4 - (mailbox_space_size*proxies))/4 dup (?) + + shadow_pdir dd KB4/4 dup (?) + + io_apic dd KB4/4 dup (?) ; global done + local_apic dd KB4/4 dup (?) ; local done + + logical_info_page db KB4 dup (?) ; ? + +; local page start + db 100h-8 dup (?) + + gdt dd 8*2*4/4 dup (?) ; local: gdt = offset gdt + gdtsize*pnr-1 + db 4 dup (?) + + cpu_cb db (128+4) dup (?) ; local + sched_cb db (16*8+64) dup (?) ; local + + intr_cb db 16*4 dup (?) ; local + + reserved_space_3b dd (3*KB+320)/4 dup (?) + + reserved_space_3c dd (704)/4 dup (?) +; local page end + + pag_cb db 32 dup (?) + idt dd 40h*8/4 dup (?) + task_proot dd tasks*dwords_per_task_proot*(1 SHL max_cpu) dup (?) ; | + proot_end_marker dd dwords_per_task_proot*(1 SHL max_cpu) dup (?) ; | + ; | + redirection_table dd tasks*tasks dup (?) ; | ;REDIR + ; | + small_associated_task dw max_small_spaces dup (?) ; | ; | + ; | +kernel_r_tables ends ; | + ; V +kernel_r_tables_size equ (offset small_associated_task+2) ; masm611 bug + +.erre (kernel_r_tables_size - offset kernel_resident_tables) LE kernel_resident_tab_size + + + + +special_proots struc + + db offset task_proot dup (?) + + empty_proot dd (2*(1 SHL max_cpu)) dup (?) + kernel_proot dd (2*(1 SHL max_cpu)) dup (?) + sigma0_proot dd (2*(1 SHL max_cpu)) dup (?) + +special_proots ends + + + +.erre offset pnode_space GE (offset physical_kernel_memory + physical_kernel_mem_size) + + + + + + diff --git a/l4-x86/smp/lx/kifc/apic.inc b/l4-x86/smp/lx/kifc/apic.inc new file mode 100644 index 0000000..6eb8372 --- /dev/null +++ b/l4-x86/smp/lx/kifc/apic.inc @@ -0,0 +1,71 @@ + + apic_id equ 0020h + apic_version equ 0030h + + apic_task_prio equ 0080h + apic_arb_prio equ 0090h + apic_proc_prio equ 00A0h + apic_eoi equ 00B0h + apic_remote_read equ 00C0h + apic_logical_dest equ 00D0h + apic_dest_format equ 00E0h + apic_svr equ 00F0h + + apic_isr equ 0100h + apic_tmr equ 0180h + apic_irr equ 0200h + + apic_error_mask equ 0280h + + apic_icr equ 0300h + + apic_LINT_timer equ 0320h + apic_LINT0 equ 0350h + apic_LINT1 equ 0360h + apic_LINT_err equ 0370h + + apic_timer_init equ 0380h + apic_timer_curr equ 0390h + apic_timer_divide equ 03E0h + + + apic_enabled_bit equ 8 + focus_processor_checking_bit equ 9 + + + + icr_dest_specified equ 00b SHL 18 + icr_dest_self equ 01b SHL 18 + icr_dest_all_incl_self equ 10b SHL 18 + icr_dest_all_excl_self equ 11b SHL 18 + + icr_trigger_edge equ 0b SHL 15 + icr_trigger_level equ 1b SHL 15 + + icr_level_deassert equ 0b SHL 14 + icr_level_assert equ 1b SHL 14 + + icr_dest_mode_physical equ 0b SHL 11 + icr_dest_mode_logical equ 1b SHL 11 + + icr_delivery_mode_fixed equ 000b SHL 8 + icr_delivery_mode_lowest_prio equ 001b SHL 8 + icr_delivery_mode_SMI equ 010b SHL 8 + icr_delivery_mode_remote_read equ 011b SHL 8 + icr_delivery_mode_NMI equ 100b SHL 8 + icr_delivery_mode_init equ 101b SHL 8 + icr_delivery_mode_startup equ 110b SHL 8 + + + apic_startup_msg equ icr_dest_all_excl_self + icr_delivery_mode_startup + icr_level_assert + apic_init_msg equ icr_dest_all_excl_self + icr_delivery_mode_init + icr_level_assert + apic_init_deassert_msg equ icr_dest_all_excl_self + icr_delivery_mode_init + + + io_apic_select_reg equ 0 + io_apic_window equ 10h + + + io_apic_redir_table equ 10h + + \ No newline at end of file diff --git a/l4-x86/smp/lx/kifc/apstrtup.inc b/l4-x86/smp/lx/kifc/apstrtup.inc new file mode 100644 index 0000000..1417e21 --- /dev/null +++ b/l4-x86/smp/lx/kifc/apstrtup.inc @@ -0,0 +1,16 @@ + +;------------------------------------------------------------------------------------------- +; aquire new processor number +;------------------------------------------------------------------------------------------- +; Warning: May only be called once for each processor. +; PRECONDITION: physical kernel info page established. +; +; POSTCONDITION: new processor number in reg +; +;------------------------------------------------------------------------------------------- +aquire_new_processor_number macro reg + sub reg,reg + inc reg + lock xadd [physical_kernel_info_page+numb_proc],reg + inc reg +endm diff --git a/l4-x86/smp/lx/kifc/contents b/l4-x86/smp/lx/kifc/contents new file mode 100644 index 0000000..8f25644 --- /dev/null +++ b/l4-x86/smp/lx/kifc/contents @@ -0,0 +1,34 @@ + +Contents of src\kernifc: + + LN-internal Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + A name "x,4/5" means that there is a file "x.inc" that is included in source files and + includes either "x4.inc" (for LN/486) or "x5.inc" for LN/Pentium. + + +adrspace,4/5 Address-Space Description +apic APIC Description +cpucb,4/5 CPU-Control-Block Description + Macros +intrifc Interrupt/Trap/Fault Description + Macros +kpage Kernel Page Description +lbmac PC clock access Macros +pagcb Page Map Control Block Description +pagconst Paging Constants +pagmac Paging Macros Macros +pnodes Page Map Node Description +schedcb Scheduler Control Block Description + Macros +schedcb2 ditto Description +small-as small spaces support Macros +tcb thread control block Description + Macros + +lnpre prelude for any module, contains Dijkstra Macros +lnconst prelude for any module, constants + +lnkd kdebug interface Macros +perform Pentium Performance Counters + + + +Only the mentioned files and this file of src\kernifc are supported. \ No newline at end of file diff --git a/l4-x86/smp/lx/kifc/cpucb.inc b/l4-x86/smp/lx/kifc/cpucb.inc new file mode 100644 index 0000000..4b3149c --- /dev/null +++ b/l4-x86/smp/lx/kifc/cpucb.inc @@ -0,0 +1,7 @@ + + IF (kernel_type EQ x86) OR (kernel_type EQ pentium) + +include cpucb5.inc + + ENDIF + diff --git a/l4-x86/smp/lx/kifc/cpucb5.inc b/l4-x86/smp/lx/kifc/cpucb5.inc new file mode 100644 index 0000000..5788643 --- /dev/null +++ b/l4-x86/smp/lx/kifc/cpucb5.inc @@ -0,0 +1,295 @@ + + + +cpu_control_block struc + + db offset cpu_cb dup (?) + + cpu_tss_area dd 0 ; tss_backlink + + cpu_esp0 dd 0 ; tss_esp0 + cpu_ss0 dw 0,0 ; tss_ss0 + cpu_cr3 dd 0 ; tss_esp1 + tlb_invalidated db 0,0,0,0 ; tss_ss1 + + actual_co1_tcb dd 0 ; tss_esp2 + dw 0,0 ; tss_ss2 + dd 0 ; tss_cr3 + dd 0 ; tss_eip + + cpu_label db 8 dup (0) ; tss_eflags + tss_eax + cpu_no db 0 ; tss_ecx + cpu_type db 0 + co1_type db 0 + db 0 + cpu_feature_flags dd 0 ; tss_edx + + dd 0 ; tss_ebx + dd 0 ; tss_esp + dd 0 ; tss_ebp + dd 0 ; tss_esi + + dd 0 ; tss_edi + dw 0,0 ; tss_es + dw 0,0 ; tss_cs + dw 0,0 ; tss_ss + + dw 0,0 ; tss_ds + dw 0,0 ; tss_fs + dw 0,0 ; tss_gs + dw 0,0 ; tss_ldt + + db 0,0 ; tss_tbit + cpu_iopbm dw 0 ; io_map_base + + dd 0 + +cpu_control_block ends + +cpu_tss_backlink equ cpu_tss_area + +.errnz sizeof cpu_control_block GT (offset cpu_cb + sizeof cpu_cb) + + + +no87 equ 0 +i387 equ 3 + + + + + +;---------------------------------------------------------------------------- +; +; switch thread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; src_tcb actual thread (tcb write addr) +; EBP destination thread (tcb write addr) +; +; interrupts disabled +; +; [ESP] continuation EIP of actual (source) thread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBX,ECX,EDX,EBP values loaded by source thread +; EDI might be set to src_tcb +; ESI scratch +; +; DS,ES,FS,GS,SS unchanged +; +;---------------------------------------------------------------------------- +; Remark: Direct context switch to dest thread's stack. Stored PL0 EIP of +; dest thread ignored. The program execution only moves into the dest +; thread environment. +; +; Remark: Semantics of 'ressources' is described at 'complex_context_switch'. +; +;---------------------------------------------------------------------------- + + + +switch_thread macro name,src_tcb + + cmp [src_tcb+ressources],0 + jnz deallocate_ressources_&name + + public switch_thread_&name&_ret + switch_thread_&name&_ret: + + lea esi,[ebp+sizeof tcb] + mov ds:[cpu_esp0],esi + + mov [src_tcb+thread_esp],esp + mov esp,[ebp+thread_esp] + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; switch space +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; EBP destination task no (tcb address shifted right by size of version + lthreadno) +; +; interrupts disabled +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EBP scratch +; +; DS,ES,FS,GS linear space (related to dest task) +; +;---------------------------------------------------------------------------- + + +switch_space macro + ; mov ebp,[(ebp*8)+task_proot-(offset tcb_space SHR (task_no-3))] + + and ebp,0FFh ;taskno in lower bytes + shl ebp, max_cpu + push edi + lno___prc edi + add ebp, edi + pop edi + mov ebp,[(ebp*8)+task_proot-8] + + test ebp,ebp + IFNS + IFNZ ds:[cpu_cr3],ebp + + mov ds:[cpu_cr3],ebp + mov dword ptr ds:[tlb_invalidated],ebp + mov cr3,ebp + FI + mov ebp,00CCF300h + FI + mov ds:[gdt+linear_space/8*8+4],ebp + add ebp,0000FB00h-0000F300h + mov ds:[gdt+linear_space_exec/8*8+4],ebp + + ; reload segment registers with linear user space + mov ebp,linear_space + mov ds,ebp + mov es,ebp + mov fs,ebp + mov gs,ebp + endm + + + + +;---------------------------------------------------------------------------- +; +; mark / unmark ressource +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; rsrc resource +; +; reg tcb write addr +; +; DS linear space +; +;---------------------------------------------------------------------------- + +call_opc equ 0E8h +cmp_opc equ 03Dh + + + +mark__ressource macro reg,rscr + + or [reg+ressources],mask rscr + endm + + + +unmrk_ressource macro reg,rscr + + and [reg+ressources],NOT mask rscr + endm + + +;---------------------------------------------------------------------------- +; de/re allocate INVARIANT: +; +; thread has no cpu AND ressources <> 0 <==> reallocate pushed on stack +; +;---------------------------------------------------------------------------- + + +;---------------------------------------------------------------------------- +; +; lea esp (of thread <> me) +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; tcb tcb write addr <> me ! +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg esp of thread (ignoring reallocate vec) +; +;---------------------------------------------------------------------------- + +lea___esp macro reg,tcb + + test [tcb+ressources],0FFh + mov reg,[tcb+thread_esp] + IFNZ + add reg,4*4 + FI + endm + + +;---------------------------------------------------------------------------- +; +; lea processor number +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg prc number 1,..,15 ( 0 is invalid ) +; +;---------------------------------------------------------------------------- + + +lno___prc macro reg + + str ®&hl + and reg,1111b + shr reg,3 + + endm + + + + + + + +;---------------------------------------------------------------------------- +; +; cpu features +; +;---------------------------------------------------------------------------- + + +fpu_on_chip_bit equ 0 +enhanced_v86_bit equ 1 +io_breakpoints_bit equ 2 +page_size_extensions_bit equ 3 +time_stamp_counter_bit equ 4 +pentium_style_msrs_bit equ 5 +phys_addr_extensions_bit equ 6 +machine_check_exception_bit equ 7 +cmpxchg8b_instr_bit equ 8 +on_chip_apic_bit equ 9 +mem_type_range_regs_bit equ 12 +global_pages_bit equ 13 +machine_check_arch_bit equ 14 +cmov_extensions_bit equ 15 +mmx_extensions_bit equ 16 + + +cr4_enable_io_breakpoints_bit equ 3 +cr4_enable_superpages_bit equ 4 +cr4_enable_MC_exception_bit equ 6 +cr4_enable_global_pages_bit equ 7 diff --git a/l4-x86/smp/lx/kifc/descript.inc b/l4-x86/smp/lx/kifc/descript.inc new file mode 100644 index 0000000..6075905 --- /dev/null +++ b/l4-x86/smp/lx/kifc/descript.inc @@ -0,0 +1,86 @@ +; +; Constructs a gate descriptor for x86: +; +; 31-24:Base 23:G 22:D/B 21:0 20:AVL 19-16:SGM Limit 15:P 14-13:DPL 12:S 11-8:Type 7-0:Base +; 31-16:Base 15-0:SGM Limit + +;------------------------------------------------------------------------- +; +; descriptor types +; +;------------------------------------------------------------------------- + + +r32 equ 0100000000010000b +rw32 equ 0100000000010010b +r16 equ 10000b +rw16 equ 10010b + +x32 equ 0100000000011000b +xr32 equ 0100000000011010b +x16 equ 11000b +xr16 equ 11010b + +ldtseg equ 2 +taskgate equ 5 +tsseg equ 9 +callgate equ 0Ch +intrgate equ 0Eh +trapgate equ 0Fh + + +;--------------------------------------------------------------------------- +; +; descriptor privilege levels codes +; +;--------------------------------------------------------------------------- + +dpl0 equ (0 shl 5) +dpl1 equ (1 shl 5) +dpl2 equ (2 shl 5) +dpl3 equ (3 shl 5) + + + +;---------------------------------------------------------------------------- +; +; descriptor entry +; +;---------------------------------------------------------------------------- + + +descriptor macro dtype,dpl,dbase,dsize + + +IF dsize eq 0 + + dw 0FFFFh + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high (dtype+8000h) + 0Fh + db high highword dbase + +ELSE +IF dsize AND -KB4 + + dw lowword ((dsize SHR 12)-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high ((dtype+8000h) + highword ((dsize SHR 12)-1)) + db high highword dbase + +ELSE + + dw lowword (dsize-1) + dw lowword dbase + db low highword dbase + db low (dtype+dpl+80h) + db high dtype + db high highword dbase + +ENDIF +ENDIF + + endm diff --git a/l4-x86/smp/lx/kifc/perfmon.inc b/l4-x86/smp/lx/kifc/perfmon.inc new file mode 100644 index 0000000..eec1f26 --- /dev/null +++ b/l4-x86/smp/lx/kifc/perfmon.inc @@ -0,0 +1,109 @@ + +P_event_select equ 11h + +P_event_counter0 equ 12h +P_event_counter1 equ 13h + + +;P_event_sel_register record Pcounter:8,Pinv:1,Pen:1,Px:3,Pedge:1,Pos:1,Pusr:1,Punit:8,Pevent:8 + +P_event_sel_register record P_event1:16,P_event0:16 + + + +rd_miss equ 000011b +wr_miss equ 000100b +rw_miss equ 101001b +ex_miss equ 001110b + +d_wback equ 000110b + +rw_tlb equ 000010b +ex_tlb equ 001101b + +a_stall equ 011111b +w_stall equ 011001b +r_stall equ 011010b +x_stall equ 011011b + +agi_stall equ 011111b + +pipline_flush equ 010101b + +non_cache_rd equ 011110b +ncache_refs equ 011110b +locked_bus equ 011100b + +mem2pipe equ 001001b +bank_conf equ 001010b + + +instrs_ex equ 010110b +instrs_ex_V equ 010111b + + + + + +cnt_nothing equ 000b SHL 6 +cnt_event_pl0 equ 001b SHL 6 +cnt_event_pl3 equ 010b SHL 6 +cnt_event equ 011b SHL 6 +cnt_clocks_pl0 equ 101b SHL 6 +cnt_clocks_pl3 equ 110b SHL 6 +cnt_clocks equ 111b SHL 6 + + +P_count macro event0,cmd0,event1,cmd1 + + IFIDN , + e=0 + ELSE + e=event0 + IFB + e=e+cnt_event + ELSE + e=e+cmd0 + ENDIF + IFNB + e=e+(event1 SHL P_event1) + IFB + e=e+(cnt_event SHL P_event1) + ELSE + e=e+(cmd1 SHL P_event1) + ENDIF + ENDIF + ENDIF + + push eax + push ecx + push edx + mov eax,e + sub ecx,ecx + sub edx,edx + add ecx,P_event_select + wrmsr + IFDIF , + sub eax,eax + add ecx,P_event_counter0-P_event_select + wrmsr + add ecx,P_event_counter1-P_event_counter0 + wrmsr + ENDIF + pop edx + pop ecx + pop eax + + endm + + + +P_read macro counter + + push ecx + mov ecx,counter + rdmsr + pop ecx + + endm + diff --git a/l4-x86/smp/lx/kifc/small-as.inc b/l4-x86/smp/lx/kifc/small-as.inc new file mode 100644 index 0000000..71fde88 --- /dev/null +++ b/l4-x86/smp/lx/kifc/small-as.inc @@ -0,0 +1,188 @@ + + + +;---------------------------------------------------------------------------- +; +; cmp with small_address_space_size +; +;---------------------------------------------------------------------------- + +sass32opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + +sass8opn macro opn,reg,labpre,labno,value + + IFIDN , + labpre&labno equ $+1 + ELSE + labpre&labno equ $+2 + ENDIF + opn reg,value + + endm + + + +sass32x=0 +sass8x=0 +sass8y=0 + + +sass__32 macro opn,reg,value + sass32x = sass32x+1 + sass32opn opn,reg,sass32x,%sass32x,value + endm + + +sass__8 macro opn,reg,value + sass8x = sass8x+1 + sass8opn opn,reg,sass8x,%sass8x,value + endm + + +sass__8MB4 macro opn,reg,value + sass8y = sass8y+1 + sass8opn opn,reg,sass8y,%sass8y,value + endm + + + + + +;---------------------------------------------------------------------------- +; +; update small address space size immediates +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; CL log2 (old small_address_space_size) OR 0 {initally} +; CH log2 (new small_address_space_size) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; EAX, EBX, ECX scratch +; +;---------------------------------------------------------------------------- + + + +update_small_space_size_immediates macro + + IF (sass32x+sass8y) GE 1 + sub eax,eax + inc eax + mov ebx,eax + dec cl + shl ebx,cl + add ebx,ebx + xchg cl,ch + shl eax,cl + sub eax,ebx + ENDIF + + IF sass32x GE 1 + db 01h,05h ; add dword ptr ds:[sass32x1+PM],eax + dd sass32x1+PM + ENDIF + IF sass32x GE 2 + db 01h,05h ; add dword ptr ds:[sass32x2+PM],eax + dd sass32x2+PM + ENDIF + IF sass32x GE 3 + db 01h,05h ; add dword ptr ds:[sass32x3+PM],eax + dd sass32x3+PM + ENDIF + IF sass32x GE 4 + db 01h,05h ; add dword ptr ds:[sass32x4+PM],eax + dd sass32x4+PM + ENDIF + IF sass32x GE 5 + db 01h,05h ; add dword ptr ds:[sass32x5+PM],eax + dd sass32x5+PM + ENDIF + IF sass32x GE 6 + db 01h,05h ; add dword ptr ds:[sass32x6+PM],eax + dd sass32x6+PM + ENDIF + IF sass32x GE 7 + db 01h,05h ; add dword ptr ds:[sass32x7+PM],eax + dd sass32x7+PM + ENDIF + + IF sass8y GE 1 + sar eax,22 + db 00h,05h ; add byte ptr ds:[offset sass8y1+PM],al + dd sass8y1+PM + ENDIF + IF sass8y GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8y2+PM],al + dd sass8y2+PM + ENDIF + IF sass8y GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8y3+PM],al + dd sass8y3+PM + ENDIF + IF sass8y GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8y4+PM],al + dd sass8y4+PM + ENDIF + IF sass8y GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8y5+PM],al + dd sass8y5+PM + ENDIF + IF sass8y GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8y6+PM],al + dd sass8y6+PM + ENDIF + IF sass8y GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8y7+PM],al + dd sass8y7+M + ENDIF + + IF sass8x GE 1 + mov al,ch + sub al,cl + db 00h,05h ; add byte ptr ds:[offset sass8x1+PM],al + dd sass8x1+PM + ENDIF + IF sass8x GE 2 + db 00h,05h ; add byte ptr ds:[offset sass8x2+PM],al + dd sass8x2+PM + ENDIF + IF sass8x GE 3 + db 00h,05h ; add byte ptr ds:[offset sass8x3+PM],al + dd sass8x3+PM + ENDIF + IF sass8x GE 4 + db 00h,05h ; add byte ptr ds:[offset sass8x4+PM],al + dd sass8x4+PM + ENDIF + IF sass8x GE 5 + db 00h,05h ; add byte ptr ds:[offset sass8x5+PM],al + dd sass8x5+PM + ENDIF + IF sass8x GE 6 + db 00h,05h ; add byte ptr ds:[offset sass8x6+PM],al + dd sass8x6+PM + ENDIF + IF sass8x GE 7 + db 00h,05h ; add byte ptr ds:[offset sass8x7+PM],al + dd sass8x7+PM + ENDIF + +.erre sass32x LE 7 + + endm + + diff --git a/l4-x86/smp/lx/make/cpy.bat b/l4-x86/smp/lx/make/cpy.bat new file mode 100755 index 0000000..8647094 --- /dev/null +++ b/l4-x86/smp/lx/make/cpy.bat @@ -0,0 +1,3 @@ +xcopy f:\lx\x86\l4.exe a: + + diff --git a/l4-x86/smp/lx/make/cpy2.bat b/l4-x86/smp/lx/make/cpy2.bat new file mode 100755 index 0000000..6cf43ae --- /dev/null +++ b/l4-x86/smp/lx/make/cpy2.bat @@ -0,0 +1,4 @@ +xcopy ..\x86\l4.exe a: +xcopy ..\x86\boot.com a: + + diff --git a/l4-x86/smp/lx/make/docom.bat b/l4-x86/smp/lx/make/docom.bat new file mode 100755 index 0000000..cc19be6 --- /dev/null +++ b/l4-x86/smp/lx/make/docom.bat @@ -0,0 +1 @@ +nmake /B /f \lx\make\make-l4 /X \lx\make\std.err d:\lx\x86\boot.com diff --git a/l4-x86/smp/lx/make/doit.bat b/l4-x86/smp/lx/make/doit.bat new file mode 100755 index 0000000..09866ca --- /dev/null +++ b/l4-x86/smp/lx/make/doit.bat @@ -0,0 +1 @@ +nmake /B /f \lx\make\make-l4 /X \lx\std.err f:\lx\x86\l4.exe diff --git a/l4-x86/smp/lx/make/l4.rsp b/l4-x86/smp/lx/make/l4.rsp new file mode 100644 index 0000000..782343c --- /dev/null +++ b/l4-x86/smp/lx/make/l4.rsp @@ -0,0 +1,2 @@ +kernel startpc start mpconf apstrtup cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; diff --git a/l4-x86/smp/lx/make/make-l4 b/l4-x86/smp/lx/make/make-l4 new file mode 100644 index 0000000..ddc0929 --- /dev/null +++ b/l4-x86/smp/lx/make/make-l4 @@ -0,0 +1,120 @@ + +p={f:\lx\kern\;\lx\kifc\;\lx\uifc\} +a=f:\lx\x86^\ +all_include_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + +$(a)apstrtup.obj : $(all_include_x86) $(p)apstrtup.asm + @cd \lx\x86 + @..\make\ml-x86 apstrtup asm + +$(a)mpconf.obj : $(all_include_x86) $(p)mpconf.asm + @cd \lx\x86 + @..\make\ml-x86 mpconf asm + +$(a)adrsman.obj : $(all_include_x86) $(p)adrsman.asm + @cd \lx\x86 + @..\make\ml-x86 adrsman asm + +$(a)cpuctr.obj : $(all_include_x86) $(p)cpuctr.asm + @cd \lx\x86 + @..\make\ml-x86 cpuctr asm + +$(a)dispatch.obj : $(all_include_x86) $(p)dispatch.asm + @cd \lx\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_include_x86) $(p)emuctr.asm + @cd \lx\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_include_x86) $(p)intctr.asm + @cd \lx\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman.obj : $(all_include_x86) $(p)ipcman.asm + @cd \lx\x86 + @..\make\ml-x86 ipcman asm + +$(a)kdebug.obj : $(all_include_x86) $(p)kdebug.asm + @cd \lx\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_include_x86) $(p)kdiopc.asm + @cd \lx\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \lx\x86 + @..\make\ml-x86 kernel asm + +$(a)ktest.obj : $(all_include_x86) $(p)ktest.asm + @cd \lx\x86 + @..\make\ml-x86 ktest asm + +$(a)memctr.obj : $(all_include_x86) $(p)memctr.asm + @cd \lx\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr.obj : $(all_include_x86) $(p)pagctr.asm + @cd \lx\x86 + @..\make\ml-x86 pagctr asm + +$(a)pagfault.obj : $(all_include_x86) $(p)pagfault.asm + @cd \lx\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap.obj : $(all_include_x86) $(p)pagmap.asm + @cd \lx\x86 + @..\make\ml-x86 pagmap asm + +$(a)sgmctr.obj : $(all_include_x86) $(p)sgmctr.asm + @cd \lx\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_include_x86) $(p)sigma0.asm + @cd \lx\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_include_x86) $(p)start.asm + @cd \lx\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_include_x86) $(p)startpc.asm + @cd \lx\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_include_x86) $(p)tcbman.asm + @cd \lx\x86 + @..\make\ml-x86 tcbman asm + +$(a)yoonseva.obj : $(all_include_x86) $(p)yoonseva.asm + @cd \lx\x86 + @..\make\ml-x86 yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj $(a)mpconf.obj $(a)apstrtup.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \lx\x86 + @link /nologo @..\make\l4.rsp + rem pause + + + +$(a)boot.obj : $(all_include_x86) $(p)boot.asm + @cd \lx\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \lx\x86 + link boot.obj/TINY,boot,boot.map + + + + + + diff --git a/l4-x86/smp/lx/make/make-l4.tst b/l4-x86/smp/lx/make/make-l4.tst new file mode 100644 index 0000000..c0786c4 --- /dev/null +++ b/l4-x86/smp/lx/make/make-l4.tst @@ -0,0 +1,120 @@ + +p={d:\lx\kernel\;\lx\kernifc\;\lx\userifc\} +a=d:\lx\x86^\ +all_includes_x86= $(p)l4pre.inc $(p)l4const.inc $(p)l4kd.inc $(p)adrspace.inc $(p)adrspac5.inc $(p)tcb.inc $(p)cpucb.inc $(p)cpucb5.inc $(p)intrifc.inc $(p)pagcb.inc $(p)pagconst.inc $(p)pagmac.inc $(p)pnodes.inc $(p)schedcb.inc $(p)schedcb2.inc $(p)lbmac.inc $(p)syscalls.inc $(p)uid.inc $(p)kpage.inc $(p)msg.inc $(p)SCmac.inc $(p)apic.inc + + +$(a)apstrtup.obj : $(all_includes_x86) $(p)apstrtup.asm + @cd \lx\x86 + @..\make\ml-x86 apstrtup asm + +$(a)mpconf.obj : $(all_includes_x86) $(p)mpconf.asm + @cd \lx\x86 + @..\make\ml-x86 mpconf asm + +$(a)adrsman.obj : $(all_includes_x86) $(p)adrsman.asm + @cd \lx\x86 + @..\make\ml-x86 adrsman asm + +$(a)cpuctr.obj : $(all_includes_x86) $(p)cpuctr.asm + @cd \lx\x86 + @..\make\ml-x86 cpuctr asm + +$(a)dispatch.obj : $(all_includes_x86) $(p)dispatch.asm + @cd \lx\x86 + @..\make\ml-x86 dispatch asm + +$(a)emuctr.obj : $(all_includes_x86) $(p)emuctr.asm + @cd \lx\x86 + @..\make\ml-x86 emuctr asm + +$(a)intctr.obj : $(all_includes_x86) $(p)intctr.asm + @cd \lx\x86 + @..\make\ml-x86 intctr asm + +$(a)ipcman.obj : $(all_includes_x86) $(p)ipcman.asm + @cd \lx\x86 + @..\make\ml-x86 ipcman asm + +$(a)kdebug.obj : $(all_includes_x86) $(p)kdebug.asm + @cd \lx\x86 + @..\make\ml-x86 kdebug asm + +$(a)kdiopc.obj : $(all_includes_x86) $(p)kdiopc.asm + @cd \lx\x86 + @..\make\ml-x86 kdiopc asm + +$(a)kernel.obj : $(p)kernel.asm + @cd \lx\x86 + @..\make\ml-x86 kernel asm + +$(a)ktest.obj : $(all_includes_x86) $(p)ktest.asm + @cd \lx\x86 + @..\make\ml-x86 ktest asm + +$(a)memctr.obj : $(all_includes_x86) $(p)memctr.asm + @cd \lx\x86 + @..\make\ml-x86 memctr asm + +$(a)pagctr.obj : $(all_includes_x86) $(p)pagctr.asm + @cd \lx\x86 + @..\make\ml-x86 pagctr asm + +$(a)pagfault.obj : $(all_includes_x86) $(p)pagfault.asm + @cd \lx\x86 + @..\make\ml-x86 pagfault asm + +$(a)pagmap.obj : $(all_includes_x86) $(p)pagmap.asm + @cd \lx\x86 + @..\make\ml-x86 pagmap asm + +$(a)sgmctr.obj : $(all_includes_x86) $(p)sgmctr.asm + @cd \lx\x86 + @..\make\ml-x86 sgmctr asm + +$(a)sigma0.obj : $(all_includes_x86) $(p)sigma0.asm + @cd \lx\x86 + @..\make\ml-x86 sigma0 asm + +$(a)start.obj : $(all_includes_x86) $(p)start.asm + @cd \lx\x86 + @..\make\ml-x86 start asm + +$(a)startpc.obj : $(all_includes_x86) $(p)startpc.asm + @cd \lx\x86 + @..\make\ml-x86 startpc asm + +$(a)tcbman.obj : $(all_includes_x86) $(p)tcbman.asm + @cd \lx\x86 + @..\make\ml-x86 tcbman asm + +$(a)yoonseva.obj : $(all_includes_x86) $(p)yoonseva.asm + @cd \lx\x86 + @..\make\ml-x86 yoonseva asm + +$(a)l4.exe : $(a)adrsman.obj $(a)cpuctr.obj $(a)dispatch.obj $(a)emuctr.obj +$(a)l4.exe : $(a)intctr.obj $(a)ipcman.obj $(a)kdebug.obj $(a)kdiopc.obj +$(a)l4.exe : $(a)kernel.obj $(a)ktest.obj $(a)memctr.obj $(a)pagctr.obj +$(a)l4.exe : $(a)pagfault.obj $(a)pagmap.obj $(a)sgmctr.obj $(a)sigma0.obj $(a)mpconf.obj $(a)apstrtup.obj +$(a)l4.exe : $(a)start.obj $(a)startpc.obj $(a)tcbman.obj +$(a)l4.exe : $(a)yoonseva.obj +$(a)l4.exe : $(a)boot.obj + @cd \lx\x86 + @link /nologo @..\make\l4.rsp + rem pause + + + +$(a)boot.obj : $(all_includes_x86) $(p)boot.asm + @cd \lx\x86 + @..\make\ml-x86 boot asm + +$(a)boot.com : $(a)boot.obj + @cd \lx\x86 + link boot.obj/TINY,boot,boot.map + + + + + + diff --git a/l4-x86/smp/lx/make/ml-x86.bat b/l4-x86/smp/lx/make/ml-x86.bat new file mode 100755 index 0000000..7dc9db2 --- /dev/null +++ b/l4-x86/smp/lx/make/ml-x86.bat @@ -0,0 +1,3 @@ +@echo off +@ml /Dtarget=x86 /Dmax_cpu=1 /c /Sl124 /Sp109 /Fl /nologo /Sn /I..\kifc /I..\uifc ..\kern\%1.%2 + diff --git a/l4-x86/smp/lx/make/proj.err b/l4-x86/smp/lx/make/proj.err new file mode 100644 index 0000000..62b30d1 --- /dev/null +++ b/l4-x86/smp/lx/make/proj.err @@ -0,0 +1,30 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + + Assembling: ..\kernel\adrsman.asm + Assembling: ..\kernel\cpuctr.asm + Assembling: ..\kernel\dispatch.asm + Assembling: ..\kernel\emuctr.asm + Assembling: ..\kernel\intctr.asm + Assembling: ..\kernel\ipcman.asm + Assembling: ..\kernel\kdebug.asm + Assembling: ..\kernel\kdiopc.asm + Assembling: ..\kernel\ktest.asm + Assembling: ..\kernel\memctr.asm + Assembling: ..\kernel\pagctr.asm + Assembling: ..\kernel\pagfault.asm + Assembling: ..\kernel\pagmap.asm + Assembling: ..\kernel\sgmctr.asm + Assembling: ..\kernel\sigma0.asm + Assembling: ..\kernel\start.asm + Assembling: ..\kernel\startpc.asm + Assembling: ..\kernel\tcbman.asm + Assembling: ..\kernel\yoonseva.asm + Assembling: ..\kernel\boot.asm +Object Modules [.obj]: /nologo kernel startpc start cpuctr ipcman dispatch intctr tcbman memctr sgmctr+ +Object Modules [.obj]: pagctr pagfault pagmap adrsman emuctr yoonseva kdiopc kdebug sigma0 ktest,l4.exe,l4.map; +LINK : warning L4021: no stack segment + pause +Press any key to continue . . . + diff --git a/l4-x86/smp/lx/make/std.err b/l4-x86/smp/lx/make/std.err new file mode 100644 index 0000000..69e5bbe --- /dev/null +++ b/l4-x86/smp/lx/make/std.err @@ -0,0 +1,6 @@ + +Microsoft (R) Program Maintenance Utility Version 1.20 +Copyright (c) Microsoft Corp 1988-92. All rights reserved. + +NMAKE : fatal error U1081: 'link' : program not found +Stop. diff --git a/l4-x86/smp/lx/uifc/contents b/l4-x86/smp/lx/uifc/contents new file mode 100644 index 0000000..e29ae8c --- /dev/null +++ b/l4-x86/smp/lx/uifc/contents @@ -0,0 +1,14 @@ + +Contents of src\userifc: + + LN-external Include Files + + Convention: A name "x" refers to file "x.inc" and is used for all LNs (486, Pentium). + + +msg IPC message Description + Constants +syscalls System Calls Constants +uid Unique Ids (thread+task) Description, Constants, Macros + + +Only the mentioned files and this file of src\userifc are supported. \ No newline at end of file diff --git a/l4-x86/smp/lx/uifc/msg.inc b/l4-x86/smp/lx/uifc/msg.inc new file mode 100644 index 0000000..1c02c38 --- /dev/null +++ b/l4-x86/smp/lx/uifc/msg.inc @@ -0,0 +1,128 @@ +;---------------------------------------------------------------------------- +; +; message vector +; +;---------------------------------------------------------------------------- + + +msg_vector struc + + msg_rcv_fpage dd 0 + msg_size_dope dd 0 + msg_dope dd 0 + +msg_vector ends + + +xmsg_vector struc + + dd 0,0,0 + msg_w0 dd 0 + msg_w1 dd 0 + msg_w2 dd 0 + msg_w3 dd 0 + +xmsg_vector ends + + +msg_dope_fine_structure struc + + msg_cc db 0 + msg_strings db 0 + dw 0 + +msg_dope_fine_structure ends + + +msg_dope_bits record md_mwords:19,md_strings:5,md_cc:8 + + +max_md_strings equ (mask md_strings SHR md_strings) + + + +string_vector struc + + str_len dd 0 + str_addr dd 0 + buf_size dd 0 + buf_addr dd 0 + +string_vector ends + +string_length_bits record sl_free:10,string_length:22 + + +max_message_string_length equ MB4 + + +.errnz (1 SHL (width string_length)) - max_message_string_length +.erre (1 SHL (width md_mwords))*4+sizeof msg_vector LE max_message_string_length + + + +fpage_vector struc + + snd_base dd 0 + snd_fpage dd 0 + +fpage_vector ends + + +fpage record fpage_base:24,fpage_size:6,fpopn_write:1,fpopn_grant:1 + + + +fpage_map equ 0 +fpage_map_read_only equ fpage_map +fpage_map_read_write equ (fpage_map + mask fpopn_write) +fpage_grant equ mask fpopn_grant + + +.errnz fpage_grant AND fpage_map_read_write +.errnz fpage_grant AND fpage_map_read_only +.errnz fpage_map_read_write AND fpage_map_read_only + + + +;---------------------------------------------------------------------------- +; +; completion codes +; +;---------------------------------------------------------------------------- + + +msgccbyte record ccec:4,cci:1,ccr:1,ccm:1,ccd:1 + + +deceit equ mask ccd +map_msg equ mask ccm + +open_receive equ deceit + +redirected equ mask ccr +from_inner_clan equ mask cci + + +ipc_ok equ 00h SHL ccec + +ipc_not_existent_or_illegal equ 01h SHL ccec + +ipc_s equ 1 SHL ccec + +ipc_timeout equ 02h SHL ccec +ipc_cancelled equ 04h SHL ccec +ipc_map_failed equ 06h SHL ccec +ipc_snd_pf_timeout equ 08h SHL ccec +ipc_rcv_pf_timeout equ 0Ah SHL ccec +ipc_aborted equ 0Ch SHL ccec +ipc_cut equ 0Eh SHL ccec + + +ipc_error_mask equ mask ccec + +ipc_control_mask equ (deceit+map_msg+redirected+from_inner_clan) + + + + diff --git a/l4-x86/smp/lx/uifc/scmac.inc b/l4-x86/smp/lx/uifc/scmac.inc new file mode 100644 index 0000000..f7154ea --- /dev/null +++ b/l4-x86/smp/lx/uifc/scmac.inc @@ -0,0 +1,362 @@ + + +;---------------------------------------------------------------------------- +; +; ipc macros +; +;---------------------------------------------------------------------------- + + +never = -1 + +max_fpage = 31 SHL 2 + + +snd_timeout = never +spf_timeout = never +rcv_timeout = never +rpf_timeout = never + +iiic=-1 +iiia=-1 +iiib=-1 + + +ipc___pre macro +iiic=-1 +iiia=-1 +iiib=-1 +endm + + + +encode_timeout macro v +IF &v eq never + iiim=0 + iiie=0 +ELSE +IF &v eq 0 + iiim=0 + iiie=1 +ELSE + iiim=&v + iiie=10 + IF iiim ge 100h*10000h + iiie=iiie-8 + iiim=iiim/10000h + ENDIF + IF iiim ge 100h*100h + iiie=iiie-4 + iiim=iiim/100h + ENDIF + IF iiim ge 100h*10h + iiie=iiie-2 + iiim=iiim/10h + ENDIF + IF iiim ge 100h*4 + iiie=iiie-1 + iiim=iiim/4 + ENDIF +ENDIF +ENDIF +endm + +ipc___ld_timeout macro + iiic=0 + encode_timeout %snd_timeout + iiic=iiic+(iiim SHL 16)+(iiie SHL 4) + encode_timeout %rcv_timeout + iiic=iiic OR (iiim SHL 24)+iiie + encode_timeout %spf_timeout + iiic=iiic+(iiie SHL 12) + encode_timeout %rpf_timeout + iiic=iiic+(iiie SHL 8) + IF iiic eq 0 + xor ecx,ecx + ELSE + mov ecx,iiic + ENDIF +endm + + +ipc___ldc macro reg,v + + IF v eq 0 + xor reg,reg + ELSE + IF iiic ge 0 and v-iiic le 127 and -v+iiic le 128 + lea reg,[ecx+v-iiic] + ELSE + IF iiia ge 0 and v-iiia le 126 and -v+iiia le 129 + lea reg,[eax+v-iiia+1] + ELSE + IF iiib ge 0 and v-iiib le 126 and -v+iiib le 129 + lea reg,[ebp+v-iiib+1] + ELSE + mov reg,v + ENDIF + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_snd macro + ipc___ldc eax,-1 + iiia=0 + endm + + + +ipc___ld_snd macro mw0,mw1,msg + IFDIF , + mov edx,mw0 + ENDIF + IFDIF , + mov ebx,mw1 + ENDIF + IFB + xor eax,eax + iiia=1 + ELSE + IFIDN , + ipc___ldc eax,map_msg + iiia=map_msg+1 + ELSE + IFDIF , + mov eax,msg + iiia=-1 + ENDIF + ENDIF + ENDIF + endm + + +ipc___no_rcv macro + ipc___ldc ebp,-1 + iiib=0 + endm + + +ipc___ld_rcv macro msg + IFB + xor ebp,ebp + iiib=1 + ELSE + IFIDN , + ipc___ldc ebp,max_fpage+map_msg + iiib=max_fpage+map_msg+1 + ELSE + mov ebp,msg + iiib=-1 + ENDIF + ENDIF + endm + + +ipc___ld_thread macro dest + IFDIF , + mov esi,dest + mov edi,dest.4 + ENDIF + endm + + +ipc___ld_intr macro intr + ipc___ldc esi,intr + xor edi,edi + endm + + + +ipc___exec macro + int ipc +snd_timeout=never +spf_timeout=never +rcv_timeout=never +rpf_timeout=never +iiic=-1 +iiia=-1 +iiib=-1 + endm + + + +ipc___call macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___sndwt macro dest,sw0,sw1,smsg,rmsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___ld_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___send macro dest,sw0,sw1,smsg + ipc___pre + ipc___ld_timeout + ipc___ld_snd sw0,sw1, + ipc___no_rcv + ipc___ld_thread dest + ipc___exec + endm + + +ipc___receive macro source,rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___ld_thread source + ipc___exec + endm + + +ipc___wait macro rmsg + ipc___pre + ipc___ld_rcv + ipc___ld_timeout + ipc___no_snd + ipc___exec + endm + + +ipc___receive_intr macro intr + ipc___pre + ipc___ld_rcv + ipc___no_snd + ipc___ld_timeout + ipc___ld_intr intr+1 + ipc___exec + endm + + + + + + + + + +sndmsg macro dwords,strings + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd 0 + dd (d SHL md_mwords)+(s SHL md_strings) + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +rcvmsg macro dwords,strings,fpage + IFB + dd 0 + ELSE + dd fpage + ENDIF + d=0 + s=0 + IF dwords GT 2 + d=dwords + ENDIF + IFNB + s=strings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + dd 0 + endm + + + +sr_msg macro sdwords,sstrings,rdwords,rstrings,rfpage + IFB + dd 0 + ELSE + dd rfpage + ENDIF + d=0 + s=0 + IF rdwords GT 2 + d=rdwords + ENDIF + IFNB + s=rstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + d=0 + s=0 + IF sdwords GT 2 + d=sdwords + ENDIF + IFNB + s=sstrings + ENDIF + dd (d SHL md_mwords)+(s SHL md_strings) + endm + + +msg_vec1 struc + + dd 0 ; msg_rcv_fpage + dd 0 ; msg_size_dope + dd 0 ; msg_dope + dd 0 ; msg_w0 + dd 0 ; msg_w1 + dd 0 ; msg_w2 + msg_w3 dd 0 + msg_w4 dd 0 + msg_w5 dd 0 + msg_w6 dd 0 + msg_w7 dd 0 + +msg_vec1 ends + + + + + +;--------------------------------------------------------------------------------------- +; +; miscellaneous macros +; +;--------------------------------------------------------------------------------------- + + +thrd__self macro + + sub esi,esi + sub edi,edi + int id_nearest + + endm + + +thrd__switch macro dest + + IFB + sub esi,esi + int thread_switch + ELSE + mov esi,&dest + int thread_switch + ENDIF + + endm + + + \ No newline at end of file diff --git a/l4-x86/smp/lx/uifc/syscalls.inc b/l4-x86/smp/lx/uifc/syscalls.inc new file mode 100644 index 0000000..ff0f980 --- /dev/null +++ b/l4-x86/smp/lx/uifc/syscalls.inc @@ -0,0 +1,25 @@ +;********************************************************************* +;****** ****** +;****** LN System Calls (INT n) ****** +;****** ****** +;********************************************************************* + + +ipc equ 30h + +id_nearest equ 31h + +fpage_unmap equ 32h + +thread_switch equ 33h + +thread_schedule equ 34h + +lthread_ex_regs equ 35h + +task_new equ 36h + + + +ex_regs_update_flag equ 30 +ex_regs_auto_propagating_flag equ 29 \ No newline at end of file diff --git a/l4-x86/smp/lx/uifc/uid.inc b/l4-x86/smp/lx/uifc/uid.inc new file mode 100644 index 0000000..c885466 --- /dev/null +++ b/l4-x86/smp/lx/uifc/uid.inc @@ -0,0 +1,274 @@ + + + +;---------------------------------------------------------------------------- +; +; thread & task id +; +;---------------------------------------------------------------------------- + +thread_id record chief_no:8, task_no:8, lthread_no:6, ver:10 + +thread_id_x record xchief_no:8, thread_no:14, xver:10 + + + +threads equ (1 SHL width thread_no) +lthreads equ (1 SHL width lthread_no) + +threads_per_task equ lthreads + +tasks equ (1 SHL width task_no) + + log2 +log2_tasks equ log2_ + + +max_lthread_no equ (lthreads-1) +max_task_no equ (tasks-1) + + + + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + + +kernel_task_no equ 1 ; + pnr + +kernel_task equ (kernel_task_no SHL task_no) + +ipc_transparent equ 0 +ipc_inhibited equ 0FFFFFFFFh +ipc_locked equ 0FFFFFFFEh + + +;---------------------------------------------------------------------------- +; +; special tasks & threads +; +;---------------------------------------------------------------------------- + +initial_version equ 1 + +max_kernel_tcb equ (kernel_task+(lthreads-1)*sizeof tcb+offset tcb_space) + + +sigma0_task_no equ 2 ;+ max_cpu-1 +sigma1_task_no equ 3 ;+ max_cpu-1 +booter_task_no equ 4 ;+ max_cpu-1 + +root_chief_no equ booter_task_no +max_clan_depth equ 15 + +sigma0_task equ (sigma0_task_no SHL task_no+initial_version+root_chief_no SHL chief_no) + +sigma1_task equ (3 SHL task_no+initial_version+root_chief_no SHL chief_no) + +booter_task equ (4 SHL task_no+initial_version+root_chief_no SHL chief_no) +booter_lthread equ (0 SHL lthread_no) +booter_thread equ (booter_task+booter_lthread) + + + + +;---------------------------------------------------------------------------- +; +; mov task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task id (low) +; +;---------------------------------------------------------------------------- + + +mov___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,NOT mask lthread_no +endm + + + + +;---------------------------------------------------------------------------- +; +; mov lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg lthread +; +;---------------------------------------------------------------------------- + + + +mov___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + endm + + + + +;---------------------------------------------------------------------------- +; +; set lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; reg thread id (low) +; lthread lthread +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg set to specified lthread +; +;---------------------------------------------------------------------------- + + +set___lthread macro reg,lthread + + and reg,NOT mask lthread_no + IFDIF ,<0> + or reg,lthread + ENDIF + endm + + + + + +;---------------------------------------------------------------------------- +; +; mov chief +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg chief id, task only, ver and chief undefined +; +;---------------------------------------------------------------------------- + + +mov___chief macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + shr reg,chief_no-task_no +endm + + + + + + +;---------------------------------------------------------------------------- +; +; lno task +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg task no +; +;---------------------------------------------------------------------------- + + +lno___task macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask task_no + shr reg,task_no + endm + + + + +;---------------------------------------------------------------------------- +; +; lno thread / lthread +; +;---------------------------------------------------------------------------- +; PRECONDITION: +; +; thread thread id (low) +; +;---------------------------------------------------------------------------- +; POSTCONDITION: +; +; reg (l)thread no +; +;---------------------------------------------------------------------------- + + +lno___thread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask thread_no + shr reg,thread_no + endm + + + +lno___lthread macro reg,thread + + IFNB + IFDIF , + mov reg,thread + ENDIF + ENDIF + and reg,mask lthread_no + shr reg,lthread_no + endm + + diff --git a/l4-x86/ssh.log b/l4-x86/ssh.log new file mode 100644 index 0000000..6b0ac57 --- /dev/null +++ b/l4-x86/ssh.log @@ -0,0 +1,94 @@ +Mon Feb 07 15:29:41 2000 aa: Creating random seed file E:\temp\random.seed. This may take a while +Mon Feb 07 15:30:05 2000 aa: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:30:05 2000 aa: Crypto library info: +Mon Feb 07 15:30:06 2000 aa: Comments=(null) +Mon Feb 07 15:30:06 2000 aa: CompanyName=(null) +Mon Feb 07 15:30:06 2000 aa: FileDescription=VTXXX32 - VT emulation library. +Mon Feb 07 15:30:06 2000 aa: FileVersion=1.3 +Mon Feb 07 15:30:06 2000 aa: InternalName=VTXXX32.DLL +Mon Feb 07 15:30:06 2000 aa: LegalCopyright=Copyright © xxx 1995 - 1998. +Mon Feb 07 15:30:06 2000 aa: LegalTrademarks=(null) +Mon Feb 07 15:30:06 2000 aa: OriginalFilename=VTXXX32.DLL +Mon Feb 07 15:30:06 2000 aa: PrivateBuild=(null) +Mon Feb 07 15:30:06 2000 aa: ProductName=VTXXX32 - VT emulation library. +Mon Feb 07 15:30:06 2000 aa: ProductVersion=1.3 +Mon Feb 07 15:30:06 2000 aa: SpecialBuild=(null) +Mon Feb 07 15:30:06 2000 aa: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:30:28 2000 aa: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:30:28 2000 aa: Crypto library info: +Mon Feb 07 15:30:28 2000 aa: Comments=(null) +Mon Feb 07 15:30:28 2000 aa: CompanyName=(null) +Mon Feb 07 15:30:28 2000 aa: FileDescription=VTXXX32 - VT emulation library. +Mon Feb 07 15:30:28 2000 aa: FileVersion=1.3 +Mon Feb 07 15:30:28 2000 aa: InternalName=VTXXX32.DLL +Mon Feb 07 15:30:28 2000 aa: LegalCopyright=Copyright © xxx 1995 - 1998. +Mon Feb 07 15:30:28 2000 aa: LegalTrademarks=(null) +Mon Feb 07 15:30:28 2000 aa: OriginalFilename=VTXXX32.DLL +Mon Feb 07 15:30:28 2000 aa: PrivateBuild=(null) +Mon Feb 07 15:30:28 2000 aa: ProductName=VTXXX32 - VT emulation library. +Mon Feb 07 15:30:28 2000 aa: ProductVersion=1.3 +Mon Feb 07 15:30:28 2000 aa: SpecialBuild=(null) +Mon Feb 07 15:30:28 2000 aa: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:30:30 2000 aa: Can not load crypto library +Mon Feb 07 15:44:16 2000 96: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:44:16 2000 96: Crypto library info: +Mon Feb 07 15:44:16 2000 96: Comments=(null) +Mon Feb 07 15:44:16 2000 96: CompanyName=(null) +Mon Feb 07 15:44:16 2000 96: FileDescription=VTXXX32 - VT emulation library. +Mon Feb 07 15:44:16 2000 96: FileVersion=1.3 +Mon Feb 07 15:44:16 2000 96: InternalName=VTXXX32.DLL +Mon Feb 07 15:44:16 2000 96: LegalCopyright=Copyright © xxx 1995 - 1998. +Mon Feb 07 15:44:16 2000 96: LegalTrademarks=(null) +Mon Feb 07 15:44:16 2000 96: OriginalFilename=VTXXX32.DLL +Mon Feb 07 15:44:16 2000 96: PrivateBuild=(null) +Mon Feb 07 15:44:16 2000 96: ProductName=VTXXX32 - VT emulation library. +Mon Feb 07 15:44:16 2000 96: ProductVersion=1.3 +Mon Feb 07 15:44:16 2000 96: SpecialBuild=(null) +Mon Feb 07 15:44:16 2000 96: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:45:11 2000 96: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:45:11 2000 96: Crypto library info: +Mon Feb 07 15:45:11 2000 96: Comments=(null) +Mon Feb 07 15:45:11 2000 96: CompanyName=(null) +Mon Feb 07 15:45:11 2000 96: FileDescription=VTXXX32 - VT emulation library. +Mon Feb 07 15:45:11 2000 96: FileVersion=1.3 +Mon Feb 07 15:45:11 2000 96: InternalName=VTXXX32.DLL +Mon Feb 07 15:45:11 2000 96: LegalCopyright=Copyright © xxx 1995 - 1998. +Mon Feb 07 15:45:11 2000 96: LegalTrademarks=(null) +Mon Feb 07 15:45:11 2000 96: OriginalFilename=VTXXX32.DLL +Mon Feb 07 15:45:11 2000 96: PrivateBuild=(null) +Mon Feb 07 15:45:11 2000 96: ProductName=VTXXX32 - VT emulation library. +Mon Feb 07 15:45:11 2000 96: ProductVersion=1.3 +Mon Feb 07 15:45:11 2000 96: SpecialBuild=(null) +Mon Feb 07 15:45:11 2000 96: ------------------------------- CUT HERE ------------------------------- +Mon Feb 07 15:45:21 2000 96: Can not load crypto library +Tue Feb 08 18:32:50 2000 9a: ------------------------------- CUT HERE ------------------------------- +Tue Feb 08 18:32:50 2000 9a: Crypto library info: +Tue Feb 08 18:32:50 2000 9a: Comments=(null) +Tue Feb 08 18:32:50 2000 9a: CompanyName=(null) +Tue Feb 08 18:32:50 2000 9a: FileDescription=VTXXX32 - VT emulation library. +Tue Feb 08 18:32:50 2000 9a: FileVersion=1.3 +Tue Feb 08 18:32:50 2000 9a: InternalName=VTXXX32.DLL +Tue Feb 08 18:32:50 2000 9a: LegalCopyright=Copyright © xxx 1995 - 1998. +Tue Feb 08 18:32:50 2000 9a: LegalTrademarks=(null) +Tue Feb 08 18:32:50 2000 9a: OriginalFilename=VTXXX32.DLL +Tue Feb 08 18:32:50 2000 9a: PrivateBuild=(null) +Tue Feb 08 18:32:50 2000 9a: ProductName=VTXXX32 - VT emulation library. +Tue Feb 08 18:32:50 2000 9a: ProductVersion=1.3 +Tue Feb 08 18:32:50 2000 9a: SpecialBuild=(null) +Tue Feb 08 18:32:50 2000 9a: ------------------------------- CUT HERE ------------------------------- +Tue Feb 08 18:32:59 2000 9a: ------------------------------- CUT HERE ------------------------------- +Tue Feb 08 18:32:59 2000 9a: Crypto library info: +Tue Feb 08 18:32:59 2000 9a: Comments=(null) +Tue Feb 08 18:32:59 2000 9a: CompanyName=(null) +Tue Feb 08 18:32:59 2000 9a: FileDescription=VTXXX32 - VT emulation library. +Tue Feb 08 18:32:59 2000 9a: FileVersion=1.3 +Tue Feb 08 18:32:59 2000 9a: InternalName=VTXXX32.DLL +Tue Feb 08 18:32:59 2000 9a: LegalCopyright=Copyright © xxx 1995 - 1998. +Tue Feb 08 18:32:59 2000 9a: LegalTrademarks=(null) +Tue Feb 08 18:32:59 2000 9a: OriginalFilename=VTXXX32.DLL +Tue Feb 08 18:32:59 2000 9a: PrivateBuild=(null) +Tue Feb 08 18:32:59 2000 9a: ProductName=VTXXX32 - VT emulation library. +Tue Feb 08 18:32:59 2000 9a: ProductVersion=1.3 +Tue Feb 08 18:32:59 2000 9a: SpecialBuild=(null) +Tue Feb 08 18:32:59 2000 9a: ------------------------------- CUT HERE ------------------------------- +Tue Feb 08 18:33:01 2000 9a: Can not load crypto library diff --git a/tools/.#makel4kadist.1.1 b/tools/.#makel4kadist.1.1 new file mode 100755 index 0000000..5c4d45c --- /dev/null +++ b/tools/.#makel4kadist.1.1 @@ -0,0 +1,25 @@ +#!/bin/sh + +BUILDDIR=`pwd`/l4kadist +if [ ! -x $BUILDDIR ] ; then mkdir $BUILDDIR; fi +cd $BUILDDIR || exit 1 + +rm -rf l4-ka +cvs -d i30cvs.ira.uka.de:/home/cvs export -kv -r RC2 -D now l4-ka + +cd l4-ka || exit 1 +rm -rf apps/{testing,topp,membus,serv,helpers} +rm -rf apps/lib/ide +rm -rf `find kernel -name "*smp*"` kernel/include/x86/mps-14.h +rm -rf `find kernel -name "*mips*"` `find kernel -name "*sgi*"` +rm -rf kernel/kdb/{new-kdb.c,tracing.c,interrupts.c} +rm -rf doc +rm -rf kernel/README.html + +#tools/stripcpp -UCONFIG_DEBUGGER_NEW_KDB `find kernel -type f | xargs grep -l CONFIG_DEBUGGER_NEW_KDB | grep -v xconfig` +#tools/stripcpp -UCONFIG_SMP `find kernel -type f | xargs grep -l CONFIG_SMP | grep -v xconfig` +#tools/stripcpp -UCONFIG_IPC_FASTPATH `find kernel -type f | xargs grep -l CONFIG_IPC_FASTPATH | grep -v xconfig` + +tools/addlicense -l tools/gpl.license `find apps kernel -type f` + +rm -rf tools diff --git a/tools/Makefile b/tools/Makefile new file mode 100755 index 0000000..f565ead --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,35 @@ + +/tmp/dump_tcb: /tmp/dump_tcb.c /tmp/_thread.h /tmp/thread.c + @gcc -I../kernel/include --save-temps -D__ARCH__=x86 -DASSEMBLY -x c++ -o $@ /tmp/dump_tcb.c + @$@ + @rm $@ $^ + +/tmp/thread.c: + @( cat ../kernel/include/tcb.h | awk 'BEGIN{printme=0} /} tcb_t;/ { printme = 0} { if (printme == 1 ) { print } } /typedef struct tcb_t {/ {printme = 1 } ' ) | cpp -P | tr '*[;' ' ' | sed -e 's/[ \t\\]*/ /' | awk -F' ' '{print $$2}' | grep -v '^$$' | awk '{ print "D("$$1");" } ' > $@ + +/tmp/_thread.h: + @( cat ../kernel/include/tcb.h | awk 'BEGIN{printme=1} /typedef struct tcb_t {/ {printme = 1 } { if (printme == 1 ) { print $0 } } /} tcb_t;/ { printme = 0}' ; echo "#endif" ) > $@ + +/tmp/dump_tcb.c: + @printf '\ +#include "config.h" \n\ +#include "macros.h" \n\ +#include INC_ARCH(config.h) \n\ +#include "types.h" \n\ +#include "thread.h" \n\ +#define notify_procedure(x...) \n\ +#include "ipc.h" \n\ +#include "/tmp/_thread.h" \n\ + \n\ +#include \n\ + \n\ +tcb_t tcb; \n\ + \n\ +#define OFS(x) (((dword_t)&tcb.##x) - (dword_t)&tcb) \n\ + \n\ +#define D(x) printf("%%-20s:%%10x%%10d\\n", #x, OFS(x), OFS(x)); \n\ + \n\ +int main() \n\ +{ \n\ + #include "/tmp/thread.c" \n\ +} \n' > $@ diff --git a/tools/addlicense b/tools/addlicense new file mode 100755 index 0000000..9998865 --- /dev/null +++ b/tools/addlicense @@ -0,0 +1,70 @@ +#!/usr/bin/perl +###################################################################### +## Copyright (C) 2001, Karlsruhe University +## +## File path: addlicense +## Description: Add a license to files specified on the command +## line. +## +## @LICENSE@ +## +## $Id: addlicense,v 1.1 2001/11/27 17:20:46 skoglund Exp $ +## +###################################################################### + +my @files, $license; + + +## Parse args +while ($arg = shift) { + if ($arg =~ /^-l$/) { + $license = shift; + } elsif ($arg =~ /^--?h(elp)?$/) { + USAGE (); + } else { + push (@files, $arg); + } +} + +USAGE () unless @files; + +sub USAGE { + $0 =~ s,^(.*/),,; + print STDERR "USAGE: $0 [-l license] file...\n\n"; + exit 1; +} + +## Slurp whole files +undef $/; + + +## Get license +if ($license) { + open (L, $license) || die "open ($license): $!\n"; + $license = ; + close L; +} else { + $license = ; +} + +$license =~ s/^\s*//; +$license =~ s/\s*$//; + + +## Modify files +foreach $file (@files) { + open (F, $file) || die "open ($file): $!\n"; + my $contents = ; + close F; + + while ($contents =~ /(.*)\@LICENSE\@.*/) { + my $pfx = $1; + my $tmplicense = $license; + $tmplicense =~ s/^/$pfx/mg; + $contents =~ s/(.*)\@LICENSE\@.*/$tmplicense/; + open (NEW, "> $file.new") || die "open (> $file.new): $!\n"; + print NEW "$contents" || die "write ($file.new): $!\n"; + close NEW; + rename "$file.new", "$file" || die "rename $file.new, $file: $!\n"; + } +} diff --git a/tools/bsd.license b/tools/bsd.license new file mode 100644 index 0000000..cfd4e01 --- /dev/null +++ b/tools/bsd.license @@ -0,0 +1,21 @@ +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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + diff --git a/tools/countlines b/tools/countlines new file mode 100755 index 0000000..62c4f1a --- /dev/null +++ b/tools/countlines @@ -0,0 +1,44 @@ +#!/usr/bin/perl +###################################################################### +## +## Copyright (C) 2000, University of Karlsruhe +## +## Filename: countlines +## Description: Count number of lines in C files, not including +## comments and blank line. +## Author: Espen Skoglund +## +## $Id: countlines,v 1.1 2000/01/26 15:37:51 skoglund Exp $ +## +###################################################################### + + +my @files = @ARGV; + +## Slurp whole files +undef $/; + +foreach $file ( @files ) { + + open( SRCFILE, $file ) || die "open($file): $!\n"; + my $fc = ; + close SRCFILE; + + ## Remove comments. + $fc =~ s!/\*.*?\*/!!gs; + $fc =~ s!//.*$!!mg; + + ## Remove blank lines + $fc =~ s/^\s*\n//mg; + + my $num = $fc =~ s/\n/\n/g; + printf("%-40s %5d\n", $file.":", $num); + + $tot += $num; +} + +print "-"x(40+6), "\n"; +printf("%-40s %5d\n", "Total:", $tot); + + + diff --git a/tools/gpl.license b/tools/gpl.license new file mode 100644 index 0000000..63b1d84 --- /dev/null +++ b/tools/gpl.license @@ -0,0 +1,14 @@ +This program 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 +of the License, or (at your option) any later version. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. diff --git a/tools/lgpl.license b/tools/lgpl.license new file mode 100644 index 0000000..304937c --- /dev/null +++ b/tools/lgpl.license @@ -0,0 +1,14 @@ +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA diff --git a/tools/makel4kadist b/tools/makel4kadist new file mode 100755 index 0000000..30bbb32 --- /dev/null +++ b/tools/makel4kadist @@ -0,0 +1,25 @@ +#!/bin/sh + +BUILDDIR=`pwd`/l4kadist +if [ ! -x $BUILDDIR ] ; then mkdir $BUILDDIR; fi +cd $BUILDDIR || exit 1 + +rm -rf l4-ka +cvs -d i30pc20.ira.uka.de:/home/cvs export -kv -r RC2 -D now l4-ka + +cd l4-ka || exit 1 +rm -rf apps/{testing,topp,membus,serv,helpers} +rm -rf apps/lib/ide +rm -rf `find kernel -name "*smp*"` kernel/include/x86/mps-14.h +rm -rf `find kernel -name "*mips*"` `find kernel -name "*sgi*"` +rm -rf kernel/kdb/{new-kdb.c,tracing.c,interrupts.c} +rm -rf doc +rm -rf kernel/README.html + +#tools/stripcpp -UCONFIG_DEBUGGER_NEW_KDB `find kernel -type f | xargs grep -l CONFIG_DEBUGGER_NEW_KDB | grep -v xconfig` +#tools/stripcpp -UCONFIG_SMP `find kernel -type f | xargs grep -l CONFIG_SMP | grep -v xconfig` +#tools/stripcpp -UCONFIG_IPC_FASTPATH `find kernel -type f | xargs grep -l CONFIG_IPC_FASTPATH | grep -v xconfig` + +tools/addlicense -l tools/gpl.license `find apps kernel -type f` + +rm -rf tools diff --git a/tools/mktime.c b/tools/mktime.c new file mode 100644 index 0000000..af75bcd --- /dev/null +++ b/tools/mktime.c @@ -0,0 +1,80 @@ + + +#define M_BITS 8 + +#define is_good_m(x) ((x) < (1 << M_BITS)) + +#define best_m1(x) (x) +#define best_m2(x) (is_good_m(x) ? x : best_m1(x>>2)) +#define best_m3(x) (is_good_m(x) ? x : best_m2(x>>2)) +#define best_m4(x) (is_good_m(x) ? x : best_m3(x>>2)) +#define best_m5(x) (is_good_m(x) ? x : best_m4(x>>2)) +#define best_m6(x) (is_good_m(x) ? x : best_m5(x>>2)) +#define best_m7(x) (is_good_m(x) ? x : best_m6(x>>2)) +#define best_m8(x) (is_good_m(x) ? x : best_m7(x>>2)) +#define best_m9(x) (is_good_m(x) ? x : best_m8(x>>2)) +#define best_m10(x) (is_good_m(x) ? x : best_m9(x>>2)) +#define best_m11(x) (is_good_m(x) ? x : best_m10(x>>2)) +#define best_m12(x) (is_good_m(x) ? x : best_m11(x>>2)) +#define best_m13(x) (is_good_m(x) ? x : best_m12(x>>2)) +#define best_m14(x) (is_good_m(x) ? x : best_m13(x>>2)) +#define best_mant(x) (is_good_m(x) ? x : best_m14(x>>2)) + +#define best_e1(x) (1) +#define best_e2(x) (is_good_m(x) ? 2 : best_e1(x>>2)) +#define best_e3(x) (is_good_m(x) ? 3 : best_e2(x>>2)) +#define best_e4(x) (is_good_m(x) ? 4 : best_e3(x>>2)) +#define best_e5(x) (is_good_m(x) ? 5 : best_e4(x>>2)) +#define best_e6(x) (is_good_m(x) ? 6 : best_e5(x>>2)) +#define best_e7(x) (is_good_m(x) ? 7 : best_e6(x>>2)) +#define best_e8(x) (is_good_m(x) ? 8 : best_e7(x>>2)) +#define best_e9(x) (is_good_m(x) ? 9 : best_e8(x>>2)) +#define best_e10(x) (is_good_m(x) ? 10 : best_e9(x>>2)) +#define best_e11(x) (is_good_m(x) ? 11 : best_e10(x>>2)) +#define best_e12(x) (is_good_m(x) ? 12 : best_e11(x>>2)) +#define best_e13(x) (is_good_m(x) ? 13 : best_e12(x>>2)) +#define best_e14(x) (is_good_m(x) ? 14 : best_e13(x>>2)) +#define best_exp(x) (is_good_m(x) ? 15 : best_e14(x>>2)) + + +#define l4_time(ms) {best_mant(ms), best_exp(ms)} + + +#define mus(x) (x) +#define mills(x) (1000*mus(x)) +#define secs(x) (1000*mills(x)) +#define mins(x) (60*secs(x)) +#define hours(x) (60*mins(x)) + +#include + +int main() +{ + +#if 0 /* very long timeouts , long long */ +#define ms 68451041280LL + struct { + int m; + int e; + } to = l4_time(ms); + + + printf("ms=%Ld, m=%d, e=%d t=%Ld\n", + ms, to.m, to.e, + (((long long)to.m)* (1<<(2*(15-(long long)to.e))))); +#else + +#define ms secs(1)+mills(250) + struct { + int m; + int e; + } to = l4_time(ms); + + + printf("ms=%d, m=%d, e=%d t=%d\n", + ms, to.m, to.e, + (to.m* (1<<(2*(15-to.e))))); + +#endif + +} diff --git a/tools/stripcpp b/tools/stripcpp new file mode 100755 index 0000000..26f5611 --- /dev/null +++ b/tools/stripcpp @@ -0,0 +1,203 @@ +#!/usr/bin/perl +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: stripcpp +## Description: Utility for stripping out certain cpp defined code. +## +## @LICENSE@ +## +## $Id: stripcpp,v 1.4 2001/12/04 17:54:05 uhlig Exp $ +## +###################################################################### + +my @files, %defs; + + +## Parse args +while ($arg = shift) { + if ($arg =~ /^-D(\w+)(=(\S+))?/) { + $defs{$1} = $3 eq '' ? 1 : $3; + } elsif ($arg =~ /^-U(\w+)/) { + $undefs{$1} = 1; + } elsif ($arg =~ /^--?h(elp)?$/) { + USAGE (0); + } elsif ($arg =~ /^-/) { + USAGE (1); + } else { + push (@files, $arg); + } +} + +USAGE (1) unless @files; + +sub USAGE { + my $status = shift; + $0 =~ s,^(.*/),,; + print STDERR "USAGE: $0 [-Uvar...] [-Dvar...] [-Dvar=value..] file...\n\n"; + exit $status; +} + +## Slurp whole files +undef $/; + +select (STDIN); $| = 1; +select (STDOUT); $| = 1; + +## Modify files. This is not terribly efficient since we put the whole +## file into a string and perform a large number of regexp searches and +## replacements on it. +foreach $file (@files) { + open (F, $file) || die "open ($file): $!\n"; + my $contents = ; + close F; + + my $changed = 0; + my $num, $cnt = 0; + + ## Markup nested ifdefs + while ($contents =~ /^(\#\s*(if|ifn?def|elif|else|endif))/m) { + my $sub = "!!!"; + if ($2 eq 'if' || $2 eq 'ifdef' || $2 eq 'ifndef') { + $cnt++; + $sub = "!!! beg<$cnt>"; + } elsif ($2 eq 'elif') { + $sub = "!!! elif<$cnt>"; + } elsif ($2 eq 'else') { + $sub = "!!! else<$cnt>"; + } elsif ($2 eq 'endif') { + $sub = "!!! end<$cnt>"; + $cnt--; + } + $contents =~ s/^(\#\s*(if|ifn?def|elif|else|endif))/$sub$1/m; + } + + ## Start fixing up our modifications and possibly removing blocks. + ## Begin with the outhermost nesting. + $cnt = 1; + do { + $num = 0; + + while ($contents =~ /^!!! (\w+)<$cnt>(\#\s*)(\w+)\s*(\W*(\w+).*)/m) { + my $cut = 0; + my $keep = 0; + my $firstblock = 0; + + $firstblock = 1 if $3 eq 'if' || $3 eq 'ifdef' || $3 eq 'ifndef'; + + if ($3 eq 'ifdef') { + if ($undefs{$5}) { $cut = 1; } + elsif ($defs{$5}) { $keep = 1; } + } + elsif ($3 eq 'ifndef') { + if ($undefs{$5}) { $keep = 1; } + elsif ($defs{$5}) { $cut = 1; } + } + elsif ($3 eq 'if' || $3 eq 'elif') { + my $expr = $4; + my $elif = ($3 eq 'elif'); + if ($expr =~ m,^[\(\s]*(!)?\s*defined\s*\(\s*(\w+)\s*\)\s*[\)\s]*(\s*/\*.*?\*/)*\s*$,) { + ## Simple ifdef like expression + if ($undefs{$2}) { + if ($1 eq '!') { $keep = 1; } + else { $cut = 1; } + } + elsif ($defs{$2}) { + if ($1 eq '!') { $cut = 1; } + else { $keep = 1; } + } + } else { + ## More complex expression + my $expr = $4; + my @words; + while ($expr =~ s/\bdefined\s*\(\s*(\w+)\s*\)//) { + push (@words, $1) if $defs{$1} || $undefs{$1}; + } + if (@words) { + ## Complex expression containing some of our defined words + my ($pfx, $line) = ($contents =~ /(.*?\n)!!! \w+<$cnt>(.*?)\n/s); + my $linenum = ($pfx =~ tr/\n/\n/) + 1; + my $fname = $file; $fname =~ s,^\./,,; + my $yesno; + print ("In file \"$fname\", line $linenum, complex expression:\n", + " $line\n", + "\nRemove block (y/n): "); + $/ = "\n"; + do { + chomp ($yesno = ); + } while ($yesno !~ /[yYnN]/); + undef $/; + $cut = ($yesno eq 'y' || $yesno eq 'Y') ? 1 : 0; + if (!$cut) { + ## Remove subexpression(s) + foreach $word (@words) { + while ($line =~ + s/\s*(&&|\|\|)\s*(!\s*)?defined\s*\(\s*$word\s*\)//) {} + while ($line =~ + s/(!\s*)?defined\s*\(\s*$word\s*\)\s*(&&|\|\|)\s*//) {} + } + print "Writing new expression:\n $line\n"; + $contents =~ s/\n!!! \w+<$cnt>.*?\n/\n$line\n/; + $changed = 1; + } + } + } + } + + if ($keep) { + ## Keep the current block + if (!$firstblock) { + # Remove beginning of ifdef + $contents =~ s/(^|\n)\#\s*if(?!.*?\n\#\s*if).*?(\n!!! \w+<$cnt>)/\n$1/s; + } + $contents =~ s/\n!!! \w+<$cnt>.*?\n/\n/s; + $contents =~ /^!!! (else|elif|end)<$cnt>/m; + if ($1 eq 'end') { + # Just remove endif + $contents =~ s/\n!!! end<$cnt>.*?\n/\n/s; + } elsif ($1 eq 'else' || $1 eq 'elif') { + # Remove else or elif part too + $contents =~ s/\n!!! el(se|if)<$cnt>.*?\n!!! end<$cnt>.*?\n/\n/s; + } + $changed = 1; + } + + elsif ($cut) { + ## Remove current block + $contents =~ s/\n!!! \w+<$cnt>.*?(\n!!! \w+<$cnt>)/\n$1/s; + if ($firstblock) { + $contents =~ /^!!! (else|elif|end)<$cnt>/m; + if ($1 eq 'end') { + ## Just remove endif + $contents =~ s/\n!!! end<$cnt>.*?\n/\n/s; + } elsif ($1 eq 'elif') { + ## Convert elif into if + $contents =~ s/\n!!! elif<$cnt>(\#\s*)elif/\n$1if/s; + } elsif ($1 eq 'else') { + ## Remove else and endif + $contents =~ s/\n!!! else<$cnt>.*?\n/\n/s; + $contents =~ s/\n!!! end<$cnt>.*?\n/\n/s; + } + } + $changed = 1; + } + + else { + ## Do not modify current block + $contents =~ s/(^|\n)!!! (\w+)<$cnt>/\n/s; + } + $num++; + } + + ## Increase nesting + $cnt++; + } while ($num > 0); + + if ($changed) { + open (NEW, "> $file.new") || die "open (> $file.new): $!\n"; + print NEW "$contents" || die "write ($file.new): $!\n"; + close NEW; + rename "$file.new", "$file" || die "rename $file.new, $file: $!\n"; + } +} diff --git a/tools/transmap b/tools/transmap new file mode 100755 index 0000000..fda5685 --- /dev/null +++ b/tools/transmap @@ -0,0 +1,71 @@ +#!/usr/bin/perl +###################################################################### +## +## Copyright (C) 2001, Karlsruhe University +## +## File path: transmap +## Description: Take a mapfile and translates input from stdin or +## files on cmdline so that the output contains +## function names with offsets. All input lines which +## starts with a hex value is assumed to be an address +## to be translated. +## +## This program 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 +## of the License, or (at your option) any later version. +## +## This program 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 this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +## 02111-1307, USA. +## +## $Id: transmap,v 1.2 2001/03/01 14:34:48 skoglund Exp $ +## +###################################################################### + +$mapfile = shift; + +$0 =~ s,^.*/(.*),\1,; +$mapfile || die "USAGE: $0 mapfile [files...]\n"; + +sub get_func { + my $value = shift; + my $count = shift; + my $addr, $prevaddr, $prevname; + + open(MAPFILE, "$mapfile") || die "open($mapfile): $!"; + $prevaddr = 0; + $prevname = ""; + + while ( ) { + ($addr, $name) = /(\S+) . (.*)/; + last if hex($addr) > hex($value); + ($prevaddr, $prevname) = ($addr, $name); + } + + close MAPFILE; + + $counters{$prevname} = $counters{$prevname} + $count if $count; + sprintf(" %-32s", sprintf("%s+%x:", $prevname, hex($value)-hex($prevaddr))); +} + + +while (<>) { + $line = $_; + ($addr) = ($line =~ /^\s*([a-fA-F0-9]+):/); + ($count) = ($line =~ /^\s*[a-fA-F0-9]+:\s*(\d+)/); + $name = get_func($addr, $count); + $line =~ s/^\s*([a-fA-F0-9]+):/$name/eg; + print "$line"; +} + +print "\n"; +foreach $name ( sort { $counters{$b} <=> $counters{$a} } keys %counters ) { + printf(" %-32s %d\n", "$name:", $counters{$name}); +}